OrcaSlicer latest
OrcaSlicer
Loading...
Searching...
No Matches
Slic3r::Geometry Namespace Reference

Namespaces

namespace  ArcWelder
namespace  BicubicInternal
namespace  rotcalip
namespace  impl

Classes

class  ArrangeItem
class  ArrangeItemIndex
class  Transformation
struct  TransformationSVD
struct  CubicKernelWrapper
struct  CircleSq
struct  Circle
struct  PolynomialCurve
struct  PiecewiseFittedCurve
class  Lines2VDSegments
class  MedialAxis
class  VoronoiDiagram
struct  SegmentCellRange
struct  PointCellRange
class  VoronoiUtils
struct  ParabolicSegment
class  VoronoiUtilsCgal

Typedefs

template<typename NumberType>
using LinearKernel = CubicKernelWrapper<BicubicInternal::LinearKernel<NumberType>>
template<typename NumberType>
using CubicCatmulRomKernel = CubicKernelWrapper<BicubicInternal::CubicCatmulRomKernel<NumberType>>
template<typename NumberType>
using CubicBSplineKernel = CubicKernelWrapper<BicubicInternal::CubicBSplineKernel<NumberType>>
using Circlef = Circle<Vec2f>
using Circled = Circle<Vec2d>
using VD = VoronoiDiagram
using PolygonsSegmentIndexConstIt = std::vector<Arachne::PolygonsSegmentIndex>::const_iterator
using LinesIt = Lines::iterator
using ColoredLinesConstIt = ColoredLines::const_iterator
using ColoredLinesIt = ColoredLines::iterator
using ParabolicTangentToSegmentOrientation = impl::ParabolicTangentToSegmentOrientationPredicateFiltered
using ParabolicTangentToParabolicTangentOrientation = impl::ParabolicTangentToParabolicTangentOrientationPredicateFiltered
using CGAL_Point = impl::K::Point_2

Enumerations

enum  Orientation { ORIENTATION_CCW = 1 , ORIENTATION_CW = -1 , ORIENTATION_COLINEAR = 0 }

Functions

bool directions_parallel (double angle1, double angle2, double max_diff)
bool directions_perpendicular (double angle1, double angle2, double max_diff)
template<class T>
bool contains (const std::vector< T > &vector, const Point &point)
template bool contains (const ExPolygons &vector, const Point &point)
double rad2deg_dir (double angle)
void simplify_polygons (const Polygons &polygons, double tolerance, Polygons *retval)
double linint (double value, double oldmin, double oldmax, double newmin, double newmax)
bool arrange (size_t total_parts, const Vec2d &part_size, coordf_t dist, const BoundingBoxf *bb, Pointfs &positions)
template<typename T>
T dist (const boost::polygon::point_data< T > &p1, const boost::polygon::point_data< T > &p2)
template<typename segment_type, typename point_type>
point_type project_point_to_segment (segment_type &seg, point_type &px)
void assemble_transform (Transform3d &transform, const Vec3d &translation, const Vec3d &rotation, const Vec3d &scale, const Vec3d &mirror)
Transform3d assemble_transform (const Vec3d &translation, const Vec3d &rotation, const Vec3d &scale, const Vec3d &mirror)
void assemble_transform (Transform3d &transform, const Transform3d &translation, const Transform3d &rotation, const Transform3d &scale, const Transform3d &mirror)
Transform3d assemble_transform (const Transform3d &translation, const Transform3d &rotation, const Transform3d &scale, const Transform3d &mirror)
void translation_transform (Transform3d &transform, const Vec3d &translation)
Transform3d translation_transform (const Vec3d &translation)
void rotation_transform (Transform3d &transform, const Vec3d &rotation)
Transform3d rotation_transform (const Vec3d &rotation)
void scale_transform (Transform3d &transform, double scale)
void scale_transform (Transform3d &transform, const Vec3d &scale)
Transform3d scale_transform (double scale)
Transform3d scale_transform (const Vec3d &scale)
Vec3d extract_euler_angles (const Eigen::Matrix< double, 3, 3, Eigen::DontAlign > &rotation_matrix)
Vec3d extract_euler_angles (const Transform3d &transform)
void rotation_from_two_vectors (Vec3d from, Vec3d to, Vec3d &rotation_axis, double &phi, Matrix3d *rotation_matrix)
static std::pair< Transform3d, Transform3d > extract_rotation_scale (const Transform3d &trafo)
static Transform3d extract_rotation_matrix (const Transform3d &trafo)
static Transform3d extract_scale (const Transform3d &trafo)
static bool contains_skew (const Transform3d &trafo)
Transform3d transform3d_from_string (const std::string &transform_str)
Eigen::Quaterniond rotation_xyz_diff (const Vec3d &rot_xyz_from, const Vec3d &rot_xyz_to)
double rotation_diff_z (const Vec3d &rot_xyz_from, const Vec3d &rot_xyz_to)
Transformation mat_around_a_point_rotate (const Transformation &InMat, const Vec3d &pt, const Vec3d &axis, float rotate_theta_radian)
Transformation generate_transform (const Vec3d &x_dir, const Vec3d &y_dir, const Vec3d &z_dir, const Vec3d &origin)
bool is_point_inside_polygon_corner (const Point &a, const Point &b, const Point &c, const Point &query_point)
static Orientation orient (const Point &a, const Point &b, const Point &c)
static bool is_ccw (const Polygon &poly)
bool ray_ray_intersection (const Vec2d &p1, const Vec2d &v1, const Vec2d &p2, const Vec2d &v2, Vec2d &res)
bool segment_segment_intersection (const Vec2d &p1, const Vec2d &v1, const Vec2d &p2, const Vec2d &v2, Vec2d &res)
bool segments_intersect (const Slic3r::Point &ip1, const Slic3r::Point &ip2, const Slic3r::Point &jp1, const Slic3r::Point &jp2)
template<typename T>
T foot_pt (const T &line_pt, const T &line_dir, const T &pt)
Vec2d foot_pt (const Line &iline, const Point &ipt)
template<typename T>
auto ray_point_distance_squared (const T &ray_pt, const T &ray_dir, const T &pt)
template<typename T>
auto ray_point_distance (const T &ray_pt, const T &ray_dir, const T &pt)
double ray_point_distance_squared (const Line &iline, const Point &ipt)
double ray_point_distance (const Line &iline, const Point &ipt)
template<typename T>
bool liang_barsky_line_clipping_interval (const Eigen::Matrix< T, 2, 1, Eigen::DontAlign > &x0, const Eigen::Matrix< T, 2, 1, Eigen::DontAlign > &v, const BoundingBoxBase< Eigen::Matrix< T, 2, 1, Eigen::DontAlign > > &bbox, std::pair< double, double > &out_interval)
template<typename T>
bool liang_barsky_line_clipping (Eigen::Matrix< T, 2, 1, Eigen::DontAlign > &x0, Eigen::Matrix< T, 2, 1, Eigen::DontAlign > &x1, const BoundingBoxBase< Eigen::Matrix< T, 2, 1, Eigen::DontAlign > > &bbox)
template<typename T>
bool liang_barsky_line_clipping (const Eigen::Matrix< T, 2, 1, Eigen::DontAlign > &x0src, const Eigen::Matrix< T, 2, 1, Eigen::DontAlign > &x1src, const BoundingBoxBase< Eigen::Matrix< T, 2, 1, Eigen::DontAlign > > &bbox, Eigen::Matrix< T, 2, 1, Eigen::DontAlign > &x0clip, Eigen::Matrix< T, 2, 1, Eigen::DontAlign > &x1clip)
template<typename T>
T rad2deg (T angle)
template<typename T>
constexpr T deg2rad (const T angle)
template<typename T>
T angle_to_0_2PI (T angle)
template<typename T>
void to_range_pi_pi (T &angle)
bool is_rotation_ninety_degrees (double a)
bool is_rotation_ninety_degrees (const Vec3d &rotation)
template<typename KernelWrapper>
static KernelWrapper::FloatType cubic_interpolate (const Eigen::ArrayBase< typename KernelWrapper::FloatType > &F, const typename KernelWrapper::FloatType pt)
template<typename Kernel, typename Derived>
static float bicubic_interpolate (const Eigen::MatrixBase< Derived > &F, const Eigen::Matrix< typename Kernel::FloatType, 2, 1, Eigen::DontAlign > &pt)
Point circle_center_taubin_newton (const Points::const_iterator &input_start, const Points::const_iterator &input_end, size_t cycles=20)
 Find the center of the circle corresponding to the vector of Points as an arc.
Vec2d circle_center_taubin_newton (const Vec2ds::const_iterator &input_begin, const Vec2ds::const_iterator &input_end, size_t cycles)
 Adapted from work in "Circular and Linear Regression: Fitting circles and lines by least squares", pg 126 Returns a point corresponding to the center of a circle for which all of the points from input_begin to input_end lie on.
Circled circle_taubin_newton (const Vec2ds &input, size_t cycles)
Circled circle_ransac (const Vec2ds &input, size_t iterations, double *min_error)
template<typename Vector>
Vector circle_center (const Vector &a, const Vector &bsrc, const Vector &csrc, typename Vector::Scalar epsilon)
Point circle_center_taubin_newton (const Points &input, size_t cycles=20)
Vec2d circle_center_taubin_newton (const Vec2ds &input, size_t cycles=20)
template<typename Vector, typename Points>
CircleSq< Vector > smallest_enclosing_circle2_welzl (const Points &points, const typename Vector::Scalar epsilon)
template<typename Vector, typename Points>
Circle< Vector > smallest_enclosing_circle_welzl (const Points &points, const typename Vector::Scalar epsilon)
Circled smallest_enclosing_circle_welzl (const Points &points)
template<typename T>
int ray_circle_intersections_r2_lv2_c (T r2, T a, T b, T lv2, T c, std::pair< Eigen::Matrix< T, 2, 1, Eigen::DontAlign >, Eigen::Matrix< T, 2, 1, Eigen::DontAlign > > &out)
template<typename T>
int ray_circle_intersections (T r, T a, T b, T c, std::pair< Eigen::Matrix< T, 2, 1, Eigen::DontAlign >, Eigen::Matrix< T, 2, 1, Eigen::DontAlign > > &out)
Polygon convex_hull (Points pts)
Pointf3s convex_hull (Pointf3s points)
Polygon convex_hull (const Polygons &polygons)
Polygon convex_hull (const ExPolygons &expolygons)
Polygon convex_hulll (const Polylines &polylines)
bool convex_polygons_intersect (const Polygon &A, const Polygon &B)
std::pair< std::vector< Vec2d >, std::vector< Vec2d > > decompose_convex_polygon_top_bottom (const std::vector< Vec2d > &src)
bool inside_convex_polygon (const std::pair< std::vector< Vec2d >, std::vector< Vec2d > > &top_bottom_decomposition, const Vec2d &pt)
template<int Dimension, typename NumberType>
PolynomialCurve< Dimension, NumberType > fit_polynomial (const std::vector< Vec< Dimension, NumberType > > &observations, const std::vector< NumberType > &observation_points, const std::vector< NumberType > &weights, size_t order)
template<typename Kernel, int Dimension, typename NumberType>
PiecewiseFittedCurve< Dimension, NumberType, Kernel > fit_curve (const std::vector< Vec< Dimension, NumberType > > &observations, const std::vector< NumberType > &observation_points, const std::vector< NumberType > &weights, size_t segments_count, size_t endpoints_level_of_freedom)
template<int Dimension, typename NumberType>
PiecewiseFittedCurve< Dimension, NumberType, LinearKernel< NumberType > > fit_linear_spline (const std::vector< Vec< Dimension, NumberType > > &observations, std::vector< NumberType > observation_points, std::vector< NumberType > weights, size_t segments_count, size_t endpoints_level_of_freedom=0)
template<int Dimension, typename NumberType>
PiecewiseFittedCurve< Dimension, NumberType, CubicBSplineKernel< NumberType > > fit_cubic_bspline (const std::vector< Vec< Dimension, NumberType > > &observations, std::vector< NumberType > observation_points, std::vector< NumberType > weights, size_t segments_count, size_t endpoints_level_of_freedom=0)
template<int Dimension, typename NumberType>
PiecewiseFittedCurve< Dimension, NumberType, CubicCatmulRomKernel< NumberType > > fit_catmul_rom_spline (const std::vector< Vec< Dimension, NumberType > > &observations, std::vector< NumberType > observation_points, std::vector< NumberType > weights, size_t segments_count, size_t endpoints_level_of_freedom=0)
template<typename VD, typename SEGMENTS>
const VD::point_type retrieve_cell_point (const typename VD::cell_type &cell, const SEGMENTS &segments)
template<typename VD, typename SEGMENTS>
std::pair< typename VD::coord_type, typename VD::coord_type > measure_edge_thickness (const VD &vd, const typename VD::edge_type &edge, const SEGMENTS &segments)
VD::vertex_type::color_type encode_input_segment_endpoint (const VD::cell_type::source_index_type cell_source_index, const boost::polygon::direction_1d dir)
template<typename SegmentIterator>
boost::polygon::enable_if< typenameboost::polygon::gtl_if< typenameboost::polygon::is_segment_concept< typenameboost::polygon::geometry_concept< typenamestd::iterator_traits< SegmentIterator >::value_type >::type >::type >::type, typenameboost::polygon::segment_point_type< typenamestd::iterator_traits< SegmentIterator >::value_type >::type >::type decode_input_segment_endpoint (const VD::vertex_type::color_type color, const SegmentIterator segment_begin, const SegmentIterator segment_end)
CGAL_Point to_cgal_point (const VD::vertex_type *pt)
CGAL_Point to_cgal_point (const Point &pt)
CGAL_Point to_cgal_point (const Vec2d &pt)
Linef make_linef (const VD::edge_type &edge)
bool is_equal (const VD::vertex_type &vertex_first, const VD::vertex_type &vertex_second)
template<typename SegmentIterator>
static boost::polygon::enable_if< typenameboost::polygon::gtl_if< typenameboost::polygon::is_segment_concept< typenameboost::polygon::geometry_concept< typenamestd::iterator_traits< SegmentIterator >::value_type >::type >::type >::type, ParabolicSegment >::type get_parabolic_segment (const VD::edge_type &edge, const SegmentIterator segment_begin, const SegmentIterator segment_end)
template<typename SegmentIterator>
static boost::polygon::enable_if< typenameboost::polygon::gtl_if< typenameboost::polygon::is_segment_concept< typenameboost::polygon::geometry_concept< typenamestd::iterator_traits< SegmentIterator >::value_type >::type >::type >::type, CGAL::Orientation >::type orientation_of_two_edges (const VD::edge_type &edge_a, const VD::edge_type &edge_b, const SegmentIterator segment_begin, const SegmentIterator segment_end)
template<typename SegmentIterator>
static boost::polygon::enable_if< typenameboost::polygon::gtl_if< typenameboost::polygon::is_segment_concept< typenameboost::polygon::geometry_concept< typenamestd::iterator_traits< SegmentIterator >::value_type >::type >::type >::type, bool >::type check_if_three_edges_are_ccw (const VD::edge_type &edge_first, const VD::edge_type &edge_second, const VD::edge_type &edge_third, const SegmentIterator segment_begin, const SegmentIterator segment_end)

Class Documentation

◆ Slic3r::Geometry::ArrangeItem

class Slic3r::Geometry::ArrangeItem
Class Members
coordf_t dist
size_t index_x
size_t index_y
Vec2d pos = Vec2d::Zero()

◆ Slic3r::Geometry::ParabolicSegment

struct Slic3r::Geometry::ParabolicSegment
Collaboration diagram for Slic3r::Geometry::ParabolicSegment:
Class Members
const Line directrix
const Point focus
const Orientation is_focus_on_left
const Linef segment

Typedef Documentation

◆ CGAL_Point

using Slic3r::Geometry::CGAL_Point = impl::K::Point_2

◆ Circled

◆ Circlef

◆ ColoredLinesConstIt

using Slic3r::Geometry::ColoredLinesConstIt = ColoredLines::const_iterator

◆ ColoredLinesIt

using Slic3r::Geometry::ColoredLinesIt = ColoredLines::iterator

◆ CubicBSplineKernel

◆ CubicCatmulRomKernel

◆ LinearKernel

template<typename NumberType>
using Slic3r::Geometry::LinearKernel = CubicKernelWrapper<BicubicInternal::LinearKernel<NumberType>>

◆ LinesIt

using Slic3r::Geometry::LinesIt = Lines::iterator

◆ ParabolicTangentToParabolicTangentOrientation

◆ ParabolicTangentToSegmentOrientation

◆ PolygonsSegmentIndexConstIt

typedef std::vector< Arachne::PolygonsSegmentIndex >::const_iterator Slic3r::Geometry::PolygonsSegmentIndexConstIt = std::vector<Arachne::PolygonsSegmentIndex>::const_iterator

◆ VD

Enumeration Type Documentation

◆ Orientation

Enumerator
ORIENTATION_CCW 
ORIENTATION_CW 
ORIENTATION_COLINEAR 
31{
33 ORIENTATION_CW = -1,
35};
@ ORIENTATION_CCW
Definition Geometry.hpp:32
@ ORIENTATION_COLINEAR
Definition Geometry.hpp:34
@ ORIENTATION_CW
Definition Geometry.hpp:33

Function Documentation

◆ angle_to_0_2PI()

template<typename T>
T Slic3r::Geometry::angle_to_0_2PI ( T angle)
318{
319 static const T TWO_PI = T(2) * T(PI);
320 while (angle < T(0))
321 {
322 angle += TWO_PI;
323 }
324 while (TWO_PI < angle)
325 {
326 angle -= TWO_PI;
327 }
328
329 return angle;
330}
static constexpr double PI
Definition libslic3r.h:81
double angle(const Eigen::MatrixBase< Derived > &v1, const Eigen::MatrixBase< Derived2 > &v2)
Definition Point.hpp:138

References Slic3r::angle(), and PI.

Referenced by Slic3r::Geometry::Transformation::set_rotation().

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

◆ arrange()

