OrcaSlicer latest
OrcaSlicer
Loading...
Searching...
No Matches
Slic3r::anonymous_namespace{SketchEngine.cpp} Namespace Reference

Functions

bool off_same (const Vec2d &a, const Vec2d &b)
bool off_is_open_curve (const SketchEntity &e)
bool off_pick (const std::vector< Vec2d > &cands, const Vec2d &seed, Vec2d &out)
bool off_line_line (const Vec2d &a0, const Vec2d &a1, const Vec2d &b0, const Vec2d &b1, const Vec2d &seed, Vec2d &out)
std::vector< Vec2d > off_line_circle (const Vec2d &p0, const Vec2d &p1, const Vec2d &c, double r)
std::vector< Vec2d > off_circle_circle (const Vec2d &c0, double r0, const Vec2d &c1, double r1)
void off_set_end (SketchEntity &e, bool at_end, const Vec2d &q)
bool off_one (const SketchEntity &e, double d, SketchEntity &out)
bool off_join (SketchEntity &a, SketchEntity &b)
void off_reverse (SketchEntity &e)
bool angle_on_arc (const SketchEntity &e, double ang, double tol)
void entity_intersections (const SketchEntity &A, const SketchEntity &B, std::vector< Vec2d > &out)

Function Documentation

◆ angle_on_arc()

bool Slic3r::anonymous_namespace{SketchEngine.cpp}::angle_on_arc ( const SketchEntity & e,
double ang,
double tol )
2161{
2162 const double TWO_PI = 2.0 * M_PI;
2163 const double sweep = e.end_angle - e.start_angle;
2164 double d = (sweep >= 0.0) ? ang - e.start_angle : e.start_angle - ang;
2165 d = std::fmod(d, TWO_PI);
2166 if (d < 0.0) d += TWO_PI;
2167 if (d > TWO_PI - tol) d -= TWO_PI; // just before the start counts as the start
2168 return d >= -tol && d <= std::abs(sweep) + tol;
2169}
#define M_PI
Definition ExtrusionSimulator.cpp:31
double start_angle
Definition SketchEngine.hpp:37
double end_angle
Definition SketchEngine.hpp:38

References angle_on_arc(), Slic3r::SketchEntity::end_angle, M_PI, and Slic3r::SketchEntity::start_angle.

Referenced by angle_on_arc(), and entity_intersections().

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

◆ entity_intersections()

