OrcaSlicer latest
OrcaSlicer
Loading...
Searching...
No Matches
Slic3r::FillAdaptive::noncrossing Namespace Reference

Classes

struct  SweepLine
struct  Junction
struct  LevelPath

Typedefs

using Lin = Vec2d

Functions

static void clip_profile (std::vector< Vec2d > &f, const Lin &c, int side, double w0, double w1, double lim0, double lim1, bool cut_at_window, bool drop_past_limits)
static std::vector< Vec2d > path_points (const LevelPath &path, const std::vector< SweepLine > &lines, double reach)
static double polyline_length (const std::vector< Vec2d > &pts)
static std::pair< Vec2d, size_t > point_along (const std::vector< Vec2d > &pts, double t)

Variables

static const Vec2d family_dir [3] { Vec2d(1., 0.), Vec2d(0.5, 0.5 * sqrt(3.)), Vec2d(0.5, -0.5 * sqrt(3.)) }

Class Documentation

◆ Slic3r::FillAdaptive::noncrossing::SweepLine

struct Slic3r::FillAdaptive::noncrossing::SweepLine
Collaboration diagram for Slic3r::FillAdaptive::noncrossing::SweepLine:
Class Members
Vec2d a
Vec2d b
int family
vector< pair< double, int > > junctions
Lin lin

◆ Slic3r::FillAdaptive::noncrossing::Junction

struct Slic3r::FillAdaptive::noncrossing::Junction
Collaboration diagram for Slic3r::FillAdaptive::noncrossing::Junction:
Class Members
vector< pair< int, int > > bends
vector< int > lines
Vec2d p
vector< pair< int, int > > pairs

◆ Slic3r::FillAdaptive::noncrossing::LevelPath

struct Slic3r::FillAdaptive::noncrossing::LevelPath
Collaboration diagram for Slic3r::FillAdaptive::noncrossing::LevelPath:
Class Members
vector< vector< Lin > > cuts
int end_term { -1 }
vector< int > junctions
vector< int > lines
vector< pair< Lin, int > > pushes
int start_term { -1 }
vector< int > turn
vector< Vec2d > verts

Typedef Documentation

◆ Lin

Function Documentation

◆ clip_profile()