bool Slic3r::Geometry::arrange ( size_t total_parts,
const Vec2d & part_size,
coordf_t dist,
const BoundingBoxf * bb,
Pointfs & positions )
173{
174 positions.clear();
175
176 Vec2d part = part_size;
177
178 // use actual part size (the largest) plus separation distance (half on each side) in spacing algorithm
179 part(0) += dist;
180 part(1) += dist;
181
182 Vec2d area(Vec2d::Zero());
183 if (bb != NULL && bb->defined) {
184 area = bb->size();
185 } else {
186 // bogus area size, large enough not to trigger the error below
187 area(0) = part(0) * total_parts;
188 area(1) = part(1) * total_parts;
189 }
190
191 // this is how many cells we have available into which to put parts
192 size_t cellw = floor((area(0) + dist) / part(0));
193 size_t cellh = floor((area(1) + dist) / part(1));
194 if (total_parts > (cellw * cellh))
195 return false;
196
197 // total space used by cells
198 Vec2d cells(cellw * part(0), cellh * part(1));
199
200 // bounding box of total space used by cells
201 BoundingBoxf cells_bb;
202 cells_bb.merge(Vec2d(0,0)); // min
203 cells_bb.merge(cells); // max
204
205 // center bounding box to area
206 cells_bb.translate(
207 (area(0) - cells(0)) / 2,
208 (area(1) - cells(1)) / 2
209 );
210
211 // list of cells, sorted by distance from center
212 std::vector<ArrangeItemIndex> cellsorder;
213
214 // work out distance for all cells, sort into list
215 for (size_t i = 0; i <= cellw-1; ++i) {
216 for (size_t j = 0; j <= cellh-1; ++j) {
217 coordf_t cx = linint(i + 0.5, 0, cellw, cells_bb.min(0), cells_bb.max(0));
218 coordf_t cy = linint(j + 0.5, 0, cellh, cells_bb.min(1), cells_bb.max(1));
219
220 coordf_t xd = fabs((area(0) / 2) - cx);
221 coordf_t yd = fabs((area(1) / 2) - cy);
222
223 ArrangeItem c;
224 c.pos(0) = cx;
225 c.pos(1) = cy;
226 c.index_x = i;
227 c.index_y = j;
228 c.dist = xd * xd + yd * yd - fabs((cellw / 2) - (i + 0.5));
229
230 // binary insertion sort
231 {
232 coordf_t index = c.dist;
233 size_t low = 0;
234 size_t high = cellsorder.size();
235 while (low < high) {
236 size_t mid = (low + ((high - low) / 2)) | 0;
237 coordf_t midval = cellsorder[mid].index;
238
239 if (midval < index) {
240 low = mid + 1;
241 } else if (midval > index) {
242 high = mid;
243 } else {
244 cellsorder.insert(cellsorder.begin() + mid, ArrangeItemIndex(index, c));
245 goto ENDSORT;
246 }
247 }
248 cellsorder.insert(cellsorder.begin() + low, ArrangeItemIndex(index, c));
249 }
250 ENDSORT: ;
251 }
252 }
253
254 // the extents of cells actually used by objects
255 coordf_t lx = 0;
256 coordf_t ty = 0;
257 coordf_t rx = 0;
258 coordf_t by = 0;
259
260 // now find cells actually used by objects, map out the extents so we can position correctly
261 for (size_t i = 1; i <= total_parts; ++i) {
262 ArrangeItemIndex c = cellsorder[i - 1];
263 coordf_t cx = c.item.index_x;
264 coordf_t cy = c.item.index_y;
265 if (i == 1) {
266 lx = rx = cx;
267 ty = by = cy;
268 } else {
269 if (cx > rx) rx = cx;
270 if (cx < lx) lx = cx;
271 if (cy > by) by = cy;
272 if (cy < ty) ty = cy;
273 }
274 }
275 // now we actually place objects into cells, positioned such that the left and bottom borders are at 0
276 for (size_t i = 1; i <= total_parts; ++i) {
277 ArrangeItemIndex c = cellsorder.front();
278 cellsorder.erase(cellsorder.begin());
279 coordf_t cx = c.item.index_x - lx;
280 coordf_t cy = c.item.index_y - ty;
281
282 positions.push_back(Vec2d(cx * part(0), cy * part(1)));
283 }
284
285 if (bb != NULL && bb->defined) {
286 for (Pointfs::iterator p = positions.begin(); p != positions.end(); ++p) {
287 p->x() += bb->min(0);
288 p->y() += bb->min(1);
289 }
290 }
291
292 return true;
293}
PointType size() const
Definition BoundingBox.cpp:178
bool defined
Definition BoundingBox.hpp:22
PointType min
Definition BoundingBox.hpp:20
Definition Geometry.cpp:164
double coordf_t
Definition libslic3r.h:51
T dist(const boost::polygon::point_data< T > &p1, const boost::polygon::point_data< T > &p2)
Definition Geometry.cpp:298
double linint(double value, double oldmin, double oldmax, double newmin, double newmax)
Definition Geometry.cpp:84
double coordf_t
Definition GUI_ObjectList.hpp:46
double area(const ExPolygon &poly)
Definition ExPolygon.hpp:511
Eigen::Matrix< double, 2, 1, Eigen::DontAlign > Vec2d
Definition Point.hpp:67

References Slic3r::area(), Slic3r::BoundingBoxBase< PointType, APointsType >::defined, Slic3r::Geometry::ArrangeItem::dist, dist(), Slic3r::Geometry::ArrangeItem::index_x, Slic3r::Geometry::ArrangeItem::index_y, Slic3r::Geometry::ArrangeItemIndex::item, linint(), Slic3r::BoundingBoxBase< PointType, APointsType >::max, Slic3r::BoundingBoxBase< PointType, APointsType >::merge(), Slic3r::BoundingBoxBase< PointType, APointsType >::min, Slic3r::Geometry::ArrangeItem::pos, Slic3r::BoundingBoxBase< PointType, APointsType >::size(), and Slic3r::BoundingBoxBase< PointType, APointsType >::translate().

Referenced by Slic3r::arrangement::arrange().

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

◆ assemble_transform() [1/4]

Transform3d Slic3r::Geometry::assemble_transform ( const Transform3d & translation,
const Transform3d & rotation,
const Transform3d & scale,
const Transform3d & mirror )
340{
342 assemble_transform(transform, translation, rotation, scale, mirror);
343 return transform;
344}
int scale(const int val)
Definition WipeTowerDialog.cpp:58
void assemble_transform(Transform3d &transform, const Vec3d &translation, const Vec3d &rotation, const Vec3d &scale, const Vec3d &mirror)
Definition Geometry.cpp:319
Eigen::Transform< double, 3, Eigen::Affine, Eigen::DontAlign > Transform3d
Definition Point.hpp:96
Linef3 transform(const Linef3 &line, const Transform3d &t)
Definition Line.cpp:15

References assemble_transform(), scale(), and Slic3r::transform().

Here is the call graph for this function:

◆ assemble_transform() [2/4]

Transform3d Slic3r::Geometry::assemble_transform ( const Vec3d & translation,
const Vec3d & rotation,
const Vec3d & scale,
const Vec3d & mirror )
328{
330 assemble_transform(transform, translation, rotation, scale, mirror);
331 return transform;
332}

References assemble_transform(), scale(), and Slic3r::transform().

Here is the call graph for this function:

◆ assemble_transform() [3/4]

void Slic3r::Geometry::assemble_transform ( Transform3d & transform,
const Transform3d & translation,
const Transform3d & rotation,
const Transform3d & scale,
const Transform3d & mirror )
335{
336 transform = translation * rotation * scale * mirror;
337}

References scale(), and Slic3r::transform().

Here is the call graph for this function:

◆ assemble_transform() [4/4]

void Slic3r::Geometry::assemble_transform ( Transform3d & transform,
const Vec3d & translation,
const Vec3d & rotation,
const Vec3d & scale,
const Vec3d & mirror )
320{
321 transform = Transform3d::Identity();
322 transform.translate(translation);
323 transform.rotate(Eigen::AngleAxisd(rotation(2), Vec3d::UnitZ()) * Eigen::AngleAxisd(rotation(1), Vec3d::UnitY()) * Eigen::AngleAxisd(rotation(0), Vec3d::UnitX()));
324 transform.scale(scale.cwiseProduct(mirror));
325}

References scale(), and Slic3r::transform().

Referenced by Slic3r::GUI::GLCanvas3D::_render_sla_slices(), assemble_transform(), assemble_transform(), Slic3r::compacted_tower_print_instance_hull(), Slic3r::GUI::GLCanvas3D::get_empty_cells(), Slic3r::sla::RotfinderBoilerplate< MAX_ITER >::get_mesh_to_rotate(), Slic3r::layered_print_cleareance_valid(), Slic3r::GLVolume::SinkingContours::render(), Slic3r::GUI::Bed3D::Axes::render(), Slic3r::GUI::GLGizmoBase::Grabber::render(), Slic3r::GUI::GLGizmoTextureDisplacement::render_adjust_texture_gizmo(), Slic3r::GUI::GLGizmoPainterBase::render_cursor_height_range(), Slic3r::GUI::GLGizmoPainterBase::render_cursor_sphere(), Slic3r::GUI::Bed3D::render_model(), Slic3r::GUI::Selection::render_sidebar_hints(), Slic3r::GUI::Selection::render_sidebar_position_hints(), Slic3r::GUI::Selection::render_sidebar_rotation_hints(), Slic3r::GUI::Selection::render_sidebar_scale_hints(), Slic3r::GUI::Selection::scale_and_translate(), Slic3r::Print::sequential_print_clearance_valid(), and Slic3r::GUI::GLCanvas3D::update_sequential_clearance().

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

◆ bicubic_interpolate()

template<typename Kernel, typename Derived>
float Slic3r::Geometry::bicubic_interpolate ( const Eigen::MatrixBase< Derived > & F,
const Eigen::Matrix< typename Kernel::FloatType, 2, 1, Eigen::DontAlign > & pt )
static
261 {
262 typedef typename Kernel::FloatType T;
263 const int w = F.cols();
264 const int h = F.rows();
265 const int ix = (int) floor(pt[0]);
266 const int iy = (int) floor(pt[1]);
267 const T s = pt[0] - T( ix);
268 const T t = pt[1] - T( iy);
269
270 if (ix > 1 && ix + 2 < w && iy > 1 && iy + 2 < h) {
271 // Inside the fully interpolated region.
272 return Kernel::interpolate(
273 Kernel::interpolate(F(ix - 1, iy - 1), F(ix, iy - 1), F(ix + 1, iy - 1), F(ix + 2, iy - 1), s),
274 Kernel::interpolate(F(ix - 1, iy), F(ix, iy), F(ix + 1, iy), F(ix + 2, iy), s),
275 Kernel::interpolate(F(ix - 1, iy + 1), F(ix, iy + 1), F(ix + 1, iy + 1), F(ix + 2, iy + 1), s),
276 Kernel::interpolate(F(ix - 1, iy + 2), F(ix, iy + 2), F(ix + 1, iy + 2), F(ix + 2, iy + 2), s), t);
277 }
278 // Transition region. Extend with a constant function.
279 auto f = [&F, w, h](int x, int y) {
280 return F(BicubicInternal::clamp(x, 0, w - 1), BicubicInternal::clamp(y, 0, h - 1));
281 };
282 return Kernel::interpolate(
283 Kernel::interpolate(f(ix - 1, iy - 1), f(ix, iy - 1), f(ix + 1, iy - 1), f(ix + 2, iy - 1), s),
284 Kernel::interpolate(f(ix - 1, iy), f(ix, iy), f(ix + 1, iy), f(ix + 2, iy), s),
285 Kernel::interpolate(f(ix - 1, iy + 1), f(ix, iy + 1), f(ix + 1, iy + 1), f(ix + 2, iy + 1), s),
286 Kernel::interpolate(f(ix - 1, iy + 2), f(ix, iy + 2), f(ix + 1, iy + 2), f(ix + 2, iy + 2), s), t);
287}
T clamp(T a, T lower, T upper)
Definition Bicubic.hpp:186
static double f(double x, double z_sin, double z_cos, bool vertical, bool flip)
Definition FillGyroid.cpp:124
@ F
Definition libslic3r.h:145

References Slic3r::Geometry::BicubicInternal::clamp(), Slic3r::F, and Slic3r::f().

Here is the call graph for this function:

◆ check_if_three_edges_are_ccw()

template<typename SegmentIterator>
boost::polygon::enable_if< typenameboost::polygon::gtl_if< typenameboost::polygon::is_segment_concept< typenameboost::polygon::geometry_concept< typenamestd::iterator_traits< SegmentIterator >::value_type >::type >::type >::type, bool >::type Slic3r::Geometry::check_if_three_edges_are_ccw ( const VD::edge_type & edge_first,
const VD::edge_type & edge_second,
const VD::edge_type & edge_third,
const SegmentIterator segment_begin,
const SegmentIterator segment_end )
static
284{
285 assert(is_equal(*edge_first.vertex0(), *edge_second.vertex0()) && is_equal(*edge_second.vertex0(), *edge_third.vertex0()));
286
287 CGAL::Orientation orientation = orientation_of_two_edges(edge_first, edge_second, segment_begin, segment_end);
288 if (orientation == CGAL::Orientation::COLLINEAR) {
289 // The first two edges are collinear, so the third edge must be on the right side on the first of them.
290 return orientation_of_two_edges(edge_first, edge_third, segment_begin, segment_end) == CGAL::Orientation::RIGHT_TURN;
291 } else if (orientation == CGAL::Orientation::LEFT_TURN) {
292 // CCW oriented angle between vectors (common_pt, pt1) and (common_pt, pt2) is bellow PI.
293 // So we need to check if test_pt isn't between them.
294 CGAL::Orientation orientation1 = orientation_of_two_edges(edge_first, edge_third, segment_begin, segment_end);
295 CGAL::Orientation orientation2 = orientation_of_two_edges(edge_second, edge_third, segment_begin, segment_end);
296 return (orientation1 != CGAL::Orientation::LEFT_TURN || orientation2 != CGAL::Orientation::RIGHT_TURN);
297 } else {
298 assert(orientation == CGAL::Orientation::RIGHT_TURN);
299 // CCW oriented angle between vectors (common_pt, pt1) and (common_pt, pt2) is upper PI.
300 // So we need to check if test_pt is between them.
301 CGAL::Orientation orientation1 = orientation_of_two_edges(edge_first, edge_third, segment_begin, segment_end);
302 CGAL::Orientation orientation2 = orientation_of_two_edges(edge_second, edge_third, segment_begin, segment_end);
303 return (orientation1 == CGAL::Orientation::RIGHT_TURN || orientation2 == CGAL::Orientation::LEFT_TURN);
304 }
305}
bool is_equal(const VD::vertex_type &vertex_first, const VD::vertex_type &vertex_second)
Definition VoronoiUtilsCgal.cpp:161
static boost::polygon::enable_if< typenameboost::polygon::gtl_if< typenameboost::polygon::is_segment_concept< typenameboost::polygon::geometry_concept< typenamestd::iterator_traits< SegmentIterator >::value_type >::type >::type >::type, CGAL::Orientation >::type orientation_of_two_edges(const VD::edge_type &edge_a, const VD::edge_type &edge_b, const SegmentIterator segment_begin, const SegmentIterator segment_end)
Definition VoronoiUtilsCgal.cpp:236
Definition Orient.cpp:47

References is_equal(), and orientation_of_two_edges().

Referenced by Slic3r::Geometry::VoronoiUtilsCgal::is_voronoi_diagram_planar_angle().

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

◆ circle_center()

template<typename Vector>
Vector Slic3r::Geometry::circle_center ( const Vector & a,
const Vector & bsrc,
const Vector & csrc,
typename Vector::Scalar epsilon )
19{
20 using Scalar = typename Vector::Scalar;
21 Vector b = bsrc - a;
22 Vector c = csrc - a;
23 Scalar lb = b.squaredNorm();
24 Scalar lc = c.squaredNorm();
25 if (Scalar d = b.x() * c.y() - b.y() * c.x(); std::abs(d) < epsilon) {
26 // The three points are collinear. Take the center of the two points
27 // furthest away from each other.
28 Scalar lbc = (csrc - bsrc).squaredNorm();
29 return Scalar(0.5) * (
30 lb > lc && lb > lbc ? a + bsrc :
31 lc > lb && lc > lbc ? a + csrc : bsrc + csrc);
32 } else {
33 Vector v = lc * b - lb * c;
34 return a + Vector(- v.y(), v.x()) / (2 * d);
35 }
36}
Point Vector
Definition Point.hpp:42

Referenced by Slic3r::Geometry::CircleSq< Vector >::CircleSq(), and circle_ransac().

Here is the caller graph for this function:

◆ circle_center_taubin_newton() [1/4]

Point Slic3r::Geometry::circle_center_taubin_newton ( const Points & input,
size_t cycles = 20 )
inline
100{ return circle_center_taubin_newton(input.cbegin(), input.cend(), cycles); }
Point circle_center_taubin_newton(const Points::const_iterator &input_begin, const Points::const_iterator &input_end, size_t cycles)
Find the center of the circle corresponding to the vector of Points as an arc.
Definition Circle.cpp:19

References circle_center_taubin_newton().

Here is the call graph for this function:

◆ circle_center_taubin_newton() [2/4]

Point Slic3r::Geometry::circle_center_taubin_newton ( const Points::const_iterator & input_begin,
const Points::const_iterator & input_end,
size_t cycles )

Find the center of the circle corresponding to the vector of Points as an arc.

20{
21 Vec2ds tmp;
22 tmp.reserve(std::distance(input_begin, input_end));
23 std::transform(input_begin, input_end, std::back_inserter(tmp), [] (const Point& in) { return unscale(in); } );
24 Vec2d center = circle_center_taubin_newton(tmp.cbegin(), tmp.end(), cycles);
25 return Point::new_scale(center.x(), center.y());
26}
Definition Point.hpp:199
static Point new_scale(coordf_t x, coordf_t y)
Definition Point.hpp:214
void center(ExPolygonsWithIds &e)
Definition Emboss.cpp:1382
std::vector< Vec2d > Vec2ds
Definition Point.hpp:78
T unscale(Q v)
Definition libslic3r.h:138

References Slic3r::center(), circle_center_taubin_newton(), Slic3r::Point::new_scale(), and Slic3r::unscale().

Referenced by circle_center_taubin_newton(), circle_center_taubin_newton(), circle_center_taubin_newton(), and circle_taubin_newton().

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