void Slic3r::anonymous_namespace{SketchEngine.cpp}::entity_intersections ( const SketchEntity & A,
const SketchEntity & B,
std::vector< Vec2d > & out )
2173{
2174 using T = SketchEntity::Type;
2175 const double eps = 1e-9;
2176 auto on_seg = [](const SketchEntity& L, const Vec2d& p) {
2177 const Vec2d d = L.p1 - L.p0;
2178 const double l2 = d.squaredNorm();
2179 if (l2 < 1e-24) return false;
2180 const double t = (p - L.p0).dot(d) / l2;
2181 return t >= -1e-9 && t <= 1.0 + 1e-9;
2182 };
2183 if (A.type == T::Line && B.type == T::Line) {
2184 const Vec2d r = A.p1 - A.p0, q = B.p1 - B.p0, w = B.p0 - A.p0;
2185 const double den = r.x() * q.y() - r.y() * q.x();
2186 if (std::abs(den) < eps * r.norm() * q.norm()) {
2187 // Parallel. Collinear overlap is a crossing wherever it is: report the overlap's
2188 // nearest end, which the caller then tests against the shared joints.
2189 if (std::abs(r.x() * w.y() - r.y() * w.x()) > 1e-9 * std::max(1.0, r.norm())) return;
2190 for (const Vec2d& p : { B.p0, B.p1 }) if (on_seg(A, p)) out.push_back(p);
2191 for (const Vec2d& p : { A.p0, A.p1 }) if (on_seg(B, p)) out.push_back(p);
2192 return;
2193 }
2194 const double t = (w.x() * q.y() - w.y() * q.x()) / den;
2195 const double u = (w.x() * r.y() - w.y() * r.x()) / den;
2196 if (t >= -1e-9 && t <= 1.0 + 1e-9 && u >= -1e-9 && u <= 1.0 + 1e-9) out.push_back(A.p0 + t * r);
2197 return;
2198 }
2199 if (A.type == T::Arc && B.type == T::Line) { entity_intersections(B, A, out); return; }
2200 if (A.type == T::Line && B.type == T::Arc) {
2201 const Vec2d d = A.p1 - A.p0, f = A.p0 - B.center;
2202 const double a = d.squaredNorm(), b = 2.0 * f.dot(d), c = f.squaredNorm() - B.radius * B.radius;
2203 if (a < 1e-24) return;
2204 double disc = b * b - 4.0 * a * c;
2205 if (disc < -1e-9 * a * B.radius * B.radius) return;
2206 disc = std::sqrt(std::max(0.0, disc));
2207 for (double t : { (-b - disc) / (2.0 * a), (-b + disc) / (2.0 * a) }) {
2208 if (t < -1e-9 || t > 1.0 + 1e-9) continue;
2209 const Vec2d p = A.p0 + t * d;
2210 if (angle_on_arc(B, std::atan2(p.y() - B.center.y(), p.x() - B.center.x()), 1e-9))
2211 out.push_back(p);
2212 }
2213 return;
2214 }
2215 if (A.type == T::Arc && B.type == T::Arc) {
2216 const Vec2d dc = B.center - A.center;
2217 const double dd = dc.norm();
2218 if (dd < 1e-12) {
2219 // Concentric: they overlap only on the same circle, and then everywhere they share.
2220 if (std::abs(A.radius - B.radius) > 1e-9) return;
2221 for (const Vec2d& p : { B.p0, B.p1 })
2222 if (angle_on_arc(A, std::atan2(p.y() - A.center.y(), p.x() - A.center.x()), 1e-9)) out.push_back(p);
2223 for (const Vec2d& p : { A.p0, A.p1 })
2224 if (angle_on_arc(B, std::atan2(p.y() - B.center.y(), p.x() - B.center.x()), 1e-9)) out.push_back(p);
2225 return;
2226 }
2227 if (dd > A.radius + B.radius + 1e-9 || dd < std::abs(A.radius - B.radius) - 1e-9) return;
2228 const double x = (dd * dd + A.radius * A.radius - B.radius * B.radius) / (2.0 * dd);
2229 const double h = std::sqrt(std::max(0.0, A.radius * A.radius - x * x));
2230 const Vec2d u = dc / dd, m = A.center + x * u, n(-u.y(), u.x());
2231 for (const Vec2d& p : { Vec2d(m + h * n), Vec2d(m - h * n) }) {
2232 if (angle_on_arc(A, std::atan2(p.y() - A.center.y(), p.x() - A.center.x()), 1e-9) &&
2233 angle_on_arc(B, std::atan2(p.y() - B.center.y(), p.x() - B.center.x()), 1e-9))
2234 out.push_back(p);
2235 if (h < 1e-12) break;
2236 }
2237 }
2238}
#define L(s)
Definition ExtrusionEntity.cpp:25
void entity_intersections(const SketchEntity &A, const SketchEntity &B, std::vector< Vec2d > &out)
Definition SketchEngine.cpp:2172
bool angle_on_arc(const SketchEntity &e, double ang, double tol)
Definition SketchEngine.cpp:2160
T l2(const boost::geometry::model::d2::point_xy< T > &v)
Definition ExtrusionSimulator.cpp:177
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
T dot(const boost::geometry::model::d2::point_xy< T > &v1, const boost::geometry::model::d2::point_xy< T > &v2)
Definition ExtrusionSimulator.cpp:154
Definition SketchEngine.hpp:30
Vec2d p0
Definition SketchEngine.hpp:33
Type
Definition SketchEngine.hpp:31
Type type
Definition SketchEngine.hpp:32
Vec2d center
Definition SketchEngine.hpp:35
double radius
Definition SketchEngine.hpp:36
Vec2d p1
Definition SketchEngine.hpp:34