void Slic3r::FillAdaptive::noncrossing::clip_profile ( std::vector< Vec2d > & f,
const Lin & c,
int side,
double w0,
double w1,
double lim0,
double lim1,
bool cut_at_window,
bool drop_past_limits )
static
1324{
1325 const double r0 = std::max(lim0, f.front().x()), r1 = std::min(lim1, f.back().x());
1326 if (r1 <= r0)
1327 return;
1328 const size_t ia = std::upper_bound(f.begin(), f.end(), r0, [](double x, const Vec2d &p) { return x < p.x(); }) - f.begin();
1329 const size_t ib = std::lower_bound(f.begin() + ia, f.end(), r1, [](const Vec2d &p, double x) { return p.x() < x; }) - f.begin();
1330 auto interpolate = [](const Vec2d &a, const Vec2d &b, double x) { return b.x() > a.x() ? a.y() + (x - a.x()) / (b.x() - a.x()) * (b.y() - a.y()) : b.y(); };
1331 std::vector<Vec2d> local{ Vec2d(r0, interpolate(f[ia - 1], f[ia], r0)) };
1332 local.insert(local.end(), f.begin() + ia, f.begin() + ib);
1333 local.emplace_back(r1, interpolate(f[ib - 1], f[ib], r1));
1334
1335 const double tol = 1.;
1336 auto beyond = [&c, side, tol](const Vec2d &p) { return side * (c.x() * p.x() + c.y() - p.y()) - tol; };
1337 std::vector<std::pair<double, double>> stretches;
1338 auto add = [&stretches](double x0, double x1) {
1339 if (!stretches.empty() && stretches.back().second >= x0)
1340 stretches.back().second = x1;
1341 else
1342 stretches.emplace_back(x0, x1);
1343 };
1344 for (size_t i = 1; i < local.size(); ++i) {
1345 const Vec2d &p = local[i - 1], &q = local[i];
1346 if (q.x() <= p.x())
1347 continue;
1348 const double bp = beyond(p), bq = beyond(q);
1349 if (bp > 0. && bq > 0.)
1350 add(p.x(), q.x());
1351 else if (bp > 0. || bq > 0.) {
1352 const double x = p.x() + bp / (bp - bq) * (q.x() - p.x());
1353 if (bp > 0.)
1354 add(p.x(), x);
1355 else
1356 add(x, q.x());
1357 }
1358 }
1359 std::vector<std::pair<double, double>> keep;
1360 for (auto [x0, x1] : stretches) {
1361 if (x1 < w0 || x0 > w1)
1362 continue;
1363 if (drop_past_limits && ((x0 <= r0 && r0 == lim0) || (x1 >= r1 && r1 == lim1)))
1364 continue;
1365 keep.emplace_back(cut_at_window ? std::max(x0, w0) : x0, cut_at_window ? std::min(x1, w1) : x1);
1366 }
1367 if (keep.empty())
1368 return;
1369
1370 auto y_local = [&](double x) {
1371 size_t i = 1;
1372 while (i + 1 < local.size() && local[i].x() < x)
1373 ++i;
1374 return interpolate(local[i - 1], local[i], x);
1375 };
1376 std::vector<Vec2d> out(f.begin(), f.begin() + ia);
1377 auto push = [&out, tol](double x, double y) {
1378 if (out.empty() || x > out.back().x() || std::abs(y - out.back().y()) > 2. * tol)
1379 out.emplace_back(x, y);
1380 };
1381 size_t k = 0;
1382 for (const Vec2d &p : local) {
1383 for (; k < keep.size() && keep[k].second < p.x(); ++k) {
1384 const auto [x0, x1] = keep[k];
1385 push(x0, y_local(x0));
1386 push(x0, c.x() * x0 + c.y());
1387 push(x1, c.x() * x1 + c.y());
1388 push(x1, y_local(x1));
1389 }
1390 if (k < keep.size() && keep[k].first <= p.x() && p.x() <= keep[k].second)
1391 continue;
1392 push(p.x(), p.y());
1393 }
1394 for (; k < keep.size(); ++k) {
1395 const auto [x0, x1] = keep[k];
1396 push(x0, y_local(x0));
1397 push(x0, c.x() * x0 + c.y());
1398 push(x1, c.x() * x1 + c.y());
1399 push(x1, y_local(x1));
1400 }
1401 for (size_t i = ib; i < f.size(); ++i)
1402 push(f[i].x(), f[i].y());
1403 f = std::move(out);
1404}
SpiralVase::SpiralPoint add(SpiralVase::SpiralPoint a, SpiralVase::SpiralPoint b)
Definition SpiralVase.cpp:26
@ local
Definition Time.hpp:13
Point interpolate(const Point &a, const Point &b, double t)
Definition ExclusionVolumeTravelAvoidance.cpp:158
static double f(double x, double z_sin, double z_cos, bool vertical, bool flip)
Definition FillGyroid.cpp:124
Eigen::Matrix< double, 2, 1, Eigen::DontAlign > Vec2d
Definition Point.hpp:67

References Slic3r::f().

Referenced by path_points().

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

◆ path_points()