◆ circle_center_taubin_newton() [3/4]

Vec2d Slic3r::Geometry::circle_center_taubin_newton ( const Vec2ds & input,
size_t cycles = 20 )
inline
104{ return circle_center_taubin_newton(input.cbegin(), input.cend(), cycles); }

References circle_center_taubin_newton().

Here is the call graph for this function:

◆ circle_center_taubin_newton() [4/4]

Vec2d Slic3r::Geometry::circle_center_taubin_newton ( const Vec2ds::const_iterator & input_begin,
const Vec2ds::const_iterator & input_end,
size_t cycles )

Adapted from work in "Circular and Linear Regression: Fitting circles and lines by least squares", pg 126 Returns a point corresponding to the center of a circle for which all of the points from input_begin to input_end lie on.

Find the center of the circle corresponding to the vector of Pointfs as an arc.

32{
33 // calculate the centroid of the data set
34 const Vec2d sum = std::accumulate(input_begin, input_end, Vec2d(0,0));
35 const size_t n = std::distance(input_begin, input_end);
36 const double n_flt = static_cast<double>(n);
37 const Vec2d centroid { sum / n_flt };
38
39 // Compute the normalized moments of the data set.
40 double Mxx = 0, Myy = 0, Mxy = 0, Mxz = 0, Myz = 0, Mzz = 0;
41 for (auto it = input_begin; it < input_end; ++it) {
42 // center/normalize the data.
43 double Xi {it->x() - centroid.x()};
44 double Yi {it->y() - centroid.y()};
45 double Zi {Xi*Xi + Yi*Yi};
46 Mxy += (Xi*Yi);
47 Mxx += (Xi*Xi);
48 Myy += (Yi*Yi);
49 Mxz += (Xi*Zi);
50 Myz += (Yi*Zi);
51 Mzz += (Zi*Zi);
52 }
53
54 // divide by number of points to get the moments
55 Mxx /= n_flt;
56 Myy /= n_flt;
57 Mxy /= n_flt;
58 Mxz /= n_flt;
59 Myz /= n_flt;
60 Mzz /= n_flt;
61
62 // Compute the coefficients of the characteristic polynomial for the circle
63 // eq 5.60
64 const double Mz {Mxx + Myy}; // xx + yy = z
65 const double Cov_xy {Mxx*Myy - Mxy*Mxy}; // this shows up a couple times so cache it here.
66 const double C3 {4.0*Mz};
67 const double C2 {-3.0*(Mz*Mz) - Mzz};
68 const double C1 {Mz*(Mzz - (Mz*Mz)) + 4.0*Mz*Cov_xy - (Mxz*Mxz) - (Myz*Myz)};
69 const double C0 {(Mxz*Mxz)*Myy + (Myz*Myz)*Mxx - 2.0*Mxz*Myz*Mxy - Cov_xy*(Mzz - (Mz*Mz))};
70
71 const double C22 = {C2 + C2};
72 const double C33 = {C3 + C3 + C3};
73
74 // solve the characteristic polynomial with Newton's method.
75 double xnew = 0.0;
76 double ynew = 1e20;
77
78 for (size_t i = 0; i < cycles; ++i) {
79 const double yold {ynew};
80 ynew = C0 + xnew * (C1 + xnew*(C2 + xnew * C3));
81 if (std::abs(ynew) > std::abs(yold)) {
82 BOOST_LOG_TRIVIAL(error) << "Geometry: Fit is going in the wrong direction.\n";
83 return Vec2d(std::nan(""), std::nan(""));
84 }
85 const double Dy {C1 + xnew*(C22 + xnew*C33)};
86
87 const double xold {xnew};
88 xnew = xold - (ynew / Dy);
89
90 if (std::abs((xnew-xold) / xnew) < 1e-12) i = cycles; // converged, we're done here
91
92 if (xnew < 0) {
93 // reset, we went negative
94 xnew = 0.0;
95 }
96 }
97
98 // compute the determinant and the circle's parameters now that we've solved.
99 double DET = xnew*xnew - xnew*Mz + Cov_xy;
100
101 Vec2d center(Mxz * (Myy - xnew) - Myz * Mxy, Myz * (Mxx - xnew) - Mxz*Mxy);
102 center /= (DET * 2.);
103 return center + centroid;
104}

References Slic3r::center().

Here is the call graph for this function:

◆ circle_ransac()

Circled Slic3r::Geometry::circle_ransac ( const Vec2ds & input,
size_t iterations,
double * min_error )
120{
121 if (input.size() < 3)
122 return Circled::make_invalid();
123
124 std::mt19937 rng;
125 std::vector<Vec2d> samples;
126 Circled circle_best = Circled::make_invalid();
127 double err_min = std::numeric_limits<double>::max();
128 for (size_t iter = 0; iter < iterations; ++ iter) {
129 samples.clear();
130 std::sample(input.begin(), input.end(), std::back_inserter(samples), 3, rng);
131 Circled c;
132 c.center = Geometry::circle_center(samples[0], samples[1], samples[2], EPSILON);
133 c.radius = std::accumulate(input.begin(), input.end(), 0., [&c](double acc, const Vec2d& pt) { return (pt - c.center).norm() + acc; });
134 c.radius /= double(input.size());
135 double err = 0;
136 for (const Vec2d &pt : input)
137 err = std::max(err, std::abs((pt - c.center).norm() - c.radius));
138 if (err < err_min) {
139 err_min = err;
140 circle_best = c;
141 }
142 }
143 if (min_error)
144 *min_error = err_min;
145 return circle_best;
146}
#define EPSILON
Definition ColorUtils.cpp:64
Circle< Vec2d > Circled
Definition Circle.hpp:96
Vector circle_center(const Vector &a, const Vector &bsrc, const Vector &csrc, typename Vector::Scalar epsilon)
Definition Circle.hpp:18
static Circle make_invalid()
Definition Circle.hpp:92
Vector center
Definition Circle.hpp:70
Scalar radius
Definition Circle.hpp:71

References Slic3r::Geometry::Circle< Vector >::center, circle_center(), EPSILON, Slic3r::Geometry::Circle< Vec2d >::make_invalid(), and Slic3r::Geometry::Circle< Vector >::radius.

Referenced by Slic3r::BuildVolume::BuildVolume(), and Slic3r::Measure::get_center_and_radius().

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

◆ circle_taubin_newton()

Circled Slic3r::Geometry::circle_taubin_newton ( const Vec2ds & input,
size_t cycles )
107{
108 Circled out;
109 if (input.size() < 3) {
110 out = Circled::make_invalid();
111 } else {
112 out.center = circle_center_taubin_newton(input, cycles);
113 out.radius = std::accumulate(input.begin(), input.end(), 0., [&out](double acc, const Vec2d& pt) { return (pt - out.center).norm() + acc; });
114 out.radius /= double(input.size());
115 }
116 return out;
117}

References Slic3r::Geometry::Circle< Vector >::center, circle_center_taubin_newton(), Slic3r::Geometry::Circle< Vec2d >::make_invalid(), and Slic3r::Geometry::Circle< Vector >::radius.

Here is the call graph for this function:

◆ contains() [1/2]

template bool Slic3r::Geometry::contains ( const ExPolygons & vector,
const Point & point )

◆ contains() [2/2]

template<class T>
bool Slic3r::Geometry::contains ( const std::vector< T > & vector,
const Point & point )
56{
57 for (typename std::vector<T>::const_iterator it = vector.begin(); it != vector.end(); ++it) {
58 if (it->contains(point)) return true;
59 }
60 return false;
61}

Referenced by Slic3r::FillSpiralInset::_fill_surface_single(), Slic3r::GUI::HMSQuery::_is_internal_error(), Slic3r::GUI::HMSQuery::_query_error_msg(), Slic3r::active_capability_config(), Slic3r::anonymous_namespace{PythonInterpreter.cpp}::add_sys_path_entry(), Slic3r::GUI::MenuFactory::append_menu_items_flush_options(), Slic3r::check_filaments(), Slic3r::GUI::GUI_App::check_new_version(), Slic3r::ExPolygon::contains(), Slic3r::Polygon::contains(), Slic3r::TreeSupport3D::convert_lines_to_internal(), Slic3r::TreeSupport3D::evaluate_point_for_next_layer_function(), Slic3r::SnapmakerPrinterAgent::fetch_filament_info(), Slic3r::IslandLocator::find(), Slic3r::find_containing_expolygon_index(), Slic3r::find_nearby_points(), Slic3r::TreeSupport3D::get_avoidance_status(), Slic3r::GUI::get_error_message(), Slic3r::DevPrinterConfigUtil::get_fan_mode_text(), Slic3r::handle_extrusion_collection(), Slic3r::MoonrakerPrinterAgent::handle_request(), Slic3r::FillLightning::inside(), Slic3r::ClipperUtils::interior_point(), Slic3r::is_inside_ex(), Slic3r::load_assemble_plate_list(), Slic3r::GUI::GuideFrame::LoadProfileFamily(), Slic3r::TreeSupport3D::move_inside_if_outside(), Slic3r::one_of(), Slic3r::one_of(), Slic3r::GUI::GuideFrame::OnScriptMessage(), Slic3r::GUI::ZUserLogin::OnScriptMessage(), Slic3r::BBLSubTask::parse_content_json(), Slic3r::MachineObject::parse_json(), Slic3r::UserManager::parse_json(), Slic3r::DevPrintOptionsParser::ParseDetectionV1_0(), Slic3r::DevFilaSystemParser::ParseV1_0(), Slic3r::anonymous_namespace{ClipperUtils.cpp}::path_encloses(), Slic3r::WipeTowerIntegration::travel_to_tower_gap(), and Slic3r::MachineObject::update_slice_info().

Here is the caller graph for this function:

◆ contains_skew()

bool Slic3r::Geometry::contains_skew ( const Transform3d & trafo)
static
467{
468 return !extract_scale(trafo).linear().isDiagonal();
469}
static Transform3d extract_scale(const Transform3d &trafo)
Definition Geometry.cpp:461

References extract_scale().

Referenced by Slic3r::Geometry::Transformation::has_skew().

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

◆ convex_hull() [1/4]

Polygon Slic3r::Geometry::convex_hull ( const ExPolygons & expolygons)
118{
119 Points pp;
120 size_t sz = 0;
121 for (const auto &expoly : expolygons)
122 sz += expoly.contour.size();
123 pp.reserve(sz);
124 for (const auto &expoly : expolygons)
125 pp.insert(pp.end(), expoly.contour.points.begin(), expoly.contour.points.end());
126 return convex_hull(pp);
127}
Polygon convex_hull(Points pts)
Definition ConvexHull.cpp:21
std::vector< Point, PointsAllocator< Point > > Points
Definition Point.hpp:73

References convex_hull().

Here is the call graph for this function:

◆ convex_hull() [2/4]

Polygon Slic3r::Geometry::convex_hull ( const Polygons & polygons)
109{
110 Points pp;
111 for (Polygons::const_iterator p = polygons.begin(); p != polygons.end(); ++p) {
112 pp.insert(pp.end(), p->points.begin(), p->points.end());
113 }
114 return convex_hull(std::move(pp));
115}

References convex_hull().

Here is the call graph for this function:

◆ convex_hull() [3/4]

Pointf3s Slic3r::Geometry::convex_hull ( Pointf3s points)
51{
52 assert(points.size() >= 3);
53 // sort input points
54 std::sort(points.begin(), points.end(), [](const Vec3d &a, const Vec3d &b){ return a.x() < b.x() || (a.x() == b.x() && a.y() < b.y()); });
55
56 int n = points.size(), k = 0;
57 Pointf3s hull;
58
59 if (n >= 3)
60 {
61 hull.resize(2 * n);
62
63 // Build lower hull
64 for (int i = 0; i < n; ++i)
65 {
66 Point p = Point::new_scale(points[i](0), points[i](1));
67 while (k >= 2)
68 {
69 Point k1 = Point::new_scale(hull[k - 1](0), hull[k - 1](1));
70 Point k2 = Point::new_scale(hull[k - 2](0), hull[k - 2](1));
71
73 --k;
74 else
75 break;
76 }
77
78 hull[k++] = points[i];
79 }
80
81 // Build upper hull
82 for (int i = n - 2, t = k + 1; i >= 0; --i)
83 {
84 Point p = Point::new_scale(points[i](0), points[i](1));
85 while (k >= t)
86 {
87 Point k1 = Point::new_scale(hull[k - 1](0), hull[k - 1](1));
88 Point k2 = Point::new_scale(hull[k - 2](0), hull[k - 2](1));
89
91 --k;
92 else
93 break;
94 }
95
96 hull[k++] = points[i];
97 }
98
99 hull.resize(k);
100
101 assert(hull.front() == hull.back());
102 hull.pop_back();
103 }
104
105 return hull;
106}
static Orientation orient(const Point &a, const Point &b, const Point &c)
Definition Geometry.hpp:44
Eigen::Matrix< double, 3, 1, Eigen::DontAlign > Vec3d
Definition Point.hpp:68
std::vector< Vec3d > Pointf3s
Definition Point.hpp:79

References Slic3r::Point::new_scale(), orient(), and ORIENTATION_CCW.

Here is the call graph for this function:

◆ convex_hull() [4/4]

Polygon Slic3r::Geometry::convex_hull ( Points pts)
22{
23 std::sort(pts.begin(), pts.end(), [](const Point& a, const Point& b) { return a.x() < b.x() || (a.x() == b.x() && a.y() < b.y()); });
24 pts.erase(std::unique(pts.begin(), pts.end(), [](const Point& a, const Point& b) { return a.x() == b.x() && a.y() == b.y(); }), pts.end());
25
26 Polygon hull;
27 int n = (int)pts.size();
28 if (n >= 3) {
29 int k = 0;
30 hull.points.resize(2 * n);
31 // Build lower hull
32 for (int i = 0; i < n; ++ i) {
33 while (k >= 2 && Geometry::orient(pts[i], hull[k-2], hull[k-1]) != Geometry::ORIENTATION_CCW)
34 -- k;
35 hull[k ++] = pts[i];
36 }
37 // Build upper hull
38 for (int i = n-2, t = k+1; i >= 0; i--) {
39 while (k >= t && Geometry::orient(pts[i], hull[k-2], hull[k-1]) != Geometry::ORIENTATION_CCW)
40 -- k;
41 hull[k ++] = pts[i];
42 }
43 hull.points.resize(k);
44 assert(hull.points.front() == hull.points.back());
45 hull.points.pop_back();
46 }
47 return hull;
48}
Points points
Definition MultiPoint.hpp:22
Definition Polygon.hpp:31

References orient(), ORIENTATION_CCW, and Slic3r::MultiPoint::points.

Referenced by Slic3r::BuildVolume::BuildVolume(), Slic3r::ModelVolume::ModelVolume(), Slic3r::Print::_make_skirt(), Slic3r::bed_exclusion_arrange_polygon(), Slic3r::ModelVolume::calculate_convex_hull_2d(), Slic3r::compacted_tower_print_instance_hull(), Slic3r::compacted_wipe_tower_zone(), Slic3r::ExPolygonCollection::convex_hull(), convex_hull(), convex_hull(), Slic3r::TriangleMesh::convex_hull(), Slic3r::ModelObject::convex_hull_2d(), convex_hulll(), Slic3r::GUI::CameraUtils::create_hull2d(), Slic3r::Print::finalize_first_layer_convex_hull(), Slic3r::generate_extra_perimeters_over_overhangs(), Slic3r::get_arrange_poly(), Slic3r::GUI::anonymous_namespace{GLGizmoAlignment.cpp}::instance_box_in_frame(), Slic3r::its_convex_hull_2d_above(), Slic3r::lay_on_face_planes(), Slic3r::GLVolumeCollection::load_object_auxiliary(), Slic3r::nearest_clear_wipe_tower_anchor(), Slic3r::Print::sequential_print_clearance_valid(), Slic3r::solid_bodies(), Slic3r::ModelVolume::transform_this_mesh(), Slic3r::ModelVolume::transform_this_mesh(), Slic3r::sla::SupportPointGenerator::uniformly_cover(), Slic3r::GUI::GLCanvas3D::update_sequential_clearance(), and Slic3r::Print::validate_compacted_wipe_tower_clearance().

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

◆ convex_hulll()

Polygon Slic3r::Geometry::convex_hulll ( const Polylines & polylines)
130{
131 Points pp;
132 size_t sz = 0;
133 for (const auto &polyline : polylines)
134 sz += polyline.points.size();
135 pp.reserve(sz);
136 for (const auto &polyline : polylines)
137 pp.insert(pp.end(), polyline.points.begin(), polyline.points.end());
138 return convex_hull(pp);
139}

References convex_hull().

Here is the call graph for this function:

◆ convex_polygons_intersect()