References angle_on_arc(), Slic3r::SketchEntity::center, Slic3r::dot(), entity_intersections(), Slic3r::f(), L, Slic3r::l2(), Slic3r::SketchEntity::p0, Slic3r::SketchEntity::p1, Slic3r::SketchEntity::radius, and Slic3r::SketchEntity::type.

Referenced by entity_intersections().

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

◆ off_circle_circle()

std::vector< Vec2d > Slic3r::anonymous_namespace{SketchEngine.cpp}::off_circle_circle ( const Vec2d & c0,
double r0,
const Vec2d & c1,
double r1 )
1209{
1210 std::vector<Vec2d> out;
1211 const Vec2d d = c1 - c0;
1212 const double L = d.norm();
1213 if (L < 1e-12 || L > r0 + r1 || L < std::abs(r0 - r1)) return out;
1214 const double a = (r0 * r0 - r1 * r1 + L * L) / (2.0 * L);
1215 const double h2 = r0 * r0 - a * a;
1216 const double h = h2 > 0.0 ? std::sqrt(h2) : 0.0;
1217 const Vec2d u = d / L, n(-u.y(), u.x());
1218 out.push_back(c0 + a * u + h * n);
1219 out.push_back(c0 + a * u - h * n);
1220 return out;
1221}

References L, and off_circle_circle().

Referenced by off_circle_circle(), and off_join().

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

◆ off_is_open_curve()

bool Slic3r::anonymous_namespace{SketchEngine.cpp}::off_is_open_curve ( const SketchEntity & e)
1162{
1164}
@ Arc
Definition SketchEngine.hpp:31
@ Line
Definition SketchEngine.hpp:31

References Slic3r::SketchEntity::Arc, Slic3r::SketchEntity::Line, off_is_open_curve(), and Slic3r::SketchEntity::type.

Referenced by off_is_open_curve().

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

◆ off_join()

bool Slic3r::anonymous_namespace{SketchEngine.cpp}::off_join ( SketchEntity & a,
SketchEntity & b )
1298{
1299 const Vec2d seed = 0.5 * (a.p1 + b.p0);
1300 Vec2d q;
1301 const bool aL = a.type == SketchEntity::Type::Line;
1302 const bool bL = b.type == SketchEntity::Type::Line;
1303 if (aL && bL) {
1304 if (!off_line_line(a.p0, a.p1, b.p0, b.p1, seed, q)) return false;
1305 } else if (aL) {
1306 if (!off_pick(off_line_circle(a.p0, a.p1, b.center, b.radius), seed, q)) return false;
1307 } else if (bL) {
1308 if (!off_pick(off_line_circle(b.p0, b.p1, a.center, a.radius), seed, q)) return false;
1309 } else {
1310 if (!off_pick(off_circle_circle(a.center, a.radius, b.center, b.radius), seed, q)) return false;
1311 }
1312 off_set_end(a, true, q);
1313 off_set_end(b, false, q);
1314 return true;
1315}
bool off_line_line(const Vec2d &a0, const Vec2d &a1, const Vec2d &b0, const Vec2d &b1, const Vec2d &seed, Vec2d &out)
Definition SketchEngine.cpp:1179
std::vector< Vec2d > off_circle_circle(const Vec2d &c0, double r0, const Vec2d &c1, double r1)
Definition SketchEngine.cpp:1208
bool off_pick(const std::vector< Vec2d > &cands, const Vec2d &seed, Vec2d &out)
Definition SketchEngine.cpp:1168
void off_set_end(SketchEntity &e, bool at_end, const Vec2d &q)
Definition SketchEngine.cpp:1225
std::vector< Vec2d > off_line_circle(const Vec2d &p0, const Vec2d &p1, const Vec2d &c, double r)
Definition SketchEngine.cpp:1192

References Slic3r::SketchEntity::center, Slic3r::SketchEntity::Line, off_circle_circle(), off_join(), off_line_circle(), off_line_line(), off_pick(), off_set_end(), Slic3r::SketchEntity::p0, Slic3r::SketchEntity::p1, Slic3r::SketchEntity::radius, and Slic3r::SketchEntity::type.