std::vector< Vec2d > Slic3r::FillAdaptive::noncrossing::path_points ( const LevelPath & path,
const std::vector< SweepLine > & lines,
double reach )
static
1407{
1408 std::vector<Vec2d> f = path.verts;
1409 const int nb = int(path.junctions.size());
1410 auto x_of = [&path](int b) { return path.verts[b + 1].x(); };
1411 auto sharp = [&](int b) { return lines[path.lines[b]].family != 0 && lines[path.lines[b + 1]].family != 0; };
1412 // The run of bends turning the same way as bend b, up to the neighbouring bends turning the other way.
1413 auto window = [&](int b) {
1414 int l = b - 1, r = b + 1;
1415 while (l >= 0 && path.turn[l] == path.turn[b])
1416 --l;
1417 while (r < nb && path.turn[r] == path.turn[b])
1418 ++r;
1419 return std::make_pair(l >= 0 ? x_of(l) : f.front().x(), r < nb ? x_of(r) : f.back().x());
1420 };
1421 // Sharp bends between the slanted lines go last, so they win at the tip of a small triangle.
1422 for (int b = 0; b < nb; ++b)
1423 if (!sharp(b)) {
1424 const auto [w0, w1] = window(b);
1425 for (const Lin &c : path.cuts[b])
1426 clip_profile(f, c, path.turn[b], w0, w1, x_of(b) - reach, x_of(b) + reach, true, false);
1427 }
1428 for (int b = 0; b < nb; ++b)
1429 if (sharp(b))
1430 for (const Lin &c : path.cuts[b])
1431 clip_profile(f, c, path.turn[b], x_of(b), x_of(b), x_of(b) - reach, x_of(b) + reach, false, true);
1432 for (const auto &[c, b] : path.pushes) {
1433 const auto [w0, w1] = window(b);
1434 clip_profile(f, c, path.turn[b], w0, w1, x_of(b) - reach, x_of(b) + reach, true, true);
1435 }
1436 std::vector<Vec2d> pts;
1437 for (const Vec2d &p : f) {
1438 while (pts.size() >= 2 && std::abs(cross2(Vec2d(pts.back() - pts[pts.size() - 2]), Vec2d(p - pts.back()))) <=
1439 1e-9 * (pts.back() - pts[pts.size() - 2]).norm() * (p - pts.back()).norm())
1440 pts.pop_back();
1441 pts.push_back(p);
1442 }
1443 return pts;
1444}
std::vector< std::pair< Lin, int > > pushes
Definition FillAdaptive.cpp:1317
std::vector< int > turn
Definition FillAdaptive.cpp:1315
static void clip_profile(std::vector< Vec2d > &f, const Lin &c, int side, double w0, double w1, double lim0, double lim1, bool cut_at_window, bool drop_past_limits)
Definition FillAdaptive.cpp:1323
Vec2d Lin
Definition FillAdaptive.cpp:1290
std::vector< std::vector< Lin > > cuts
Definition FillAdaptive.cpp:1316
std::vector< int > junctions
Definition FillAdaptive.cpp:1314
std::vector< Vec2d > verts
Definition FillAdaptive.cpp:1312
std::vector< int > lines
Definition FillAdaptive.cpp:1313
int32_t cross2(const Eigen::MatrixBase< Eigen::Matrix< int32_t, 2, 1, Options > > &v1, const Eigen::MatrixBase< Eigen::Matrix< int32_t, 2, 1, Options > > &v2)=delete

References clip_profile(), Slic3r::cross2(), Slic3r::FillAdaptive::noncrossing::LevelPath::cuts, Slic3r::f(), Slic3r::FillAdaptive::noncrossing::LevelPath::junctions, Slic3r::FillAdaptive::noncrossing::LevelPath::lines, Slic3r::FillAdaptive::noncrossing::LevelPath::pushes, Slic3r::FillAdaptive::noncrossing::LevelPath::turn, and Slic3r::FillAdaptive::noncrossing::LevelPath::verts.

Here is the call graph for this function:

◆ point_along()

std::pair< Vec2d, size_t > Slic3r::FillAdaptive::noncrossing::point_along ( const std::vector< Vec2d > & pts,
double t )
static
1456{
1457 for (size_t i = 1; i < pts.size(); ++i) {
1458 const double len = (pts[i] - pts[i - 1]).norm();
1459 if (t <= len)
1460 return { pts[i - 1] + (len > 0. ? t / len : 0.) * (pts[i] - pts[i - 1]), i };
1461 t -= len;
1462 }
1463 return { pts.back(), pts.size() - 1 };
1464}

◆ polyline_length()

double Slic3r::FillAdaptive::noncrossing::polyline_length ( const std::vector< Vec2d > & pts)
static
1447{
1448 double len = 0.;
1449 for (size_t i = 1; i < pts.size(); ++i)
1450 len += (pts[i] - pts[i - 1]).norm();
1451 return len;
1452}

Variable Documentation

◆ family_dir

const Vec2d Slic3r::FillAdaptive::noncrossing::family_dir[3] { Vec2d(1., 0.), Vec2d(0.5, 0.5 * sqrt(3.)), Vec2d(0.5, -0.5 * sqrt(3.)) }
static
1292{ Vec2d(1., 0.), Vec2d(0.5, 0.5 * sqrt(3.)), Vec2d(0.5, -0.5 * sqrt(3.)) };