bool Slic3r::Geometry::convex_polygons_intersect ( const Polygon & A,
const Polygon & B )
255{
256 using namespace rotcalip;
257
258 // Establish starting antipodals as extremes in XY plane. Use the
259 // easily obtainable bounding boxes to check if A and B is disjoint
260 // and return false if the are.
261 struct BB
262 {
263 size_t xmin = 0, xmax = 0, ymin = 0, ymax = 0;
264 const Polygon &P;
265 static bool cmpy(const Point &l, const Point &u)
266 {
267 return l.y() < u.y() || (l.y() == u.y() && l.x() < u.x());
268 }
269
270 BB(const Polygon &poly): P{poly}
271 {
272 for (size_t i = 0; i < P.size(); ++i) {
273 if (P[i] < P[xmin]) xmin = i;
274 if (P[xmax] < P[i]) xmax = i;
275 if (cmpy(P[i], P[ymin])) ymin = i;
276 if (cmpy(P[ymax], P[i])) ymax = i;
277 }
278 }
279 };
280
281 BB bA{A}, bB{B};
282 BoundingBox bbA{{A[bA.xmin].x(), A[bA.ymin].y()}, {A[bA.xmax].x(), A[bA.ymax].y()}};
283 BoundingBox bbB{{B[bB.xmin].x(), B[bB.ymin].y()}, {B[bB.xmax].x(), B[bB.ymax].y()}};
284
285// if (!bbA.overlap(bbB))
286// return false;
287
288 // Establish starting antipodals as extreme vertex pairs in X or Y direction
289 // which reside on different polygons. If no such pair is found, the two
290 // polygons are certainly not disjoint.
291 Idx imin{bA.xmin, A}, imax{bB.xmax, B};
292 if (B[bB.xmin] < imin.pt()) imin = Idx{bB.xmin, B};
293 if (imax.pt() < A[bA.xmax]) imax = Idx{bA.xmax, A};
294 if (&imin.poly() == &imax.poly()) {
295 imin = Idx{bA.ymin, A};
296 imax = Idx{bB.ymax, B};
297 if (B[bB.ymin] < imin.pt()) imin = Idx{bB.ymin, B};
298 if (imax.pt() < A[bA.ymax]) imax = Idx{bA.ymax, A};
299 }
300
301 if (&imin.poly() == &imax.poly())
302 return true;
303
304 bool found_divisor = false;
305 visit_antipodals<AntipodalVisitMode::EdgesOnly>(
306 imin, imax,
307 [&imin, &imax, &found_divisor](size_t ia, size_t ib, const Point &dir) {
308 // std::cout << "A" << ia << " B" << ib << " dir " <<
309 // dir.x() << " " << dir.y() << std::endl;
310 const Polygon &A = imin.poly(), &B = imax.poly();
311
312 Point ref_a = A[(ia + 2) % A.size()], ref_b = B[(ib + 2) % B.size()];
313
314 bool is_left_a = dotperp( dir, ref_a - A[ia]) > 0;
315 bool is_left_b = dotperp(-dir, ref_b - B[ib]) > 0;
316
317 // If both reference points are on the left (or right) of their
318 // respective support lines and the opposite support line is to
319 // the right (or left), the divisor line is found. We only test
320 // the reference point, as by definition, if that is on one side,
321 // all the other points must be on the same side of a support
322 // line. If the support lines are collinear, the polygons must be
323 // on the same side of their respective support lines.
324
325 auto d = dotperp(dir, B[ib] - A[ia]);
326 if (d == 0) {
327 // The caliper lines are collinear, not just parallel
328 found_divisor = (is_left_a && is_left_b) || (!is_left_a && !is_left_b);
329 } else if (d > 0) { // B is to the left of (A, A+1)
330 found_divisor = !is_left_a && !is_left_b;
331 } else { // B is to the right of (A, A+1)
332 found_divisor = is_left_a && is_left_b;
333 }
334
335 return !found_divisor;
336 });
337
338 // Intersects if the divisor was not found
339 return !found_divisor;
340}
size_t size() const
Definition MultiPoint.hpp:50
Definition ConvexHull.cpp:141
Scalar dotperp(const Point &a, const Point &b)
Definition ConvexHull.cpp:159
Kernel::Point_3 Point
Definition MeshRepair.cpp:81
@ P
Definition libslic3r.h:149
Slic3r::Polygon Polygon
Definition Emboss.cpp:101

References Slic3r::P, and Slic3r::MultiPoint::size().

Here is the call graph for this function:

◆ cubic_interpolate()

template<typename KernelWrapper>
KernelWrapper::FloatType Slic3r::Geometry::cubic_interpolate ( const Eigen::ArrayBase< typename KernelWrapper::FloatType > & F,
const typename KernelWrapper::FloatType pt )
static
242 {
243 typedef typename KernelWrapper::FloatType T;
244 const int w = int(F.size());
245 const int ix = (int) floor(pt);
246 const T s = pt - T( ix);
247
248 if (ix > 1 && ix + 2 < w) {
249 // Inside the fully interpolated region.
250 return KernelWrapper::interpolate(F[ix - 1], F[ix], F[ix + 1], F[ix + 2], s);
251 }
252 // Transition region. Extend with a constant function.
253 auto f = [&F, w](T x) {
254 return F[BicubicInternal::clamp(x, 0, w - 1)];
255 };
256 return KernelWrapper::interpolate(f(ix - 1), f(ix), f(ix + 1), f(ix + 2), s);
257}

References Slic3r::Geometry::BicubicInternal::clamp(), Slic3r::F, and Slic3r::f().

Here is the call graph for this function:

◆ decode_input_segment_endpoint()

template<typename SegmentIterator>
boost::polygon::enable_if< typenameboost::polygon::gtl_if< typenameboost::polygon::is_segment_concept< typenameboost::polygon::geometry_concept< typenamestd::iterator_traits< SegmentIterator >::value_type >::type >::type >::type, typenameboost::polygon::segment_point_type< typenamestd::iterator_traits< SegmentIterator >::value_type >::type >::type Slic3r::Geometry::decode_input_segment_endpoint ( const VD::vertex_type::color_type color,
const SegmentIterator segment_begin,
const SegmentIterator segment_end )
inline
280{
281 using SegmentType = typename std::iterator_traits<SegmentIterator>::value_type;
283
284 const size_t segment_idx = (color >> 1) - 1;
285 const SegmentIterator segment_it = segment_begin + segment_idx;
286 const PointType source_point = boost::polygon::segment_traits<SegmentType>::get(*segment_it, ((color & 1) ? boost::polygon::HIGH :
287 boost::polygon::LOW));
288 return source_point;
289}
Definition Voronoi.hpp:21

Referenced by Slic3r::Geometry::VoronoiDiagram::try_to_repair_degenerated_voronoi_diagram_by_rotation().

Here is the caller graph for this function:

◆ decompose_convex_polygon_top_bottom()

std::pair< std::vector< Vec2d >, std::vector< Vec2d > > Slic3r::Geometry::decompose_convex_polygon_top_bottom ( const std::vector< Vec2d > & src)
346{
347 std::pair<std::vector<Vec2d>, std::vector<Vec2d>> out;
348 std::vector<Vec2d> &bottom = out.first;
349 std::vector<Vec2d> &top = out.second;
350
351 // Find the minimum point.
352 auto left_bottom = std::min_element(src.begin(), src.end(), [](const auto &l, const auto &r) { return l.x() < r.x() || (l.x() == r.x() && l.y() < r.y()); });
353 auto right_top = std::max_element(src.begin(), src.end(), [](const auto &l, const auto &r) { return l.x() < r.x() || (l.x() == r.x() && l.y() < r.y()); });
354 if (left_bottom != src.end() && left_bottom != right_top) {
355 // Produce the bottom and bottom chains.
356 if (left_bottom < right_top) {
357 bottom.assign(left_bottom, right_top + 1);
358 size_t cnt = (src.end() - right_top) + (left_bottom + 1 - src.begin());
359 top.reserve(cnt);
360 top.assign(right_top, src.end());
361 top.insert(top.end(), src.begin(), left_bottom + 1);
362 } else {
363 size_t cnt = (src.end() - left_bottom) + (right_top + 1 - src.begin());
364 bottom.reserve(cnt);
365 bottom.assign(left_bottom, src.end());
366 bottom.insert(bottom.end(), src.begin(), right_top + 1);
367 top.assign(right_top, left_bottom + 1);
368 }
369 // Remove strictly vertical segments at the end.
370 if (bottom.size() > 1) {
371 auto it = bottom.end();
372 for (-- it; it != bottom.begin() && (it - 1)->x() == bottom.back().x(); -- it) ;
373 bottom.erase(it + 1, bottom.end());
374 }
375 if (top.size() > 1) {
376 auto it = top.end();
377 for (-- it; it != top.begin() && (it - 1)->x() == top.back().x(); -- it) ;
378 top.erase(it + 1, top.end());
379 }
380 std::reverse(top.begin(), top.end());
381 }
382
383 if (top.size() < 2 || bottom.size() < 2) {
384 // invalid
385 top.clear();
386 bottom.clear();
387 }
388 return out;
389}

Referenced by Slic3r::BuildVolume::BuildVolume().

Here is the caller graph for this function:

◆ deg2rad()

template<typename T>
T Slic3r::Geometry::deg2rad ( const T angle)
constexpr
313{
314 static_assert(std::is_floating_point<T>::value, "Why do you want to calculate angle in integer?");
315 return T(PI) * angle / T(180.0);
316}

References Slic3r::angle(), and PI.

Referenced by Slic3r::SupportGridParams::SupportGridParams(), Slic3r::SupportParameters::SupportParameters(), Slic3r::Print::_make_wipe_tower(), Slic3r::GUI::belt_calib_rotation_params(), Slic3r::TriangleSelector::bucket_fill_select_triangles(), Slic3r::build_plate_tilt_slope(), Slic3r::GUI::build_plate_tilt_up_direction(), Slic3r::BeltTransformPipeline::build_rotation_matrix(), Slic3r::calculate_infill_rotation_angle(), Slic3r::anonymous_namespace{BeltTransform.cpp}::compute_belt_height_and_floor_impl(), Slic3r::detect_overhangs(), Slic3r::TreeSupport::detect_overhangs(), Slic3r::GUI::ensure_belt_purge_tower(), Slic3r::GUI::PartPlate::estimate_wipe_tower_polygon(), Slic3r::estimated_wipe_tower_footprint(), Slic3r::FillLateralLattice::fill_surface(), Slic3r::Print::first_layer_wipe_tower_corners(), Slic3r::BeltTransformPipeline::floor_shear(), Slic3r::Arachne::WallToolPaths::generate(), Slic3r::InterlockingGenerator::generate_interlocking_structure(), Slic3r::WipeTower2::generate_support_cone_wall(), Slic3r::TreeSupport::generate_toolpaths(), Slic3r::GLVolumeCollection::get_selection_support_normal_z(), Slic3r::WipeTower2::get_wipe_tower_cone_base(), Slic3r::get_wipe_tower_extrusions_extents(), Slic3r::FakeWipeTower::getFakeExtrusionPathsFromWipeTower2(), Slic3r::group_fills(), Slic3r::GUI::PartPlate::imex_wipe_tower_hull(), Slic3r::GUI::init_arrange_params(), Slic3r::MachineFrameTransform::init_from_config(), Slic3r::layered_print_cleareance_valid(), Slic3r::GUI::Plater::priv::load_files(), Slic3r::Layer::make_ironing(), anonymous_namespace{OrcaSlicer_profile_validator.cpp}::place_wipe_tower(), Slic3r::LayerRegion::process_external_surfaces(), Slic3r::PerimeterGenerator::process_no_bridge(), Slic3r::anonymous_namespace{PrintConfig.cpp}::project_bed_material_keepouts(), Slic3r::GUI::GLGizmoCut3D::render_angle_input(), Slic3r::GUI::GLGizmoTextureDisplacement::render_painted_colors(), Slic3r::GUI::GLGizmoPainterBase::render_triangles(), Slic3r::GUI::Bed_2D::repaint(), Slic3r::GUI::Camera::rotate_on_sphere(), Slic3r::GUI::Camera::rotate_on_sphere_with_target(), Slic3r::CLI::run(), Slic3r::TriangleSelector::seed_fill_select_triangles(), Slic3r::TriangleSelector::select_patch(), Slic3r::GUI::Camera::set_default_orientation(), Slic3r::GLVolumeCollection::set_default_slope_normal_z(), Slic3r::GUI::GLCanvas3D::Slope::set_normal_angle(), Slic3r::GUI::GLGizmoMeasure::set_to_around_center_of_faces(), Slic3r::spreadDotsArea(), Slic3r::WipeTower2::toolchange_Change(), and Slic3r::Print::validate_compacted_wipe_tower_clearance().

Here is the call graph for this function:

◆ directions_parallel()

bool Slic3r::Geometry::directions_parallel ( double angle1,
double angle2,
double max_diff )
41{
42 double diff = fabs(angle1 - angle2);
43 max_diff += EPSILON;
44 return diff < max_diff || fabs(diff - PI) < max_diff;
45}
Slic3r::Polygons diff(const Slic3r::Polygon &subject, const Slic3r::Polygon &clip, ApplySafetyOffset do_safety_offset)
Definition ClipperUtils.cpp:731

References Slic3r::diff(), EPSILON, and PI.

Referenced by Slic3r::BridgeDetector::bridge_direction_candidates(), Slic3r::Line::parallel_to(), and Slic3r::BridgeDetector::unsupported_edges().

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

◆ directions_perpendicular()

bool Slic3r::Geometry::directions_perpendicular ( double angle1,
double angle2,
double max_diff )
48{
49 double diff = fabs(angle1 - angle2);
50 max_diff += EPSILON;
51 return fabs(diff - 0.5 * PI) < max_diff || fabs(diff - 1.5 * PI) < max_diff;
52}

References Slic3r::diff(), EPSILON, and PI.

Referenced by Slic3r::Line::perpendicular_to().

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

◆ dist()

template<typename T>
T Slic3r::Geometry::dist ( const boost::polygon::point_data< T > & p1,
const boost::polygon::point_data< T > & p2 )
299{
300 T dx = p2(0) - p1(0);
301 T dy = p2(1) - p1(1);
302 return sqrt(dx*dx+dy*dy);
303}

Referenced by Slic3r::FanMover::_process_gcode_line(), Slic3r::GUI::anonymous_namespace{McpControl.cpp}::action_chamfer(), Slic3r::sla::ConcaveHull::add_connector_rectangles(), arrange(), Slic3r::tex2color::color_utils::calc_nearest_color_id(), Slic3r::chain_points_with_postprocessing(), Slic3r::chain_segments_greedy_constrained_reversals2_(), Slic3r::clip_extrusion(), Slic3r::sla::cluster(), Slic3r::sla::cluster(), Slic3r::sla::SupportTreeBuildsteps::connect_to_model_body(), Slic3r::contour_distance(), Slic3r::contour_distance2(), Slic3r::contour_extrusion_path(), Slic3r::cut_mesh_at_steps(), Slic3r::KDTreeIndirect< 3, float, SeamPlacerImpl::SeamCandidateCoordinateFunctor >::descent_mask(), Slic3r::AABBTreeLines::LinesDistancer< Linef3 >::distance_from_lines(), Slic3r::sla::anonymous_namespace{Clustering.cpp}::distance_queryfn(), Slic3r::GUI::DesignSketchTool::drag_rib_handle(), Slic3r::Model::duplicate_objects_grid(), Slic3r::GCode::extrude_loop(), Slic3r::GCode::extrude_path(), Slic3r::find_closest_points(), Slic3r::sla::anonymous_namespace{Rotfinder.cpp}::find_min_score(), Slic3r::find_nearby_points(), Slic3r::follow_slope_down(), Slic3r::WipeTower2::generate_support_cone_wall(), Slic3r::Measure::MeasuringImpl::get_feature(), Slic3r::sla::DrainHole::get_intersections(), Slic3r::Measure::get_measurement(), Slic3r::get_real_skirt_dist(), Slic3r::arrangement::get_shrink_bedpts(), Slic3r::Arachne::SkeletalTrapezoidation::getNearestBeading(), Slic3r::Arachne::SkeletalTrapezoidation::getOrCreateBeading(), Slic3r::MultiPoint::has_boundary_point(), Slic3r::improve_chain_by_local_search(), Slic3r::improve_cycle_by_or_opt(), Slic3r::Arachne::SkeletalTrapezoidationGraph::insertRib(), Slic3r::TriangleSelector::Capsule2D::is_edge_inside_cursor(), Slic3r::sla::DrainHole::is_inside(), Slic3r::ConflictChecker::line_intersect(), Slic3r::Arachne::SkeletalTrapezoidationGraph::makeRib(), Slic3r::GUI::GLGizmoTextureDisplacement::mark_seam_path(), measure_edge_thickness(), Slic3r::FillAdaptive::multiline_paths(), Slic3r::SpiralVaseHelpers::nearest_point_on_line(), Slic3r::SpiralVaseHelpers::nearest_point_on_lines(), Slic3r::arrangement::AutoArranger< TBin >::objfunc(), Slic3r::Voronoi::offset(), Slic3r::GUI::UVEditorCanvas::on_mouse(), Slic3r::anonymous_namespace{TextureDisplacement.cpp}::patch_boundary_distance(), Slic3r::TimelapsePosPicker::pick_nearest_object_center(), Slic3r::pick_pos_internal(), Slic3r::SeamPlacer::place_seam(), Slic3r::TreeSupport::plan_layer_heights(), Slic3r::SketchConstraints::point_line_distance(), Slic3r::TreeSupport3D::polyline_sample_next_point_at_distance(), Slic3r::SpiralVase::process_layer(), Slic3r::projection_onto(), Slic3r::PrintObjectSupportMaterial::raft_and_intermediate_support_layers(), Slic3r::anonymous_namespace{OrcaCloudServiceAgent.cpp}::random_bytes(), Slic3r::Feature::FuzzySkin::random_value(), Slic3r::GUI::GLGizmoTextureDisplacement::rank_mixes(), Slic3r::GUI::TexturePreviewCanvas::render(), Slic3r::resample_polygon(), Slic3r::anonymous_namespace{TextureDisplacement.cpp}::scan_steps(), Slic3r::separated_body_at(), Slic3r::GUI::GLGizmoMeasure::set_parallel_distance(), Slic3r::GUI::CommonGizmosDataObjects::ObjectClipper::set_position_by_ratio(), Slic3r::Voronoi::signed_vertex_distances(), Slic3r::anonymous_namespace{TextureDisplacement.cpp}::simplify_polyline(), Slic3r::solve_system(), Slic3r::sort_extra_perimeters(), Slic3r::MinCostMaxFlow::spfa(), Slic3r::AABBMesh::AABBImpl::squared_distance(), Slic3r::sla::IndexedMesh::AABBImpl::squared_distance(), Slic3r::Arachne::PolylineStitcher< Paths, Path, Junction >::stitch(), Slic3r::GeometryEngine::surface_deviation(), Slic3r::thick_lines_to_geometry(), Slic3r::WipeTower2::toolchange_Unload(), Slic3r::WipeTower::toolchange_Unload(), Slic3r::tsp_exact_cycle(), Slic3r::GUI::GLGizmoCut3D::update_clipper(), Slic3r::GUI::DesignCanvas::view_normal_to_sketch(), and Slic3r::visit_nearby_points().

◆ encode_input_segment_endpoint()

VD::vertex_type::color_type Slic3r::Geometry::encode_input_segment_endpoint ( const VD::cell_type::source_index_type cell_source_index,
const boost::polygon::direction_1d dir )
inline
270{
271 return (cell_source_index + 1) << 1 | (dir.to_int() ? 1 : 0);
272}

Referenced by Slic3r::Geometry::VoronoiDiagram::try_to_repair_degenerated_voronoi_diagram_by_rotation().