Referenced by off_join().

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

◆ off_line_circle()

std::vector< Vec2d > Slic3r::anonymous_namespace{SketchEngine.cpp}::off_line_circle ( const Vec2d & p0,
const Vec2d & p1,
const Vec2d & c,
double r )
1193{
1194 std::vector<Vec2d> out;
1195 Vec2d d = p1 - p0;
1196 const double dd = d.squaredNorm();
1197 if (dd < 1e-18 || r <= 0.0) return out;
1198 const Vec2d f = p0 - c;
1199 const double b = 2.0 * f.dot(d), cc = f.squaredNorm() - r * r;
1200 const double disc = b * b - 4.0 * dd * cc;
1201 if (disc < 0.0) return out;
1202 const double sq = std::sqrt(disc);
1203 out.push_back(p0 + ((-b - sq) / (2.0 * dd)) * d);
1204 out.push_back(p0 + ((-b + sq) / (2.0 * dd)) * d);
1205 return out;
1206}

References Slic3r::f(), and off_line_circle().

Referenced by off_join(), and off_line_circle().

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

◆ off_line_line()

bool Slic3r::anonymous_namespace{SketchEngine.cpp}::off_line_line ( const Vec2d & a0,
const Vec2d & a1,
const Vec2d & b0,
const Vec2d & b1,
const Vec2d & seed,
Vec2d & out )
1181{
1182 const Vec2d da = a1 - a0, db = b1 - b0;
1183 const double den = da.x() * db.y() - da.y() * db.x();
1184 if (std::abs(den) < 1e-12) return false; // parallel: no miter exists
1185 const Vec2d w = b0 - a0;
1186 const double t = (w.x() * db.y() - w.y() * db.x()) / den;
1187 out = a0 + t * da;
1188 (void)seed;
1189 return true;
1190}

References off_line_line().

Referenced by off_join(), and off_line_line().

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

◆ off_one()

bool Slic3r::anonymous_namespace{SketchEngine.cpp}::off_one ( const SketchEntity & e,
double d,
SketchEntity & out )
1251{
1252 switch (e.type) {
1254 Vec2d t = e.p1 - e.p0;
1255 if (t.norm() < 1e-12) return false;
1256 t.normalize();
1257 const Vec2d n(-t.y(), t.x());
1258 out = e;
1259 out.p0 = e.p0 + d * n;
1260 out.p1 = e.p1 + d * n;
1261 return true;
1262 }
1264 // A circle runs CCW (it is what a 360° CCW arc chain closes into), so the rule below
1265 // applies to it too: +d is the left side, the inside, and the radius SHRINKS. It used to
1266 // grow, so a full circle and the same outline drawn as arcs offset opposite ways.
1267 const double r = e.radius - d;
1268 if (r <= 1e-9) return false;
1269 out = e; out.radius = r; out.p0 = out.center;
1270 return true;
1271 }
1273 // Same convention as the Line above: +d moves the curve to the LEFT of its direction
1274 // of travel. For a CCW arc the left side is the inside, so the radius SHRINKS; for a
1275 // CW arc it grows. Reading the sign off the sweep is what keeps a stadium outline
1276 // (lines + caps) offsetting as one body instead of the lines going one way and the
1277 // caps the other — which is what a plain `radius + d` did.
1278 const double sgn = (e.end_angle >= e.start_angle) ? -1.0 : 1.0;
1279 const double r = e.radius + sgn * d;
1280 if (r <= 1e-9) return false;
1281 out = e;
1282 out.radius = r;
1283 out.p0 = e.center + r * Vec2d(std::cos(e.start_angle), std::sin(e.start_angle));
1284 out.p1 = e.center + r * Vec2d(std::cos(e.end_angle), std::sin(e.end_angle));
1285 return true;
1286 }
1287 default:
1288 // Point has nothing to offset; a true parallel of an ellipse is not an ellipse and of a
1289 // spline is not a same-degree spline, so both stay out of v1 rather than lie about it.
1290 return false;
1291 }
1292}
int sgn(T val)
Definition Fill3DHoneycomb.cpp:24
@ Circle
Definition SketchEngine.hpp:31