Here is the caller graph for this function:

◆ extract_euler_angles() [1/2]

Vec3d Slic3r::Geometry::extract_euler_angles ( const Eigen::Matrix< double, 3, 3, Eigen::DontAlign > & rotation_matrix)
396{
397 // The extracted "rotation" is a triplet of numbers such that Geometry::rotation_transform
398 // returns the original transform. Because of the chosen order of rotations, the triplet
399 // is not equivalent to Euler angles in the usual sense.
400 Vec3d angles = rotation_matrix.eulerAngles(2,1,0);
401 std::swap(angles(0), angles(2));
402 return angles;
403}

Referenced by extract_euler_angles(), Slic3r::Geometry::Transformation::get_rotation(), Slic3r::ModelVolume::rotate(), Slic3r::ModelInstance::rotate_assemble(), Slic3r::Geometry::Transformation::set_rotation(), Slic3r::GUI::GLGizmoMeasure::set_to_parallel(), and Slic3r::Geometry::Transformation::volume_to_bed_transformation().

Here is the caller graph for this function:

◆ extract_euler_angles() [2/2]

Vec3d Slic3r::Geometry::extract_euler_angles ( const Transform3d & transform)
406{
407 // use only the non-translational part of the transform
408 Eigen::Matrix<double, 3, 3, Eigen::DontAlign> m = transform.matrix().block(0, 0, 3, 3);
409 // remove scale
410 m.col(0).normalize();
411 m.col(1).normalize();
412 m.col(2).normalize();
413 return extract_euler_angles(m);
414}
Vec3d extract_euler_angles(const Eigen::Matrix< double, 3, 3, Eigen::DontAlign > &rotation_matrix)
Definition Geometry.cpp:395

References extract_euler_angles(), and Slic3r::transform().

Here is the call graph for this function:

◆ extract_rotation_matrix()

Transform3d Slic3r::Geometry::extract_rotation_matrix ( const Transform3d & trafo)
static
457{
458 return extract_rotation_scale(trafo).first;
459}
static std::pair< Transform3d, Transform3d > extract_rotation_scale(const Transform3d &trafo)
Definition Geometry.cpp:432

References extract_rotation_scale().

Referenced by Slic3r::Geometry::Transformation::get_rotation(), Slic3r::Geometry::Transformation::get_rotation_matrix(), and Slic3r::Geometry::Transformation::set_scaling_factor().

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

◆ extract_rotation_scale()

std::pair< Transform3d, Transform3d > Slic3r::Geometry::extract_rotation_scale ( const Transform3d & trafo)
static
433{
434 Matrix3d rotation;
436 if (trafo.linear().determinant() >= 0.0) {
437 trafo.computeRotationScaling(&rotation, &scale);
438 return { Transform3d(rotation), Transform3d(scale) };
439 }
440 for (int axis = 0; axis < 3; ++axis) {
441 Transform3d flipped = trafo;
442 flipped.linear().col(axis) *= -1.0;
443 Matrix3d r;
444 Matrix3d s;
445 flipped.computeRotationScaling(&r, &s);
446 // EPSILON keeps the lowest axis on ties, e.g. a mirror rotated by 90 degrees.
447 if (axis == 0 || r.trace() > rotation.trace() + EPSILON) {
448 rotation = r;
449 scale = s;
450 scale.col(axis) *= -1.0;
451 }
452 }
453 return { Transform3d(rotation), Transform3d(scale) };
454}
Eigen::Matrix< double, 3, 3, Eigen::DontAlign > Matrix3d
Definition Point.hpp:86

References EPSILON, and scale().

Referenced by extract_rotation_matrix(), extract_scale(), Slic3r::Geometry::Transformation::set_mirror(), Slic3r::Geometry::Transformation::set_mirror(), Slic3r::Geometry::Transformation::set_rotation(), and Slic3r::Geometry::Transformation::set_scaling_factor().

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

◆ extract_scale()

Transform3d Slic3r::Geometry::extract_scale ( const Transform3d & trafo)
static
462{
463 return extract_rotation_scale(trafo).second;
464}

References extract_rotation_scale().

Referenced by contains_skew(), Slic3r::Geometry::Transformation::get_mirror(), Slic3r::Geometry::Transformation::get_mirror_matrix(), Slic3r::Geometry::Transformation::get_scaling_factor(), Slic3r::Geometry::Transformation::get_scaling_factor_matrix(), and Slic3r::Geometry::Transformation::set_rotation().

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

◆ fit_catmul_rom_spline()

template<int Dimension, typename NumberType>
PiecewiseFittedCurve< Dimension, NumberType, CubicCatmulRomKernel< NumberType > > Slic3r::Geometry::fit_catmul_rom_spline ( const std::vector< Vec< Dimension, NumberType > > & observations,
std::vector< NumberType > observation_points,
std::vector< NumberType > weights,
size_t segments_count,
size_t endpoints_level_of_freedom = 0 )
216 {
217 return fit_curve<CubicCatmulRomKernel<NumberType>>(observations, observation_points, weights, segments_count,
218 endpoints_level_of_freedom);
219}
PiecewiseFittedCurve< Dimension, NumberType, Kernel > fit_curve(const std::vector< Vec< Dimension, NumberType > > &observations, const std::vector< NumberType > &observation_points, const std::vector< NumberType > &weights, size_t segments_count, size_t endpoints_level_of_freedom)
Definition Curves.hpp:103

References fit_curve().

Here is the call graph for this function:

◆ fit_cubic_bspline()

template<int Dimension, typename NumberType>
PiecewiseFittedCurve< Dimension, NumberType, CubicBSplineKernel< NumberType > > Slic3r::Geometry::fit_cubic_bspline ( const std::vector< Vec< Dimension, NumberType > > & observations,
std::vector< NumberType > observation_points,
std::vector< NumberType > weights,
size_t segments_count,
size_t endpoints_level_of_freedom = 0 )
204 {
205 return fit_curve<CubicBSplineKernel<NumberType>>(observations, observation_points, weights, segments_count,
206 endpoints_level_of_freedom);
207}

References fit_curve().

Referenced by Slic3r::SeamPlacer::align_seam_points().

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

◆ fit_curve()

template<typename Kernel, int Dimension, typename NumberType>
PiecewiseFittedCurve< Dimension, NumberType, Kernel > Slic3r::Geometry::fit_curve ( const std::vector< Vec< Dimension, NumberType > > & observations,
const std::vector< NumberType > & observation_points,
const std::vector< NumberType > & weights,
size_t segments_count,
size_t endpoints_level_of_freedom )
108 {
109
110 // check to make sure inputs are correct
111 assert(segments_count > 0);
112 assert(observations.size() > 0);
113 assert(observation_points.size() == observations.size());
114 assert(observation_points.size() == weights.size());
115 assert(segments_count <= observations.size());
116
117 //prepare sqrt of weights, which will then be applied to both matrix T and observed data: https://en.wikipedia.org/wiki/Weighted_least_squares
118 std::vector<NumberType> sqrt_weights(weights.size());
119 for (size_t index = 0; index < weights.size(); ++index) {
120 assert(weights[index] > 0);
121 sqrt_weights[index] = sqrt(weights[index]);
122 }
123
124 // prepare result and compute metadata
126
127 NumberType valid_length = observation_points.back() - observation_points.front();
128 NumberType segment_size = valid_length / NumberType(segments_count);
129 result.start = observation_points.front();
130 result.segment_size = segment_size;
131 result.endpoints_level_of_freedom = endpoints_level_of_freedom;
132
133 // prepare observed data
134 // Eigen defaults to column major memory layout.
135 Eigen::MatrixXf data_points(Dimension, observations.size());
136 for (size_t index = 0; index < observations.size(); ++index) {
137 data_points.col(index) = observations[index] * sqrt_weights[index];
138 }
139 // parameters count is always increased by one to make the parametric space of the curve symmetric.
140 // without this fix, the end of the curve is less flexible than the beginning
141 size_t parameters_count = segments_count + 1 + 2 * endpoints_level_of_freedom;
142 //Create weight matrix T for each point and each segment;
143 Eigen::MatrixXf T(observation_points.size(), parameters_count);
144 T.setZero();
145 //Fill the weight matrix
146 for (size_t i = 0; i < observation_points.size(); ++i) {
147 NumberType observation_point = observation_points[i];
148 //find corresponding segment index; expects kernels to be centered
149 int middle_right_segment_index = floor((observation_point - result.start) / result.segment_size);
150 //find index of first segment that is affected by the point i; this can be deduced from kernel_span
151 int start_segment_idx = middle_right_segment_index - int(Kernel::kernel_span / 2) + 1;
152 for (int segment_index = start_segment_idx; segment_index < int(start_segment_idx + Kernel::kernel_span);
153 segment_index++) {
154 NumberType segment_start = result.start + segment_index * result.segment_size;
155 NumberType normalized_segment_distance = (segment_start - observation_point) / result.segment_size;
156
157 int parameter_index = segment_index + endpoints_level_of_freedom;
158 parameter_index = std::clamp(parameter_index, 0, int(parameters_count) - 1);
159 T(i, parameter_index) += Kernel::kernel(normalized_segment_distance) * sqrt_weights[i];
160 }
161 }
162
163#ifdef LSQR_DEBUG
164 std::cout << "weight matrix: " << std::endl;
165 for (int obs = 0; obs < observation_points.size(); ++obs) {
166 std::cout << std::endl;
167 for (int segment = 0; segment < parameters_count; ++segment) {
168 std::cout << T(obs, segment) << " ";
169 }
170 }
171 std::cout << std::endl;
172#endif
173
174 // Solve for linear least square fit
175 result.coefficients.resize(Dimension, parameters_count);
176 const auto QR = T.fullPivHouseholderQr();
177 for (size_t dim = 0; dim < Dimension; ++dim) {
178 result.coefficients.row(dim) = QR.solve(data_points.row(dim).transpose());
179 }
180
181 return result;
182}
void segment(CGALMesh &src, std::vector< CGALMesh > &dst, double smoothing_alpha=0.5, int segment_number=5)
Definition MeshBoolean.cpp:480
size_t endpoints_level_of_freedom
Definition Curves.hpp:74
Eigen::MatrixXf coefficients
Definition Curves.hpp:71
NumberType start
Definition Curves.hpp:72
NumberType segment_size
Definition Curves.hpp:73

References Slic3r::Geometry::PiecewiseFittedCurve< Dimension, NumberType, KernelType >::coefficients, Slic3r::Geometry::PiecewiseFittedCurve< Dimension, NumberType, KernelType >::endpoints_level_of_freedom, Slic3r::Geometry::PiecewiseFittedCurve< Dimension, NumberType, KernelType >::segment_size, and Slic3r::Geometry::PiecewiseFittedCurve< Dimension, NumberType, KernelType >::start.

Referenced by fit_catmul_rom_spline(), fit_cubic_bspline(), and fit_linear_spline().

Here is the caller graph for this function:

◆ fit_linear_spline()

template<int Dimension, typename NumberType>
PiecewiseFittedCurve< Dimension, NumberType, LinearKernel< NumberType > > Slic3r::Geometry::fit_linear_spline ( const std::vector< Vec< Dimension, NumberType > > & observations,
std::vector< NumberType > observation_points,
std::vector< NumberType > weights,
size_t segments_count,
size_t endpoints_level_of_freedom = 0 )
192 {
193 return fit_curve<LinearKernel<NumberType>>(observations, observation_points, weights, segments_count,
194 endpoints_level_of_freedom);
195}

References fit_curve().

Here is the call graph for this function:

◆ fit_polynomial()

template<int Dimension, typename NumberType>
PolynomialCurve< Dimension, NumberType > Slic3r::Geometry::fit_polynomial ( const std::vector< Vec< Dimension, NumberType > > & observations,
const std::vector< NumberType > & observation_points,
const std::vector< NumberType > & weights,
size_t order )
38 {
39 // check to make sure inputs are correct
40 size_t cols = order + 1;
41 assert(observation_points.size() >= cols);
42 assert(observation_points.size() == weights.size());
43 assert(observations.size() == weights.size());
44
45 Eigen::MatrixXf data_points(Dimension, observations.size());
46 Eigen::MatrixXf T(observations.size(), cols);
47 for (size_t i = 0; i < weights.size(); ++i) {
48 auto squared_weight = sqrt(weights[i]);
49 data_points.col(i) = observations[i] * squared_weight;
50 // Populate the matrix
51 auto x = squared_weight;
52 auto c = observation_points[i];
53 for (size_t j = 0; j < cols; ++j, x *= c)
54 T(i, j) = x;
55 }
56
57 const auto QR = T.householderQr();
58 Eigen::MatrixXf coefficients(Dimension, cols);
59 // Solve for linear least square fit
60 for (size_t dim = 0; dim < Dimension; ++dim) {
61 coefficients.row(dim) = QR.solve(data_points.row(dim).transpose());
62 }
63
64 return {std::move(coefficients)};
65}

◆ foot_pt() [1/2]

Vec2d Slic3r::Geometry::foot_pt ( const Line & iline,
const Point & ipt )
inline
195{
196 return foot_pt<Vec2d>(iline.a.cast<double>(), (iline.b - iline.a).cast<double>(), ipt.cast<double>());
197}
Point b
Definition Line.hpp:199
Point a
Definition Line.hpp:198
T foot_pt(const T &line_pt, const T &line_dir, const T &pt)
Definition Geometry.hpp:186

References Slic3r::Line::a, Slic3r::Line::b, and foot_pt().

Here is the call graph for this function:

◆ foot_pt() [2/2]

template<typename T>
T Slic3r::Geometry::foot_pt ( const T & line_pt,
const T & line_dir,
const T & pt )
inline
187{
188 T v = pt - line_pt;
189 auto l2 = line_dir.squaredNorm();
190 auto t = (l2 == 0) ? 0 : v.dot(line_dir) / l2;
191 return line_pt + line_dir * t;
192}
T l2(const boost::geometry::model::d2::point_xy< T > &v)
Definition ExtrusionSimulator.cpp:177
T dot(const boost::geometry::model::d2::point_xy< T > &v1, const boost::geometry::model::d2::point_xy< T > &v2)
Definition ExtrusionSimulator.cpp:154

References Slic3r::l2().

Referenced by Slic3r::Voronoi::detail::dist_to_site(), Slic3r::Voronoi::edge_offset_contour_intersections(), Slic3r::foot_pt(), Slic3r::foot_pt(), foot_pt(), Slic3r::ExtrusionLoop::get_closest_path_and_point(), Slic3r::Voronoi::detail::line_point_equal_distance_points(), Slic3r::Voronoi::detail::point_segment_dr_dl_thresholds(), Slic3r::Voronoi::detail::point_segment_skeleton_thresholds(), Slic3r::TreeSupport3D::polyline_sample_next_point_at_distance(), ray_point_distance(), ray_point_distance(), ray_point_distance_squared(), and ray_point_distance_squared().

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

◆ generate_transform()

Transformation Slic3r::Geometry::generate_transform ( const Vec3d & x_dir,
const Vec3d & y_dir,
const Vec3d & z_dir,
const Vec3d & origin )
853 {
854 Matrix3d m;
855 m.col(0) = x_dir.normalized();
856 m.col(1) = y_dir.normalized();
857 m.col(2) = z_dir.normalized();
858 Transform3d mm(m);
859 Transformation tran(mm);
860 tran.set_offset(origin);
861 return tran;
862}
Definition Geometry.hpp:419

References Slic3r::Geometry::Transformation::set_offset().

Here is the call graph for this function:

◆ get_parabolic_segment()

template<typename SegmentIterator>
boost::polygon::enable_if< typenameboost::polygon::gtl_if< typenameboost::polygon::is_segment_concept< typenameboost::polygon::geometry_concept< typenamestd::iterator_traits< SegmentIterator >::value_type >::type >::type >::type, ParabolicSegment >::type Slic3r::Geometry::get_parabolic_segment ( const VD::edge_type & edge,
const SegmentIterator segment_begin,
const SegmentIterator segment_end )
inlinestatic
213{
214 using Segment = typename std::iterator_traits<SegmentIterator>::value_type;
215 assert(edge.is_curved());
216
217 const VD::cell_type *left_cell = edge.cell();
218 const VD::cell_type *right_cell = edge.twin()->cell();
219
220 const Point focus_pt = VoronoiUtils::get_source_point(*(left_cell->contains_point() ? left_cell : right_cell), segment_begin, segment_end);
221 const Segment &directrix = VoronoiUtils::get_source_segment(*(left_cell->contains_point() ? right_cell : left_cell), segment_begin, segment_end);
222 CGAL::Orientation focus_side = CGAL::opposite(CGAL::orientation(to_cgal_point(edge.vertex0()), to_cgal_point(edge.vertex1()), to_cgal_point(focus_pt)));
223
224 assert(focus_side == CGAL::Orientation::LEFT_TURN || focus_side == CGAL::Orientation::RIGHT_TURN);
225
226 const Point directrix_from = boost::polygon::segment_traits<Segment>::get(directrix, boost::polygon::LOW);
227 const Point directrix_to = boost::polygon::segment_traits<Segment>::get(directrix, boost::polygon::HIGH);
228 return {focus_pt, Line(directrix_from, directrix_to), make_linef(edge), focus_side};
229}
voronoi_diagram_type::cell_type cell_type
Definition Voronoi.hpp:42
static boost::polygon::enable_if< typenameboost::polygon::gtl_if< typenameboost::polygon::is_segment_concept< typenameboost::polygon::geometry_concept< typenamestd::iterator_traits< SegmentIterator >::value_type >::type >::type >::type, typenamestd::iterator_traits< SegmentIterator >::reference >::type get_source_segment(const VoronoiDiagram::cell_type &cell, SegmentIterator segment_begin, SegmentIterator segment_end)
Definition VoronoiUtils.cpp:53
static boost::polygon::enable_if< typenameboost::polygon::gtl_if< typenameboost::polygon::is_segment_concept< typenameboost::polygon::geometry_concept< typenamestd::iterator_traits< SegmentIterator >::value_type >::type >::type >::type, typenameboost::polygon::segment_point_type< typenamestd::iterator_traits< SegmentIterator >::value_type >::type >::type get_source_point(const VoronoiDiagram::cell_type &cell, SegmentIterator segment_begin, SegmentIterator segment_end)
Definition VoronoiUtils.cpp:69
Definition Line.hpp:156
CGAL_Point to_cgal_point(const VD::vertex_type *pt)
Definition VoronoiUtilsCgal.cpp:150
Linef make_linef(const VD::edge_type &edge)
Definition VoronoiUtilsCgal.cpp:154
Definition WipeTower.cpp:389

References Slic3r::Geometry::VoronoiUtils::get_source_point(), Slic3r::Geometry::VoronoiUtils::get_source_segment(), make_linef(), and to_cgal_point().

Referenced by orientation_of_two_edges().

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

◆ inside_convex_polygon()

bool Slic3r::Geometry::inside_convex_polygon ( const std::pair< std::vector< Vec2d >, std::vector< Vec2d > > & top_bottom_decomposition,
const Vec2d & pt )
393{
394 auto it_bottom = std::lower_bound(top_bottom_decomposition.first.begin(), top_bottom_decomposition.first.end(), pt, [](const auto &l, const auto &r){ return l.x() < r.x(); });
395 auto it_top = std::lower_bound(top_bottom_decomposition.second.begin(), top_bottom_decomposition.second.end(), pt, [](const auto &l, const auto &r){ return l.x() < r.x(); });
396 if (it_bottom == top_bottom_decomposition.first.end()) {
397 // Above max x.
398 assert(it_top == top_bottom_decomposition.second.end());
399 return false;
400 }
401 if (it_bottom == top_bottom_decomposition.first.begin()) {
402 // Below or at min x.
403 if (pt.x() < it_bottom->x()) {
404 // Below min x.
405 assert(pt.x() < it_top->x());
406 return false;
407 }
408 // At min x.
409 assert(pt.x() == it_bottom->x());
410 assert(pt.x() == it_top->x());
411 assert(it_bottom->y() <= pt.y() && pt.y() <= it_top->y());
412 return pt.y() >= it_bottom->y() && pt.y() <= it_top->y();
413 }
414
415 // Trapezoid or a triangle.
416 assert(it_bottom != top_bottom_decomposition.first .begin() && it_bottom != top_bottom_decomposition.first .end());
417 assert(it_top != top_bottom_decomposition.second.begin() && it_top != top_bottom_decomposition.second.end());
418 assert(pt.x() <= it_bottom->x());
419 assert(pt.x() <= it_top->x());
420 auto it_top_prev = it_top - 1;
421 auto it_bottom_prev = it_bottom - 1;
422 assert(pt.x() >= it_top_prev->x());
423 assert(pt.x() >= it_bottom_prev->x());
424 double det = cross2(*it_bottom - *it_bottom_prev, pt - *it_bottom_prev);
425 if (det < 0)
426 return false;
427 det = cross2(*it_top - *it_top_prev, pt - *it_top_prev);
428 return det <= 0;
429}
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 Slic3r::cross2().

Referenced by Slic3r::BuildVolume::object_state().

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

◆ is_ccw()

bool Slic3r::Geometry::is_ccw ( const Polygon & poly)
inlinestatic
67{
68 // The polygon shall be at least a triangle.
69 assert(poly.points.size() >= 3);
70 if (poly.points.size() < 3)
71 return true;
72
73 // 1) Find the lowest lexicographical point.
74 unsigned int imin = 0;
75 for (unsigned int i = 1; i < poly.points.size(); ++ i) {
76 const Point &pmin = poly.points[imin];
77 const Point &p = poly.points[i];
78 if (p(0) < pmin(0) || (p(0) == pmin(0) && p(1) < pmin(1)))
79 imin = i;
80 }
81
82 // 2) Detect the orientation of the corner imin.
83 size_t iPrev = ((imin == 0) ? poly.points.size() : imin) - 1;
84 size_t iNext = ((imin + 1 == poly.points.size()) ? 0 : imin + 1);
85 Orientation o = orient(poly.points[iPrev], poly.points[imin], poly.points[iNext]);
86 // The lowest bottom point must not be collinear if the polygon does not contain duplicate points
87 // or overlapping segments.
88 assert(o != ORIENTATION_COLINEAR);
89 return o == ORIENTATION_CCW;
90}
Orientation
Definition Geometry.hpp:31

References orient(), ORIENTATION_CCW, and ORIENTATION_COLINEAR.

Referenced by Slic3r::ExPolygonWithOffset::ExPolygonWithOffset(), Slic3r::GCodeG2G3Formatter::GCodeG2G3Formatter(), Slic3r::Geometry::ArcWelder::arc_center(), Slic3r::ArcSegment::calc_arc_length(), Slic3r::ArcSegment::calc_arc_radian(), Slic3r::Circle::calc_tangential_vector(), Slic3r::GCodeWriter::extrude_arc_as_polyline(), Slic3r::GCodeWriter::extrude_arc_to_xy(), Slic3r::GCodeWriter::extrude_arc_to_xy(), Slic3r::GCode::extrude_loop(), Slic3r::CoolingBuffer::parse_layer_gcode(), Slic3r::rounding_polygon(), Slic3r::WipeTower::rounding_polygon(), Slic3r::rounding_rectangle(), Slic3r::wipe_offset_direction(), and Slic3r::wipe_on_loops_destination().

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

◆ is_equal()

bool Slic3r::Geometry::is_equal ( const VD::vertex_type & vertex_first,
const VD::vertex_type & vertex_second )
inline
161{ return vertex_first.x() == vertex_second.x() && vertex_first.y() == vertex_second.y(); }

Referenced by check_if_three_edges_are_ccw(), Slic3r::cut_mesh(), Slic3r::is_equal(), orientation_of_two_edges(), Slic3r::slice_facet_for_cut_mesh(), and Slic3r::triangulate_slice().

Here is the caller graph for this function:

◆ is_point_inside_polygon_corner()

bool Slic3r::Geometry::is_point_inside_polygon_corner ( const Point & a,
const Point & b,
const Point & c,
const Point & query_point )

Checks if a given point is inside a corner of a polygon.

The corner of a polygon is defined by three points A, B, C in counterclockwise order.

Adapted from CuraEngine LinearAlg2D::isInsideCorner by Tim Kuipers @BagelOrb and @Ghostkeeper.

Parameters
aThe first point of the corner.
bThe second point of the corner (the common vertex of the two edges forming the corner).
cThe third point of the corner.
query_pointThe point to be checked if is inside the corner.
Returns
True if the query point is inside the corner, false otherwise.
864 {
865 // Cast all input points into int64_t to prevent overflows when points are close to max values of coord_t.
866 const Vec2i64 a_i64 = a.cast<int64_t>();
867 const Vec2i64 b_i64 = b.cast<int64_t>();
868 const Vec2i64 c_i64 = c.cast<int64_t>();
869 const Vec2i64 query_point_i64 = query_point.cast<int64_t>();
870
871 // Shift all points to have a base in vertex B.
872 // Then construct normalized vectors to ensure that we will work with vectors with endpoints on the unit circle.
873 const Vec2d ba = (a_i64 - b_i64).cast<double>().normalized();
874 const Vec2d bc = (c_i64 - b_i64).cast<double>().normalized();
875 const Vec2d bq = (query_point_i64 - b_i64).cast<double>().normalized();
876
877 // Points A and C has to be different.
878 assert(ba != bc);
879
880 // Construct a normal for the vector BQ that points to the left side of the vector BQ.
881 const Vec2d bq_left_normal = perp(bq);
882
883 const double proj_a_on_bq_normal = ba.dot(bq_left_normal); // Project point A on the normal of BQ.
884 const double proj_c_on_bq_normal = bc.dot(bq_left_normal); // Project point C on the normal of BQ.
885 if ((proj_a_on_bq_normal > 0. && proj_c_on_bq_normal <= 0.) || (proj_a_on_bq_normal <= 0. && proj_c_on_bq_normal > 0.)) {
886 // Q is between points A and C or lies on one of those vectors (BA or BC).
887
888 // Based on the CCW order of polygons (contours) and order of corner ABC,
889 // when this condition is met, the query point is inside the corner.
890 return proj_a_on_bq_normal > 0.;
891 } else {
892 // Q isn't between points A and C, but still it can be inside the corner.
893
894 const double proj_a_on_bq = ba.dot(bq); // Project point A on BQ.
895 const double proj_c_on_bq = bc.dot(bq); // Project point C on BQ.
896
897 // The value of proj_a_on_bq_normal is the same when we project the vector BA on the normal of BQ.
898 // So we can say that the Q is on the right side of the vector BA when proj_a_on_bq_normal > 0, and
899 // that the Q is on the left side of the vector BA proj_a_on_bq_normal < 0.
900 // Also, the Q is on the right side of the bisector of oriented angle ABC when proj_c_on_bq < proj_a_on_bq, and
901 // the Q is on the left side of the bisector of oriented angle ABC when proj_c_on_bq > proj_a_on_bq.
902
903 // So the Q is inside the corner when one of the following conditions is met:
904 // * The Q is on the right side of the vector BA, and the Q is on the right side of the bisector of the oriented angle ABC.
905 // * The Q is on the left side of the vector BA, and the Q is on the left side of the bisector of the oriented angle ABC.
906 return (proj_a_on_bq_normal > 0. && proj_c_on_bq < proj_a_on_bq) || (proj_a_on_bq_normal <= 0. && proj_c_on_bq >= proj_a_on_bq);
907 }
908}
Eigen::Matrix< typename Derived::Scalar, 2, 1, Eigen::DontAlign > perp(const Eigen::MatrixBase< Derived > &v)
Definition Point.hpp:130
Eigen::Matrix< int64_t, 2, 1, Eigen::DontAlign > Vec2i64
Definition Point.hpp:58
auto cast(const BoundingBoxBase< Tin > &b)
Definition BoundingBox.hpp:299

References Slic3r::cast(), and Slic3r::perp().

Referenced by Slic3r::Geometry::VoronoiUtils::compute_point_cell_range().

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

◆ is_rotation_ninety_degrees() [1/2]

bool Slic3r::Geometry::is_rotation_ninety_degrees ( const Vec3d & rotation)
inline
555{
556 return is_rotation_ninety_degrees(rotation.x()) && is_rotation_ninety_degrees(rotation.y()) && is_rotation_ninety_degrees(rotation.z());
557}
bool is_rotation_ninety_degrees(double a)
Definition Geometry.hpp:545

References is_rotation_ninety_degrees().

Here is the call graph for this function:

◆ is_rotation_ninety_degrees() [2/2]

bool Slic3r::Geometry::is_rotation_ninety_degrees ( double a)
inline
546{
547 a = fmod(std::abs(a), 0.5 * PI);
548 if (a > 0.25 * PI)
549 a = 0.5 * PI - a;
550 return a < 0.001;
551}

References PI.

Referenced by Slic3r::ModelObject::bake_xy_rotation_into_meshes(), is_rotation_ninety_degrees(), and Slic3r::Geometry::Transformation::volume_to_bed_transformation().

Here is the caller graph for this function:

◆ liang_barsky_line_clipping() [1/2]

template<typename T>
bool Slic3r::Geometry::liang_barsky_line_clipping ( const Eigen::Matrix< T, 2, 1, Eigen::DontAlign > & x0src,
const Eigen::Matrix< T, 2, 1, Eigen::DontAlign > & x1src,
const BoundingBoxBase< Eigen::Matrix< T, 2, 1, Eigen::DontAlign > > & bbox,
Eigen::Matrix< T, 2, 1, Eigen::DontAlign > & x0clip,
Eigen::Matrix< T, 2, 1, Eigen::DontAlign > & x1clip )
301{
302 x0clip = x0src;
303 x1clip = x1src;
304 return liang_barsky_line_clipping(x0clip, x1clip, bbox);
305}
bool liang_barsky_line_clipping(Eigen::Matrix< T, 2, 1, Eigen::DontAlign > &x0, Eigen::Matrix< T, 2, 1, Eigen::DontAlign > &x1, const BoundingBoxBase< Eigen::Matrix< T, 2, 1, Eigen::DontAlign > > &bbox)
Definition Geometry.hpp:272

References liang_barsky_line_clipping().

Here is the call graph for this function:

◆ liang_barsky_line_clipping() [2/2]

template<typename T>
bool Slic3r::Geometry::liang_barsky_line_clipping ( Eigen::Matrix< T, 2, 1, Eigen::DontAlign > & x0,
Eigen::Matrix< T, 2, 1, Eigen::DontAlign > & x1,
const BoundingBoxBase< Eigen::Matrix< T, 2, 1, Eigen::DontAlign > > & bbox )
inline
278{
279 Eigen::Matrix<T, 2, 1, Eigen::DontAlign> v = x1 - x0;
280 std::pair<double, double> interval;
281 if (liang_barsky_line_clipping_interval(x0, v, bbox, interval)) {
282 // Clipped successfully.
283 x1 = x0 + interval.second * v;
284 x0 += interval.first * v;
285 return true;
286 }
287 return false;
288}
bool liang_barsky_line_clipping_interval(const Eigen::Matrix< T, 2, 1, Eigen::DontAlign > &x0, const Eigen::Matrix< T, 2, 1, Eigen::DontAlign > &v, const BoundingBoxBase< Eigen::Matrix< T, 2, 1, Eigen::DontAlign > > &bbox, std::pair< double, double > &out_interval)
Definition Geometry.hpp:221

References liang_barsky_line_clipping_interval().

Referenced by Slic3r::Line::clip_with_bbox(), liang_barsky_line_clipping(), Slic3r::FillAdaptive::multiline_paths(), and Slic3r::Voronoi::offset().

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

◆ liang_barsky_line_clipping_interval()

template<typename T>
bool Slic3r::Geometry::liang_barsky_line_clipping_interval ( const Eigen::Matrix< T, 2, 1, Eigen::DontAlign > & x0,
const Eigen::Matrix< T, 2, 1, Eigen::DontAlign > & v,
const BoundingBoxBase< Eigen::Matrix< T, 2, 1, Eigen::DontAlign > > & bbox,
std::pair< double, double > & out_interval )
inline
228{
229 double t0 = 0.0;
230 double t1 = 1.0;
231 // Traverse through left, right, bottom, top edges.
232 auto clip_side = [&t0, &t1](double p, double q) -> bool {
233 if (p == 0) {
234 if (q < 0)
235 // Line parallel to the bounding box edge is fully outside of the bounding box.
236 return false;
237 // else don't clip
238 } else {
239 double r = q / p;
240 if (p < 0) {
241 if (r > t1)
242 // Fully clipped.
243 return false;
244 if (r > t0)
245 // Partially clipped.
246 t0 = r;
247 } else {
248 assert(p > 0);
249 if (r < t0)
250 // Fully clipped.
251 return false;
252 if (r < t1)
253 // Partially clipped.
254 t1 = r;
255 }
256 }
257 return true;
258 };
259
260 if (clip_side(- v.x(), - bbox.min.x() + x0.x()) &&
261 clip_side( v.x(), bbox.max.x() - x0.x()) &&
262 clip_side(- v.y(), - bbox.min.y() + x0.y()) &&
263 clip_side( v.y(), bbox.max.y() - x0.y())) {
264 out_interval.first = t0;
265 out_interval.second = t1;
266 return true;
267 }
268 return false;
269}
PointType max
Definition BoundingBox.hpp:21

Referenced by liang_barsky_line_clipping(), and Slic3r::line_rounded_thick_segment_collision().

Here is the caller graph for this function:

◆ linint()

double Slic3r::Geometry::linint ( double value,
double oldmin,
double oldmax,
double newmin,
double newmax )
85{
86 return (value - oldmin) * (newmax - newmin) / (oldmax - oldmin) + newmin;
87}

Referenced by arrange().

Here is the caller graph for this function:

◆ make_linef()

Linef Slic3r::Geometry::make_linef ( const VD::edge_type & edge)
inline
155{
156 const VD::vertex_type *v0 = edge.vertex0();
157 const VD::vertex_type *v1 = edge.vertex1();
158 return {Vec2d(v0->x(), v0->y()), Vec2d(v1->x(), v1->y())};
159}
voronoi_diagram_type::vertex_type vertex_type
Definition Voronoi.hpp:40

Referenced by get_parabolic_segment().

Here is the caller graph for this function:

◆ mat_around_a_point_rotate()

Transformation Slic3r::Geometry::mat_around_a_point_rotate ( const Transformation & InMat,
const Vec3d & pt,
const Vec3d & axis,
float rotate_theta_radian )
827{
828 auto xyz = InMat.get_offset();
829 Transformation left;
830 left.set_offset(-xyz); // at world origin
831 auto curMat = left * InMat;
832
833 auto qua = Eigen::Quaterniond(Eigen::AngleAxisd(rotate_theta_radian, axis));
834 qua.normalize();
835 Transform3d cur_matrix;
836 Transformation rotateMat4;
837 rotateMat4.set_matrix(cur_matrix.fromPositionOrientationScale(Vec3d(0., 0., 0.), qua, Vec3d(1., 1., 1.)));
838
839 curMat = rotateMat4 * curMat; // along_fix_axis
840 // rotate mat4 along fix pt
841 Transformation temp_world;
842 auto qua_world = Eigen::Quaterniond(Eigen::AngleAxisd(0, axis));
843 qua_world.normalize();
844 Transform3d cur_matrix_world;
845 temp_world.set_matrix(cur_matrix_world.fromPositionOrientationScale(pt, qua_world, Vec3d(1., 1., 1.)));
846 Vec3d temp_xyz = temp_world.get_matrix().inverse() * xyz;
847 Vec3d new_pos = temp_world.get_matrix() * (rotateMat4.get_matrix() * temp_xyz);
848 curMat.set_offset(new_pos);
849
850 return curMat;
851}
void set_matrix(const Transform3d &transform)
Definition Geometry.hpp:484
Vec3d get_offset() const
Definition Geometry.hpp:426
const Transform3d & get_matrix() const
Definition Geometry.hpp:477

References Slic3r::Geometry::Transformation::get_matrix(), Slic3r::Geometry::Transformation::get_offset(), and Slic3r::Geometry::Transformation::set_matrix().

Referenced by Slic3r::GUI::GLGizmoMeasure::set_to_around_center_of_faces(), and Slic3r::GUI::GLGizmoMeasure::set_to_reverse_rotation().

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

◆ measure_edge_thickness()