References Slic3r::SketchEntity::Arc, Slic3r::SketchEntity::center, Slic3r::SketchEntity::Circle, Slic3r::SketchEntity::end_angle, Slic3r::SketchEntity::Line, off_one(), Slic3r::SketchEntity::p0, Slic3r::SketchEntity::p1, Slic3r::SketchEntity::radius, Slic3r::sgn(), Slic3r::SketchEntity::start_angle, and Slic3r::SketchEntity::type.

Referenced by off_one().

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

◆ off_pick()

bool Slic3r::anonymous_namespace{SketchEngine.cpp}::off_pick ( const std::vector< Vec2d > & cands,
const Vec2d & seed,
Vec2d & out )
1169{
1170 if (cands.empty()) return false;
1171 double best = std::numeric_limits<double>::max();
1172 for (const Vec2d& c : cands) {
1173 const double d = (c - seed).squaredNorm();
1174 if (d < best) { best = d; out = c; }
1175 }
1176 return true;
1177}

References off_pick().

Referenced by off_join(), and off_pick().

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

◆ off_reverse()

void Slic3r::anonymous_namespace{SketchEngine.cpp}::off_reverse ( SketchEntity & e)
1321{
1322 std::swap(e.p0, e.p1);
1324 std::swap(e.start_angle, e.end_angle);
1325}

References Slic3r::SketchEntity::Arc, Slic3r::SketchEntity::end_angle, off_reverse(), Slic3r::SketchEntity::p0, Slic3r::SketchEntity::p1, Slic3r::SketchEntity::start_angle, and Slic3r::SketchEntity::type.

Referenced by off_reverse().

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

◆ off_same()

bool Slic3r::anonymous_namespace{SketchEngine.cpp}::off_same ( const Vec2d & a,
const Vec2d & b )
1155{
1156 const double tol = std::max(sketch_join_tol(), 1e-6);
1157 return (a - b).squaredNorm() <= tol * tol;
1158}
double sketch_join_tol()
Definition SketchEngine.cpp:80

References off_same(), and Slic3r::sketch_join_tol().

Referenced by off_same().

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

◆ off_set_end()

void Slic3r::anonymous_namespace{SketchEngine.cpp}::off_set_end ( SketchEntity & e,
bool at_end,
const Vec2d & q )
1226{
1227 if (e.type == SketchEntity::Type::Line) {
1228 (at_end ? e.p1 : e.p0) = q;
1229 return;
1230 }
1231 if (e.type != SketchEntity::Type::Arc) return;
1232 const bool ccw = e.end_angle >= e.start_angle;
1233 const double ang = std::atan2(q.y() - e.center.y(), q.x() - e.center.x());
1234 if (at_end) {
1235 e.p1 = q;
1236 double a = ang;
1237 if (ccw) { while (a < e.start_angle) a += 2.0 * M_PI; while (a - e.start_angle > 2.0 * M_PI) a -= 2.0 * M_PI; }
1238 else { while (a > e.start_angle) a -= 2.0 * M_PI; while (e.start_angle - a > 2.0 * M_PI) a += 2.0 * M_PI; }
1239 e.end_angle = a;
1240 } else {
1241 e.p0 = q;
1242 double a = ang;
1243 if (ccw) { while (a > e.end_angle) a -= 2.0 * M_PI; while (e.end_angle - a > 2.0 * M_PI) a += 2.0 * M_PI; }
1244 else { while (a < e.end_angle) a += 2.0 * M_PI; while (a - e.end_angle > 2.0 * M_PI) a -= 2.0 * M_PI; }
1245 e.start_angle = a;
1246 }
1247}

References Slic3r::SketchEntity::Arc, Slic3r::SketchEntity::center, Slic3r::SketchEntity::end_angle, Slic3r::SketchEntity::Line, M_PI, off_set_end(), Slic3r::SketchEntity::p0, Slic3r::SketchEntity::p1, Slic3r::SketchEntity::start_angle, and Slic3r::SketchEntity::type.

Referenced by off_join(), and off_set_end().

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