template<typename VD, typename SEGMENTS>
std::pair< typename VD::coord_type, typename VD::coord_type > Slic3r::Geometry::measure_edge_thickness ( const VD & vd,
const typename VD::edge_type & edge,
const SEGMENTS & segments )
inline
409{
410 typedef typename VD::coord_type T;
411 const typename VD::point_type pa(edge.vertex0()->x(), edge.vertex0()->y());
412 const typename VD::point_type pb(edge.vertex1()->x(), edge.vertex1()->y());
413 const typename VD::cell_type &cell1 = *edge.cell();
414 const typename VD::cell_type &cell2 = *edge.twin()->cell();
415 if (cell1.contains_segment()) {
416 if (cell2.contains_segment()) {
417 // Both cells contain a linear segment, the left / right cells are symmetric.
418 // Project pa, pb to the left segment.
419 const typename VD::segment_type segment1 = segments[cell1.source_index()];
420 const typename VD::point_type p1a = project_point_to_segment(segment1, pa);
421 const typename VD::point_type p1b = project_point_to_segment(segment1, pb);
422 return std::pair<T, T>(T(2.)*dist(pa, p1a), T(2.)*dist(pb, p1b));
423 } else {
424 // 1st cell contains a linear segment, 2nd cell contains a point.
425 // The medial axis between the cells is a parabolic arc.
426 // Project pa, pb to the left segment.
427 const typename VD::point_type p2 = retrieve_cell_point<VD>(cell2, segments);
428 return std::pair<T, T>(T(2.)*dist(pa, p2), T(2.)*dist(pb, p2));
429 }
430 } else if (cell2.contains_segment()) {
431 // 1st cell contains a point, 2nd cell contains a linear segment.
432 // The medial axis between the cells is a parabolic arc.
433 const typename VD::point_type p1 = retrieve_cell_point<VD>(cell1, segments);
434 return std::pair<T, T>(T(2.)*dist(pa, p1), T(2.)*dist(pb, p1));
435 } else {
436 // Both cells contain a point. The left / right regions are triangular and symmetric.
437 const typename VD::point_type p1 = retrieve_cell_point<VD>(cell1, segments);
438 return std::pair<T, T>(T(2.)*dist(pa, p1), T(2.)*dist(pb, p1));
439 }
440}
boost::polygon::point_data< voronoi_diagram_type::coordinate_type > point_type
Definition Voronoi.hpp:35
double coord_type
Definition Voronoi.hpp:33
boost::polygon::segment_data< voronoi_diagram_type::coordinate_type > segment_type
Definition Voronoi.hpp:36
point_type project_point_to_segment(segment_type &seg, point_type &px)
Definition Geometry.cpp:307
const VD::point_type retrieve_cell_point(const typename VD::cell_type &cell, const SEGMENTS &segments)
Definition MedialAxis.cpp:401

References dist(), project_point_to_segment(), and retrieve_cell_point().

Here is the call graph for this function:

◆ orient()

Orientation Slic3r::Geometry::orient ( const Point & a,
const Point & b,
const Point & c )
inlinestatic
44 {
45 //static_assert(sizeof(coord_t) * 2 == sizeof(int64_t), "orient works with 32 bit coordinates");
46 // BOOST_STATIC_ASSERT(sizeof(coord_t) == sizeof(int64_t));
47 if (a.x() <= 0xffffffff && b.x() <= 0xffffffff && c.x() <= 0xffffffff &&
48 a.y() <= 0xffffffff && b.y() <= 0xffffffff && c.y() <= 0xffffffff) {
49 int64_t u = int64_t(b(0)) * int64_t(c(1)) - int64_t(b(1)) * int64_t(c(0));
50 int64_t v = int64_t(a(0)) * int64_t(c(1)) - int64_t(a(1)) * int64_t(c(0));
51 int64_t w = int64_t(a(0)) * int64_t(b(1)) - int64_t(a(1)) * int64_t(b(0));
52 int64_t d = u - v + w;
53 return (d > 0) ? ORIENTATION_CCW : ((d == 0) ? ORIENTATION_COLINEAR : ORIENTATION_CW);
54 } else {
55 double u = double(b(0)) * double(c(1)) - double(b(1)) * double(c(0));
56 double v = double(a(0)) * double(c(1)) - double(a(1)) * double(c(0));
57 double w = double(a(0)) * double(b(1)) - double(a(1)) * double(b(0));
58 double d = u - v + w;
59 return (d > 0) ? ORIENTATION_CCW : ((d == 0) ? ORIENTATION_COLINEAR : ORIENTATION_CW);
60 }
61}

References ORIENTATION_CCW, ORIENTATION_COLINEAR, and ORIENTATION_CW.

Referenced by convex_hull(), convex_hull(), Slic3r::GUI::ObjectGrid::DrawColLabel(), Slic3r::GUI::DesignSketchTool::drop_orientation_constraints(), is_ccw(), Slic3r::GeometryEngine::tessellate(), and Slic3r::SketchEngine::tessellate().

Here is the caller graph for this function:

◆ orientation_of_two_edges()

template<typename SegmentIterator>
boost::polygon::enable_if< typenameboost::polygon::gtl_if< typenameboost::polygon::is_segment_concept< typenameboost::polygon::geometry_concept< typenamestd::iterator_traits< SegmentIterator >::value_type >::type >::type >::type, CGAL::Orientation >::type Slic3r::Geometry::orientation_of_two_edges ( const VD::edge_type & edge_a,
const VD::edge_type & edge_b,
const SegmentIterator segment_begin,
const SegmentIterator segment_end )
inlinestatic
237{
238 assert(is_equal(*edge_a.vertex0(), *edge_b.vertex0()));
239 CGAL::Orientation orientation;
240 if (edge_a.is_linear() && edge_b.is_linear()) {
241 orientation = CGAL::orientation(to_cgal_point(edge_a.vertex0()), to_cgal_point(edge_a.vertex1()), to_cgal_point(edge_b.vertex1()));
242 } else if (edge_a.is_curved() && edge_b.is_curved()) {
243 const ParabolicSegment parabolic_a = get_parabolic_segment(edge_a, segment_begin, segment_end);
244 const ParabolicSegment parabolic_b = get_parabolic_segment(edge_b, segment_begin, segment_end);
246 to_cgal_point(parabolic_a.focus),
247 to_cgal_point(parabolic_a.directrix.a),
248 to_cgal_point(parabolic_a.directrix.b),
249 parabolic_a.is_focus_on_left,
250 to_cgal_point(parabolic_b.focus),
251 to_cgal_point(parabolic_b.directrix.a),
252 to_cgal_point(parabolic_b.directrix.b),
253 parabolic_b.is_focus_on_left);
254 return orientation;
255 } else {
256 assert(edge_a.is_curved() != edge_b.is_curved());
257
258 const VD::edge_type &linear_edge = edge_a.is_curved() ? edge_b : edge_a;
259 const VD::edge_type &parabolic_edge = edge_a.is_curved() ? edge_a : edge_b;
260 const ParabolicSegment parabolic = get_parabolic_segment(parabolic_edge, segment_begin, segment_end);
261 orientation = ParabolicTangentToSegmentOrientation{}(to_cgal_point(parabolic.segment.a), to_cgal_point(linear_edge.vertex1()),
262 to_cgal_point(parabolic.focus),
263 to_cgal_point(parabolic.directrix.a),
264 to_cgal_point(parabolic.directrix.b),
265 parabolic.is_focus_on_left);
266
267 if (edge_b.is_curved())
268 orientation = CGAL::opposite(orientation);
269 }
270
271 return orientation;
272}
voronoi_diagram_type::edge_type edge_type
Definition Voronoi.hpp:41
Vec2d a
Definition Line.hpp:264
impl::ParabolicTangentToSegmentOrientationPredicateFiltered ParabolicTangentToSegmentOrientation
Definition VoronoiUtilsCgal.cpp:146
const Line directrix
Definition VoronoiUtilsCgal.cpp:200
const Point focus
Definition VoronoiUtilsCgal.cpp:199
impl::ParabolicTangentToParabolicTangentOrientationPredicateFiltered ParabolicTangentToParabolicTangentOrientation
Definition VoronoiUtilsCgal.cpp:147
const Linef segment
Definition VoronoiUtilsCgal.cpp:202
const CGAL::Orientation is_focus_on_left
Definition VoronoiUtilsCgal.cpp:204
static boost::polygon::enable_if< typenameboost::polygon::gtl_if< typenameboost::polygon::is_segment_concept< typenameboost::polygon::geometry_concept< typenamestd::iterator_traits< SegmentIterator >::value_type >::type >::type >::type, ParabolicSegment >::type get_parabolic_segment(const VD::edge_type &edge, const SegmentIterator segment_begin, const SegmentIterator segment_end)
Definition VoronoiUtilsCgal.cpp:212
Definition VoronoiUtilsCgal.cpp:198

References Slic3r::Line::a, Slic3r::Linef::a, Slic3r::Line::b, Slic3r::Geometry::ParabolicSegment::directrix, Slic3r::Geometry::ParabolicSegment::focus, get_parabolic_segment(), is_equal(), Slic3r::Geometry::ParabolicSegment::is_focus_on_left, Slic3r::Geometry::ParabolicSegment::segment, and to_cgal_point().

Referenced by check_if_three_edges_are_ccw().

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

◆ project_point_to_segment()

template<typename segment_type, typename point_type>
point_type Slic3r::Geometry::project_point_to_segment ( segment_type & seg,
point_type & px )
inline
308{
309 typedef typename point_type::coordinate_type T;
310 const point_type &p0 = low(seg);
311 const point_type &p1 = high(seg);
312 const point_type dir(p1(0)-p0(0), p1(1)-p0(1));
313 const point_type dproj(px(0)-p0(0), px(1)-p0(1));
314 const T t = (dir(0)*dproj(0) + dir(1)*dproj(1)) / (dir(0)*dir(0) + dir(1)*dir(1));
315 assert(t >= T(-1e-6) && t <= T(1. + 1e-6));
316 return point_type(p0(0) + t*dir(0), p0(1) + t*dir(1));
317}

Referenced by measure_edge_thickness().

Here is the caller graph for this function:

◆ rad2deg()

template<typename T>
T Slic3r::Geometry::rad2deg ( T angle)
310{ return T(180.0) * angle / T(PI); }

References Slic3r::angle(), and PI.

Referenced by Slic3r::GUI::GLGizmoScale3D::calc_ratio(), Slic3r::BridgeDetector::coverage(), Slic3r::BridgeDetector::detect_angle(), Slic3r::GUI::Camera::get_fov(), Slic3r::GUI::GLGizmoCut3D::get_tooltip(), Slic3r::GUI::GLGizmoRotate::get_tooltip(), rad2deg_dir(), Slic3r::GUI::GLGizmoCut3D::render_angle_input(), Slic3r::GUI::GLGizmoMeasure::render_dimensioning(), Slic3r::TriangleMesh::rotate(), Slic3r::GUI::Camera::rotate_on_sphere(), Slic3r::GUI::Camera::rotate_on_sphere_with_target(), Slic3r::GUI::GLGizmoMeasure::show_distance_xyz_ui(), and Slic3r::GUI::Camera::update_zenit().

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

◆ rad2deg_dir()

double Slic3r::Geometry::rad2deg_dir ( double angle)
65{
66 angle = (angle < PI) ? (-angle + PI/2.0) : (angle + PI/2.0);
67 if (angle < 0) angle += PI;
68 return rad2deg(angle);
69}
T rad2deg(T angle)
Definition Geometry.hpp:310

References Slic3r::angle(), PI, and rad2deg().

Here is the call graph for this function:

◆ ray_circle_intersections()

template<typename T>
int Slic3r::Geometry::ray_circle_intersections ( T r,
T a,
T b,
T c,
std::pair< Eigen::Matrix< T, 2, 1, Eigen::DontAlign >, Eigen::Matrix< T, 2, 1, Eigen::DontAlign > > & out )
178{
179 T lv2 = a * a + b * b;
180 if (lv2 < T(SCALED_EPSILON * SCALED_EPSILON)) {
181 //FIXME what is the correct epsilon?
182 // What if the line touches the circle?
183 return false;
184 }
185 return ray_circle_intersections_r2_lv2_c2(r * r, a, b, a * a + b * b, c, out);
186}
#define SCALED_EPSILON
Definition libslic3r.h:109

References SCALED_EPSILON.

◆ ray_circle_intersections_r2_lv2_c()

template<typename T>
int Slic3r::Geometry::ray_circle_intersections_r2_lv2_c ( T r2,
T a,
T b,
T lv2,
T c,
std::pair< Eigen::Matrix< T, 2, 1, Eigen::DontAlign >, Eigen::Matrix< T, 2, 1, Eigen::DontAlign > > & out )
163{
164 T x0 = - a * c;
165 T y0 = - b * c;
166 T d2 = r2 * lv2 - c * c;
167 if (d2 < T(0))
168 return 0;
169 T d = sqrt(d2);
170 out.first.x() = (x0 + b * d) / lv2;
171 out.first.y() = (y0 - a * d) / lv2;
172 out.second.x() = (x0 - b * d) / lv2;
173 out.second.y() = (y0 + a * d) / lv2;
174 return d == T(0) ? 1 : 2;
175}

Referenced by Slic3r::line_rounded_thick_segment_collision().

Here is the caller graph for this function:

◆ ray_point_distance() [1/2]

double Slic3r::Geometry::ray_point_distance ( const Line & iline,
const Point & ipt )
inline
215{
216 return (foot_pt(iline, ipt) - ipt.cast<double>()).norm();
217}

References foot_pt().

Here is the call graph for this function:

◆ ray_point_distance() [2/2]

template<typename T>
auto Slic3r::Geometry::ray_point_distance ( const T & ray_pt,
const T & ray_dir,
const T & pt )
inline
205{
206 return (foot_pt(ray_pt, ray_dir, pt) - pt).norm();
207}

References foot_pt().

Referenced by Slic3r::Voronoi::detail::line_point_equal_distance_points(), and Slic3r::Voronoi::signed_vertex_distances().

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

◆ ray_point_distance_squared() [1/2]

double Slic3r::Geometry::ray_point_distance_squared ( const Line & iline,
const Point & ipt )
inline
210{
211 return (foot_pt(iline, ipt) - ipt.cast<double>()).squaredNorm();
212}

References foot_pt().

Here is the call graph for this function:

◆ ray_point_distance_squared() [2/2]

template<typename T>
auto Slic3r::Geometry::ray_point_distance_squared ( const T & ray_pt,
const T & ray_dir,
const T & pt )
inline
200{
201 return (foot_pt(ray_pt, ray_dir, pt) - pt).squaredNorm();
202}

References foot_pt().

Here is the call graph for this function:

◆ ray_ray_intersection()

bool Slic3r::Geometry::ray_ray_intersection ( const Vec2d & p1,
const Vec2d & v1,
const Vec2d & p2,
const Vec2d & v2,
Vec2d & res )
inline
93{
94 double denom = v1(0) * v2(1) - v2(0) * v1(1);
95 if (std::abs(denom) < EPSILON)
96 return false;
97 double t = (v2(0) * (p1(1) - p2(1)) - v2(1) * (p1(0) - p2(0))) / denom;
98 res(0) = p1(0) + t * v1(0);
99 res(1) = p1(1) + t * v1(1);
100 return true;
101}

References EPSILON.

◆ retrieve_cell_point()

template<typename VD, typename SEGMENTS>
const VD::point_type Slic3r::Geometry::retrieve_cell_point ( const typename VD::cell_type & cell,
const SEGMENTS & segments )
inline
402{
403 assert(cell.source_category() == boost::polygon::SOURCE_CATEGORY_SEGMENT_START_POINT || cell.source_category() == boost::polygon::SOURCE_CATEGORY_SEGMENT_END_POINT);
404 return (cell.source_category() == boost::polygon::SOURCE_CATEGORY_SEGMENT_START_POINT) ? low(segments[cell.source_index()]) : high(segments[cell.source_index()]);
405}

Referenced by measure_edge_thickness().

Here is the caller graph for this function:

◆ rotation_diff_z()

double Slic3r::Geometry::rotation_diff_z ( const Vec3d & rot_xyz_from,
const Vec3d & rot_xyz_to )
766{
767 const Eigen::AngleAxisd angle_axis(rotation_xyz_diff(rot_xyz_from, rot_xyz_to));
768 const Vec3d axis = angle_axis.axis();
769 const double angle = angle_axis.angle();
770#ifndef NDEBUG
771 if (std::abs(angle) > 1e-8) {
772 assert(std::abs(axis.x()) < 1e-8);
773 assert(std::abs(axis.y()) < 1e-8);
774 }
775#endif /* NDEBUG */
776 return (axis.z() < 0) ? -angle : angle;
777}
Eigen::Quaterniond rotation_xyz_diff(const Vec3d &rot_xyz_from, const Vec3d &rot_xyz_to)
Definition Geometry.cpp:755

References Slic3r::angle(), and rotation_xyz_diff().

Referenced by Slic3r::PrintObject::PrintObject(), Slic3r::ModelObject::bake_xy_rotation_into_meshes(), and Slic3r::sla_instances().

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

◆ rotation_from_two_vectors()

void Slic3r::Geometry::rotation_from_two_vectors ( Vec3d from,
Vec3d to,
Vec3d & rotation_axis,
double & phi,
Matrix3d * rotation_matrix )
417{
418 const Matrix3d m = Eigen::Quaterniond().setFromTwoVectors(from, to).toRotationMatrix();
419 const Eigen::AngleAxisd aa(m);
420 rotation_axis = aa.axis();
421 phi = aa.angle();
422 if (rotation_matrix)
423 *rotation_matrix = m;
424}

Referenced by Slic3r::orientation::_orient(), Slic3r::orientation::orient(), Slic3r::orientation::orient(), Slic3r::orientation::orient_for_cooling(), and Slic3r::GUI::GLGizmoMeasure::set_to_parallel().

Here is the caller graph for this function:

◆ rotation_transform() [1/2]

Transform3d Slic3r::Geometry::rotation_transform ( const Vec3d & rotation)
366{
368 rotation_transform(transform, rotation);
369 return transform;
370}
void rotation_transform(Transform3d &transform, const Vec3d &rotation)
Definition Geometry.cpp:359

References rotation_transform(), and Slic3r::transform().

Here is the call graph for this function:

◆ rotation_transform() [2/2]

void Slic3r::Geometry::rotation_transform ( Transform3d & transform,
const Vec3d & rotation )
360{
361 transform = Transform3d::Identity();
362 transform.rotate(Eigen::AngleAxisd(rotation.z(), Vec3d::UnitZ()) * Eigen::AngleAxisd(rotation.y(), Vec3d::UnitY()) * Eigen::AngleAxisd(rotation.x(), Vec3d::UnitX()));
363}

References Slic3r::transform().

Referenced by Slic3r::GUI::GLCanvas3D::_render_3d_navigator(), Slic3r::GUI::GLGizmoCut3D::apply_cut_connectors(), Slic3r::apply_tolerance(), Slic3r::GUI::GLGizmoCut3D::dragging_grabber_rotation(), Slic3r::GUI::GLGizmoCut3D::flip_cut_plane(), Slic3r::GUI::GLGizmoRotate::local_transform(), Slic3r::Cut::perform_with_groove(), Slic3r::GUI::GCodeViewer::SequentialView::Marker::render(), Slic3r::GUI::GLGizmoCut3D::render_connectors(), Slic3r::GUI::GLGizmoCut3D::render_cut_plane_grabbers(), Slic3r::GUI::GLGizmoCut3D::render_rotation_snapping(), Slic3r::reset_instance_transformation(), Slic3r::GUI::Selection::rotate(), rotation_transform(), Slic3r::Geometry::Transformation::set_rotation(), Slic3r::Geometry::Transformation::set_rotation(), and Slic3r::GUI::GLGizmoCut3D::update_raycasters_for_picking_transform().

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

◆ rotation_xyz_diff()

Eigen::Quaterniond Slic3r::Geometry::rotation_xyz_diff ( const Vec3d & rot_xyz_from,
const Vec3d & rot_xyz_to )
756{
757 return
758 // From the current coordinate system to world.
759 Eigen::AngleAxisd(rot_xyz_to.z(), Vec3d::UnitZ()) * Eigen::AngleAxisd(rot_xyz_to.y(), Vec3d::UnitY()) * Eigen::AngleAxisd(rot_xyz_to.x(), Vec3d::UnitX()) *
760 // From world to the initial coordinate system.
761 Eigen::AngleAxisd(-rot_xyz_from.x(), Vec3d::UnitX()) * Eigen::AngleAxisd(-rot_xyz_from.y(), Vec3d::UnitY()) * Eigen::AngleAxisd(-rot_xyz_from.z(), Vec3d::UnitZ());
762}

Referenced by rotation_diff_z().

Here is the caller graph for this function:

◆ scale_transform() [1/4]

Transform3d Slic3r::Geometry::scale_transform ( const Vec3d & scale)
389{
392 return transform;
393}
void scale_transform(Transform3d &transform, double scale)
Definition Geometry.cpp:372

References scale(), scale_transform(), and Slic3r::transform().

Here is the call graph for this function:

◆ scale_transform() [2/4]

Transform3d Slic3r::Geometry::scale_transform ( double scale)
384{
385 return scale_transform(scale * Vec3d::Ones());
386}

References scale(), and scale_transform().

Here is the call graph for this function:

◆ scale_transform() [3/4]

void Slic3r::Geometry::scale_transform ( Transform3d & transform,
const Vec3d & scale )
378{
379 transform = Transform3d::Identity();
380 transform.scale(scale);
381}

References scale(), and Slic3r::transform().

Here is the call graph for this function:

◆ scale_transform() [4/4]

◆ segment_segment_intersection()

bool Slic3r::Geometry::segment_segment_intersection ( const Vec2d & p1,
const Vec2d & v1,
const Vec2d & p2,
const Vec2d & v2,
Vec2d & res )
inline
104{
105 double denom = v1(0) * v2(1) - v2(0) * v1(1);
106 if (std::abs(denom) < EPSILON)
107 // Lines are collinear.
108 return false;
109 double s12_x = p1(0) - p2(0);
110 double s12_y = p1(1) - p2(1);
111 double s_numer = v1(0) * s12_y - v1(1) * s12_x;
112 bool denom_is_positive = false;
113 if (denom < 0.) {
114 denom_is_positive = true;
115 denom = - denom;
116 s_numer = - s_numer;
117 }
118 if (s_numer < 0.)
119 // Intersection outside of the 1st segment.
120 return false;
121 double t_numer = v2(0) * s12_y - v2(1) * s12_x;
122 if (! denom_is_positive)
123 t_numer = - t_numer;
124 if (t_numer < 0. || s_numer > denom || t_numer > denom)
125 // Intersection outside of the 1st or 2nd segment.
126 return false;
127 // Intersection inside both of the segments.
128 double t = t_numer / denom;
129 res(0) = p1(0) + t * v1(0);
130 res(1) = p1(1) + t * v1(1);
131 return true;
132}

References EPSILON.

Referenced by Slic3r::FillLightning::lineSegmentPolygonsIntersection().

Here is the caller graph for this function:

◆ segments_intersect()

bool Slic3r::Geometry::segments_intersect ( const Slic3r::Point & ip1,
const Slic3r::Point & ip2,
const Slic3r::Point & jp1,
const Slic3r::Point & jp2 )
inline
137{
138 //assert(ip1 != ip2);
139 //assert(jp1 != jp2);
140
141 auto segments_could_intersect = [](
142 const Slic3r::Point &ip1, const Slic3r::Point &ip2,
143 const Slic3r::Point &jp1, const Slic3r::Point &jp2) -> std::pair<int, int>
144 {
145 Vec2i64 iv = (ip2 - ip1).cast<int64_t>();
146 Vec2i64 vij1 = (jp1 - ip1).cast<int64_t>();
147 Vec2i64 vij2 = (jp2 - ip1).cast<int64_t>();
148 int64_t tij1 = cross2(iv, vij1);
149 int64_t tij2 = cross2(iv, vij2);
150 return std::make_pair(
151 // signum
152 (tij1 > 0) ? 1 : ((tij1 < 0) ? -1 : 0),
153 (tij2 > 0) ? 1 : ((tij2 < 0) ? -1 : 0));
154 };
155
156 std::pair<int, int> sign1 = segments_could_intersect(ip1, ip2, jp1, jp2);
157 std::pair<int, int> sign2 = segments_could_intersect(jp1, jp2, ip1, ip2);
158 int test1 = sign1.first * sign1.second;
159 int test2 = sign2.first * sign2.second;
160 if (test1 <= 0 && test2 <= 0) {
161 // The segments possibly intersect. They may also be collinear, but not intersect.
162 if (test1 != 0 || test2 != 0)
163 // Certainly not collinear, then the segments intersect.
164 return true;
165 // If the first segment is collinear with the other, the other is collinear with the first segment.
166 assert((sign1.first == 0 && sign1.second == 0) == (sign2.first == 0 && sign2.second == 0));
167 if (sign1.first == 0 && sign1.second == 0) {
168 // The segments are certainly collinear. Now verify whether they overlap.
169 Slic3r::Point vi = ip2 - ip1;
170 // Project both on the longer coordinate of vi.
171 int axis = std::abs(vi.x()) > std::abs(vi.y()) ? 0 : 1;
172 coord_t i = ip1(axis);
173 coord_t j = ip2(axis);
174 coord_t k = jp1(axis);
175 coord_t l = jp2(axis);
176 if (i > j)
177 std::swap(i, j);
178 if (k > l)
179 std::swap(k, l);
180 return (k >= i && k <= j) || (i >= k && i <= l);
181 }
182 }
183 return false;
184}
int64_t coord_t
Definition libslic3r.h:48

References Slic3r::cast(), and Slic3r::cross2().

Referenced by Slic3r::connect_brim_lines(), Slic3r::contour_distance(), Slic3r::EdgeGrid::Grid::has_intersecting_edges(), Slic3r::EdgeGrid::Grid::intersecting_edges(), Slic3r::join_close_ends(), Slic3r::FirstIntersectionVisitor::operator()(), Slic3r::FillLightning::polygonCollidesWithLineSegment(), Slic3r::trim_loop(), and Slic3r::tsp_remove_crossings().

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

◆ simplify_polygons()

void Slic3r::Geometry::simplify_polygons ( const Polygons & polygons,
double tolerance,
Polygons * retval )
72{
73 Polygons pp;
74 for (Polygons::const_iterator it = polygons.begin(); it != polygons.end(); ++it) {
75 Polygon p = *it;
76 p.points.push_back(p.points.front());
78 p.points.pop_back();
79 pp.push_back(p);
80 }
81 *retval = Slic3r::simplify_polygons(pp);
82}
static Points _douglas_peucker(const Points &points, const double tolerance)
Definition MultiPoint.cpp:175
Polygons simplify_polygons(const Polygons &subject)
Definition ClipperUtils.cpp:1303
std::vector< Polygon, PointsAllocator< Polygon > > Polygons
Definition Polygon.hpp:22

References Slic3r::MultiPoint::_douglas_peucker(), Slic3r::MultiPoint::points, and Slic3r::simplify_polygons().

Referenced by Slic3r::Print::_make_skirt().

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

◆ smallest_enclosing_circle2_welzl()

template<typename Vector, typename Points>
CircleSq< Vector > Slic3r::Geometry::smallest_enclosing_circle2_welzl ( const Points & points,
const typename Vector::Scalar epsilon )
113{
114 using Scalar = typename Vector::Scalar;
115 CircleSq<Vector> circle;
116
117 if (! points.empty()) {
118 const auto &p0 = points[0].template cast<Scalar>();
119 if (points.size() == 1) {
120 circle.center = p0;
121 circle.radius2 = epsilon * epsilon;
122 } else {
123 circle = CircleSq<Vector>(p0, points[1].template cast<Scalar>()).inflated(epsilon);
124 for (size_t i = 2; i < points.size(); ++ i)
125 if (const Vector &p = points[i].template cast<Scalar>(); ! circle.contains(p)) {
126 // p is the first point on the smallest circle enclosing points[0..i]
127 circle = CircleSq<Vector>(p0, p).inflated(epsilon);
128 for (size_t j = 1; j < i; ++ j)
129 if (const Vector &q = points[j].template cast<Scalar>(); ! circle.contains(q)) {
130 // q is the second point on the smallest circle enclosing points[0..i]
131 circle = CircleSq<Vector>(p, q).inflated(epsilon);
132 for (size_t k = 0; k < j; ++ k)
133 if (const Vector &r = points[k].template cast<Scalar>(); ! circle.contains(r))
134 circle = CircleSq<Vector>(p, q, r, epsilon).inflated(epsilon);
135 }
136 }
137 }
138 }
139
140 return circle;
141}
Definition Circle.hpp:40
bool contains(const Vector &p) const
Definition Circle.hpp:56
Vector center
Definition Circle.hpp:43
Scalar radius2
Definition Circle.hpp:44
CircleSq inflated(Scalar epsilon) const
Definition Circle.hpp:59

References Slic3r::cast(), Slic3r::Geometry::CircleSq< Vector >::center, Slic3r::Geometry::CircleSq< Vector >::contains(), Slic3r::Geometry::CircleSq< Vector >::inflated(), and Slic3r::Geometry::CircleSq< Vector >::radius2.

Referenced by smallest_enclosing_circle_welzl().

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

◆ smallest_enclosing_circle_welzl() [1/2]

Circled Slic3r::Geometry::smallest_enclosing_circle_welzl ( const Points & points)
inline
152{
154}
Circle< Vector > smallest_enclosing_circle_welzl(const Points &points, const typename Vector::Scalar epsilon)
Definition Circle.hpp:145

References SCALED_EPSILON, and smallest_enclosing_circle_welzl().

Here is the call graph for this function:

◆ smallest_enclosing_circle_welzl() [2/2]

template<typename Vector, typename Points>
Circle< Vector > Slic3r::Geometry::smallest_enclosing_circle_welzl ( const Points & points,
const typename Vector::Scalar epsilon )
146{
148}
CircleSq< Vector > smallest_enclosing_circle2_welzl(const Points &points, const typename Vector::Scalar epsilon)
Definition Circle.hpp:112
@ Circle
Definition BuildVolume.hpp:25

References Slic3r::Circle, and smallest_enclosing_circle2_welzl().

Referenced by Slic3r::BuildVolume::BuildVolume(), and smallest_enclosing_circle_welzl().

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

◆ to_cgal_point() [1/3]

CGAL_Point Slic3r::Geometry::to_cgal_point ( const Point & pt)
inline
151{ return {pt.x(), pt.y()}; }

◆ to_cgal_point() [2/3]

CGAL_Point Slic3r::Geometry::to_cgal_point ( const VD::vertex_type * pt)
inline
150{ return {pt->x(), pt->y()}; }

Referenced by get_parabolic_segment(), Slic3r::Geometry::VoronoiUtilsCgal::is_voronoi_diagram_planar_intersection(), and orientation_of_two_edges().

Here is the caller graph for this function:

◆ to_cgal_point() [3/3]

CGAL_Point Slic3r::Geometry::to_cgal_point ( const Vec2d & pt)
inline
152{ return {pt.x(), pt.y()}; }

◆ to_range_pi_pi()

template<typename T>
void Slic3r::Geometry::to_range_pi_pi ( T & angle)
331 {
332 if (angle > T(PI) || angle <= -T(PI)) {
333 int count = static_cast<int>(std::round(angle / (2 * PI)));
334 angle -= static_cast<T>(count * 2 * PI);
335 assert(angle <= T(PI) && angle > -T(PI));
336 }
337}
static unsigned int count
Definition AuxiliaryDataViewModel.cpp:246

References Slic3r::angle(), count, and PI.

Referenced by Slic3r::GUI::dragging_rotate_gizmo(), Slic3r::GUI::GLGizmoEmboss::draw_advanced(), and Slic3r::GUI::GLGizmoSVG::draw_rotation().

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

◆ transform3d_from_string()

Transform3d Slic3r::Geometry::transform3d_from_string ( const std::string & transform_str)
733{
734 assert(is_decimal_separator_point()); // for atof
735 Transform3d transform = Transform3d::Identity();
736
737 if (!transform_str.empty()) {
738 std::vector<std::string> mat_elements_str;
739 boost::split(mat_elements_str, transform_str, boost::is_any_of(" "), boost::token_compress_on);
740
741 const unsigned int size = (unsigned int)mat_elements_str.size();
742 if (size == 16) {
743 unsigned int i = 0;
744 for (unsigned int r = 0; r < 4; ++r) {
745 for (unsigned int c = 0; c < 4; ++c) {
746 transform(r, c) = ::atof(mat_elements_str[i++].c_str());
747 }
748 }
749 }
750 }
751
752 return transform;
753}
bool is_decimal_separator_point()
Definition LocalesUtils.cpp:78

References Slic3r::is_decimal_separator_point(), and Slic3r::transform().

Referenced by Slic3r::_3MF_Importer::_generate_volumes(), and Slic3r::_BBS_3MF_Importer::_generate_volumes_new().

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

◆ translation_transform() [1/2]

Transform3d Slic3r::Geometry::translation_transform ( const Vec3d & translation)
353{
355 translation_transform(transform, translation);
356 return transform;
357}
void translation_transform(Transform3d &transform, const Vec3d &translation)
Definition Geometry.cpp:346

References Slic3r::transform(), and translation_transform().

Here is the call graph for this function:

◆ translation_transform() [2/2]

void Slic3r::Geometry::translation_transform ( Transform3d & transform,
const Vec3d & translation )
347{
348 transform = Transform3d::Identity();
349 transform.translate(translation);
350}

References Slic3r::transform().

Referenced by Slic3r::GUI::GLGizmoCut3D::PartSelection::PartSelection(), Slic3r::GUI::GLCanvas3D::_render_platelist(), Slic3r::GUI::GLGizmoCut3D::apply_cut_connectors(), Slic3r::GUI::Plater::cut_horizontal(), Slic3r::GUI::cut_model(), Slic3r::GUI::GLGizmoCut3D::dragging_grabber_move(), Slic3r::GUI::GLGizmoCut3D::get_cut_matrix(), Slic3r::Geometry::Transformation::get_offset_matrix(), Slic3r::GUI::GLGizmoCut3D::has_valid_groove(), Slic3r::GUI::init_torus_data(), Slic3r::GUI::GLGizmoCut3D::is_conflict_for_connector(), Slic3r::GUI::GLGizmoCut3D::is_outside_of_cut_contour(), Slic3r::GUI::GLGizmoFlatten::on_register_raycasters_for_picking(), Slic3r::GUI::GLGizmoFlatten::on_render(), Slic3r::GUI::GLGizmoMeasure::on_render(), Slic3r::Cut::perform_with_groove(), Slic3r::Cut::perform_with_plane(), Slic3r::process_volume_cut(), Slic3r::GUI::Plater::priv::reload_from_disk(), Slic3r::GUI::GCodeViewer::SequentialView::Marker::render(), Slic3r::GUI::GLGizmoCut3D::PartSelection::render(), Slic3r::GUI::GLGizmoCut3D::render_connectors(), Slic3r::GUI::GLGizmoPainterBase::render_cursor_circle(), Slic3r::GUI::GLGizmoCut3D::render_cut_plane(), Slic3r::GUI::GLGizmoCut3D::render_cut_plane_grabbers(), Slic3r::GUI::GLGizmoMeasure::render_dimensioning(), Slic3r::GUI::GCodeViewer::render_markers(), Slic3r::GUI::GLGizmoBrimEars::render_points(), Slic3r::GUI::GLGizmoCut3D::render_rotation_snapping(), Slic3r::GUI::Plater::priv::replace_volume_with_stl(), Slic3r::ModelVolume::restore_painting(), Slic3r::GUI::Selection::rotate(), Slic3r::GUI::GLGizmoCut3D::rotate_vec3d_around_plane_center(), Slic3r::GUI::Selection::scale_and_translate(), Slic3r::GUI::GLGizmoMeasure::set_distance(), Slic3r::GUI::GLGizmoCut3D::PartSelection::toggle_selection(), Slic3r::GUI::Selection::transform_instance_relative(), Slic3r::GUI::Selection::transform_volume_relative(), Slic3r::GUI::GLGizmoCut3D::transformed_bounding_box(), Slic3r::GUI::Selection::translate(), translation_transform(), and Slic3r::GUI::GLGizmoCut3D::update_raycasters_for_picking_transform().

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