Prusa Slicer 2.6.0
Loading...
Searching...
No Matches
Slic3r::Geometry Namespace Reference

Namespaces

namespace  BicubicInternal
 
namespace  impl
 
namespace  rotcalip
 

Classes

class  ArrangeItem
 
class  ArrangeItemIndex
 
struct  Circle
 
struct  CircleSq
 
struct  CubicKernelWrapper
 
class  Lines2VDSegments
 
class  MedialAxis
 
struct  ParabolicSegment
 
struct  PiecewiseFittedCurve
 
struct  PolynomialCurve
 
class  Transformation
 
struct  TransformationSVD
 
class  VoronoiDiagram
 
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 CircleSqf = CircleSq< Vec2f >
 
using CircleSqd = CircleSq< Vec2d >
 
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)
 
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 >
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_rotation (const Eigen::Matrix< double, 3, 3, Eigen::DontAlign > &rotation_matrix)
 
Vec3d extract_rotation (const Transform3d &transform)
 
static Transform3d extract_rotation_matrix (const Transform3d &trafo)
 
static Transform3d extract_scale (const Transform3d &trafo)
 
static std::pair< Transform3d, Transform3dextract_rotation_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 Transform3d &trafo_from, const Transform3d &trafo_to)
 
bool trafos_differ_in_rotation_by_z_and_mirroring_by_xy_only (const Transform3d &t1, const Transform3d &t2)
 
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 >
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 >
rad2deg (T angle)
 
template<typename T >
constexpr T deg2rad (const T angle)
 
template<typename T >
angle_to_0_2PI (T angle)
 
bool is_rotation_ninety_degrees (double a)
 
bool is_rotation_ninety_degrees (const Vec3d &rotation)
 
bool trafos_differ_in_rotation_by_z_and_mirroring_by_xy_only (const Transformation &t1, const Transformation &t2)
 
template<class Tout = double, class Tin >
std::pair< Tout, Tout > dir_to_spheric (const Vec< 3, Tin > &n, Tout norm=1.)
 
template<class T = double>
Vec< 3, T > spheric_to_dir (double polar, double azimuth)
 
template<class T = double, class Pair >
Vec< 3, T > spheric_to_dir (const Pair &v)
 
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 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< Vectorsmallest_enclosing_circle2_welzl (const Points &points, const typename Vector::Scalar epsilon)
 
template<typename Vector , typename Points >
Circle< Vectorsmallest_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, Kernelfit_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_typemeasure_edge_thickness (const VD &vd, const typename VD::edge_type &edge, const SEGMENTS &segments)
 
static CGAL_Point to_cgal_point (const VD::vertex_type *pt)
 
static CGAL_Point to_cgal_point (const Point &pt)
 
static CGAL_Point to_cgal_point (const Vec2d &pt)
 
static Linef make_linef (const VD::edge_type &edge)
 
static bool is_equal (const VD::vertex_type &first, const VD::vertex_type &second)
 
static ParabolicSegment get_parabolic_segment (const VD::edge_type &edge, const std::vector< VoronoiUtils::Segment > &segments)
 
static CGAL::Orientation orientation_of_two_edges (const VD::edge_type &edge_a, const VD::edge_type &edge_b, const std::vector< VoronoiUtils::Segment > &segments)
 
static bool check_if_three_edges_are_ccw (const VD::edge_type &first, const VD::edge_type &second, const VD::edge_type &third, const std::vector< VoronoiUtils::Segment > &segments)
 

Class Documentation

◆ Slic3r::Geometry::ArrangeItem

class Slic3r::Geometry::ArrangeItem
+ Collaboration diagram for 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 = typedef impl::K::Point_2

◆ Circled

◆ Circlef

◆ CircleSqd

◆ CircleSqf

◆ CubicBSplineKernel

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

◆ CubicCatmulRomKernel

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

◆ LinearKernel

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

◆ ParabolicTangentToParabolicTangentOrientation

◆ ParabolicTangentToSegmentOrientation

Enumeration Type Documentation

◆ Orientation

Enumerator
ORIENTATION_CCW 
ORIENTATION_CW 
ORIENTATION_COLINEAR 
19{
21 ORIENTATION_CW = -1,
23};
@ ORIENTATION_CCW
Definition Geometry.hpp:20
@ ORIENTATION_COLINEAR
Definition Geometry.hpp:22
@ ORIENTATION_CW
Definition Geometry.hpp:21

Function Documentation

◆ angle_to_0_2PI()

template<typename T >
T Slic3r::Geometry::angle_to_0_2PI ( angle)
291{
292 static const T TWO_PI = T(2) * T(PI);
293 while (angle < T(0))
294 {
295 angle += TWO_PI;
296 }
297 while (TWO_PI < angle)
298 {
299 angle -= TWO_PI;
300 }
301
302 return angle;
303}
static constexpr double PI
Definition libslic3r.h:58
double angle(const Eigen::MatrixBase< Derived > &v1, const Eigen::MatrixBase< Derived2 > &v2)
Definition Point.hpp:112

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

References Slic3r::area(), Slic3r::BoundingBoxBase< PointType, APointsType >::defined, dist(), floor(), linint(), Slic3r::BoundingBoxBase< PointType, APointsType >::max, Slic3r::BoundingBoxBase< PointType, APointsType >::merge(), Slic3r::BoundingBoxBase< PointType, APointsType >::min, Slic3r::BoundingBoxBase< PointType, APointsType >::size(), and Slic3r::BoundingBoxBase< PointType, APointsType >::translate().

+ Here is the call 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 
)
322{
323 Transform3d transform;
324 assemble_transform(transform, translation, rotation, scale, mirror);
325 return transform;
326}
int scale(const int val)
Definition WipeTowerDialog.cpp:14
void assemble_transform(Transform3d &transform, const Vec3d &translation, const Vec3d &rotation, const Vec3d &scale, const Vec3d &mirror)
Definition Geometry.cpp:301

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 
)
310{
311 Transform3d transform;
312 assemble_transform(transform, translation, rotation, scale, mirror);
313 return transform;
314}

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 
)
317{
318 transform = translation * rotation * scale * mirror;
319}

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 
)
302{
303 transform = Transform3d::Identity();
304 transform.translate(translation);
305 transform.rotate(Eigen::AngleAxisd(rotation(2), Vec3d::UnitZ()) * Eigen::AngleAxisd(rotation(1), Vec3d::UnitY()) * Eigen::AngleAxisd(rotation(0), Vec3d::UnitX()));
306 transform.scale(scale.cwiseProduct(mirror));
307}
Represents a 3D rotation as a rotation angle around an arbitrary 3D axis.
Definition AngleAxis.h:50

References Eigen::Transform< double, 3, Eigen::Affine, Eigen::DontAlign >::Identity(), scale(), Slic3r::Linef3::scale(), and Slic3r::transform().

Referenced by assemble_transform(), assemble_transform(), and Slic3r::GUI::GLGizmoSlaSupports::update_point_raycasters_for_picking_transform().

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

◆ bicubic_interpolate()

template<typename Kernel , typename Derived >
static float Slic3r::Geometry::bicubic_interpolate ( const Eigen::MatrixBase< Derived > &  F,
const Eigen::Matrix< typename Kernel::FloatType, 2, 1, Eigen::DontAlign > &  pt 
)
static
259 {
260 typedef typename Kernel::FloatType T;
261 const int w = F.cols();
262 const int h = F.rows();
263 const int ix = (int) floor(pt[0]);
264 const int iy = (int) floor(pt[1]);
265 const T s = pt[0] - T( ix);
266 const T t = pt[1] - T( iy);
267
268 if (ix > 1 && ix + 2 < w && iy > 1 && iy + 2 < h) {
269 // Inside the fully interpolated region.
270 return Kernel::interpolate(
271 Kernel::interpolate(F(ix - 1, iy - 1), F(ix, iy - 1), F(ix + 1, iy - 1), F(ix + 2, iy - 1), s),
272 Kernel::interpolate(F(ix - 1, iy), F(ix, iy), F(ix + 1, iy), F(ix + 2, iy), s),
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 + 2), F(ix, iy + 2), F(ix + 1, iy + 2), F(ix + 2, iy + 2), s), t);
275 }
276 // Transition region. Extend with a constant function.
277 auto f = [&F, w, h](int x, int y) {
278 return F(BicubicInternal::clamp(x, 0, w - 1), BicubicInternal::clamp(y, 0, h - 1));
279 };
280 return Kernel::interpolate(
281 Kernel::interpolate(f(ix - 1, iy - 1), f(ix, iy - 1), f(ix + 1, iy - 1), f(ix + 2, iy - 1), s),
282 Kernel::interpolate(f(ix - 1, iy), f(ix, iy), f(ix + 1, iy), f(ix + 2, iy), s),
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 + 2), f(ix, iy + 2), f(ix + 1, iy + 2), f(ix + 2, iy + 2), s), t);
285}
@ F
Definition libslic3r.h:102

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

+ Here is the call graph for this function:

◆ check_if_three_edges_are_ccw()

static bool Slic3r::Geometry::check_if_three_edges_are_ccw ( const VD::edge_type &  first,
const VD::edge_type &  second,
const VD::edge_type &  third,
const std::vector< VoronoiUtils::Segment > &  segments 
)
static
230{
231 assert(is_equal(*first.vertex0(), *second.vertex0()) && is_equal(*second.vertex0(), *third.vertex0()));
232
233 CGAL::Orientation orientation = orientation_of_two_edges(first, second, segments);
234 if (orientation == CGAL::Orientation::COLLINEAR) {
235 // The first two edges are collinear, so the third edge must be on the right side on the first of them.
236 return orientation_of_two_edges(first, third, segments) == CGAL::Orientation::RIGHT_TURN;
237 } else if (orientation == CGAL::Orientation::LEFT_TURN) {
238 // CCW oriented angle between vectors (common_pt, pt1) and (common_pt, pt2) is bellow PI.
239 // So we need to check if test_pt isn't between them.
240 CGAL::Orientation orientation1 = orientation_of_two_edges(first, third, segments);
241 CGAL::Orientation orientation2 = orientation_of_two_edges(second, third, segments);
242 return (orientation1 != CGAL::Orientation::LEFT_TURN || orientation2 != CGAL::Orientation::RIGHT_TURN);
243 } else {
244 assert(orientation == CGAL::Orientation::RIGHT_TURN);
245 // CCW oriented angle between vectors (common_pt, pt1) and (common_pt, pt2) is upper PI.
246 // So we need to check if test_pt is between them.
247 CGAL::Orientation orientation1 = orientation_of_two_edges(first, third, segments);
248 CGAL::Orientation orientation2 = orientation_of_two_edges(second, third, segments);
249 return (orientation1 == CGAL::Orientation::RIGHT_TURN || orientation2 == CGAL::Orientation::LEFT_TURN);
250 }
251}
static CGAL::Orientation orientation_of_two_edges(const VD::edge_type &edge_a, const VD::edge_type &edge_b, const std::vector< VoronoiUtils::Segment > &segments)
Definition VoronoiUtilsCgal.cpp:192
static bool is_equal(const VD::vertex_type &first, const VD::vertex_type &second)
Definition VoronoiUtilsCgal.cpp:131

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 
)
14{
15 using Scalar = typename Vector::Scalar;
16 Vector b = bsrc - a;
17 Vector c = csrc - a;
18 Scalar lb = b.squaredNorm();
19 Scalar lc = c.squaredNorm();
20 if (Scalar d = b.x() * c.y() - b.y() * c.x(); std::abs(d) < epsilon) {
21 // The three points are collinear. Take the center of the two points
22 // furthest away from each other.
23 Scalar lbc = (csrc - bsrc).squaredNorm();
24 return Scalar(0.5) * (
25 lb > lc && lb > lbc ? a + bsrc :
26 lc > lb && lc > lbc ? a + csrc : bsrc + csrc);
27 } else {
28 Vector v = lc * b - lb * c;
29 return a + Vector(- v.y(), v.x()) / (2 * d);
30 }
31}
internal::traits< Derived >::Scalar Scalar
Definition PlainObjectBase.h:106
Definition Point.hpp:158

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

+ Here is the caller graph for this function:

◆ circle_center_taubin_newton() [1/3]

Point Slic3r::Geometry::circle_center_taubin_newton ( const Points input,
size_t  cycles = 20 
)
inline
97{ return circle_center_taubin_newton(input.cbegin(), input.cend(), cycles); }
static int input(void)
Point circle_center_taubin_newton(const Points::const_iterator &input_begin, const Points::const_iterator &input_end, size_t cycles)
Adapted from work in "Circular and Linear Regression: Fitting circles and lines by least squares",...
Definition Circle.cpp:11

References circle_center_taubin_newton(), and input().

+ Here is the call graph for this function:

◆ circle_center_taubin_newton() [2/3]

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

References circle_center_taubin_newton(), and input().

+ Here is the call graph for this function:

◆ circle_center_taubin_newton() [3/3]

Point Slic3r::Geometry::circle_center_taubin_newton ( const Points::const_iterator &  input_begin,
const Points::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.

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

12{
13 Vec2ds tmp;
14 tmp.reserve(std::distance(input_begin, input_end));
15 std::transform(input_begin, input_end, std::back_inserter(tmp), [] (const Point& in) { return unscale(in); } );
16 Vec2d center = circle_center_taubin_newton(tmp.cbegin(), tmp.end(), cycles);
17 return Point::new_scale(center.x(), center.y());
18}
T unscale(Q v)
Definition libslic3r.h:95
std::vector< Vec2d > Vec2ds
Definition Point.hpp:63

References circle_center_taubin_newton(), 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_ransac()

Circled Slic3r::Geometry::circle_ransac ( const Vec2ds input,
size_t  iterations,
double *  min_error 
)
112{
113 if (input.size() < 3)
114 return Circled::make_invalid();
115
116 std::mt19937 rng;
117 std::vector<Vec2d> samples;
118 Circled circle_best = Circled::make_invalid();
119 double err_min = std::numeric_limits<double>::max();
120 for (size_t iter = 0; iter < iterations; ++ iter) {
121 samples.clear();
122 std::sample(input.begin(), input.end(), std::back_inserter(samples), 3, rng);
123 Circled c;
124 c.center = Geometry::circle_center(samples[0], samples[1], samples[2], EPSILON);
125 c.radius = std::accumulate(input.begin(), input.end(), 0., [&c](double acc, const Vec2d& pt) { return (pt - c.center).norm() + acc; });
126 c.radius /= double(input.size());
127 double err = 0;
128 for (const Vec2d &pt : input)
129 err = std::max(err, std::abs((pt - c.center).norm() - c.radius));
130 if (err < err_min) {
131 err_min = err;
132 circle_best = c;
133 }
134 }
135 if (min_error)
136 *min_error = err_min;
137 return circle_best;
138}
static constexpr double EPSILON
Definition libslic3r.h:51
STL namespace.
Definition Circle.hpp:62

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

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 
)
99{
100 Circled out;
101 if (input.size() < 3) {
102 out = Circled::make_invalid();
103 } else {
104 out.center = circle_center_taubin_newton(input, cycles);
105 out.radius = std::accumulate(input.begin(), input.end(), 0., [&out](double acc, const Vec2d& pt) { return (pt - out.center).norm() + acc; });
106 out.radius /= double(input.size());
107 }
108 return out;
109}
Vector center
Definition Circle.hpp:65
Scalar radius
Definition Circle.hpp:66

References Slic3r::Geometry::Circle< Vector >::center, circle_center_taubin_newton(), input(), Slic3r::Geometry::Circle< Vector >::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 
)
45{
46 for (typename std::vector<T>::const_iterator it = vector.begin(); it != vector.end(); ++it) {
47 if (it->contains(point)) return true;
48 }
49 return false;
50}

Referenced by Slic3r::GUI::GCodeViewer::refresh_render_paths().

+ Here is the caller graph for this function:

◆ contains_skew()

static bool Slic3r::Geometry::contains_skew ( const Transform3d trafo)
static
428{
429 Matrix3d rotation;
431 trafo.computeRotationScaling(&rotation, &scale);
432
433 if (scale.isDiagonal())
434 return false;
435
436 if (scale.determinant() >= 0.0)
437 return true;
438
439 // the matrix contains mirror
440 const Matrix3d ratio = scale.cwiseQuotient(trafo.matrix().block<3,3>(0,0));
441
442 auto check_skew = [&ratio](int i, int j, bool& skew) {
443 if (!std::isnan(ratio(i, j)) && !std::isnan(ratio(j, i)))
444 skew |= std::abs(ratio(i, j) * ratio(j, i) - 1.0) > EPSILON;
445 };
446
447 bool has_skew = false;
448 check_skew(0, 1, has_skew);
449 check_skew(0, 2, has_skew);
450 check_skew(1, 2, has_skew);
451 return has_skew;
452}
EIGEN_DEVICE_FUNC const MatrixType & matrix() const
Definition Transform.h:395
EIGEN_DEVICE_FUNC void computeRotationScaling(RotationMatrixType *rotation, ScalingMatrixType *scaling) const
Definition Transform.h:1079

References Eigen::Transform< _Scalar, _Dim, _Mode, _Options >::computeRotationScaling(), EPSILON, Eigen::Transform< _Scalar, _Dim, _Mode, _Options >::matrix(), and 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)
108{
109 Points pp;
110 size_t sz = 0;
111 for (const auto &expoly : expolygons)
112 sz += expoly.contour.size();
113 pp.reserve(sz);
114 for (const auto &expoly : expolygons)
115 pp.insert(pp.end(), expoly.contour.points.begin(), expoly.contour.points.end());
116 return convex_hull(pp);
117}
std::vector< Point, PointsAllocator< Point > > Points
Definition Point.hpp:58

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

+ Here is the call graph for this function:

◆ convex_hull() [2/4]

Polygon Slic3r::Geometry::convex_hull ( const Polygons polygons)
99{
100 Points pp;
101 for (Polygons::const_iterator p = polygons.begin(); p != polygons.end(); ++p) {
102 pp.insert(pp.end(), p->points.begin(), p->points.end());
103 }
104 return convex_hull(std::move(pp));
105}

References convex_hull().

+ Here is the call graph for this function:

◆ convex_hull() [3/4]

Pointf3s Slic3r::Geometry::convex_hull ( Pointf3s  points)
41{
42 assert(points.size() >= 3);
43 // sort input points
44 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()); });
45
46 int n = points.size(), k = 0;
47 Pointf3s hull;
48
49 if (n >= 3)
50 {
51 hull.resize(2 * n);
52
53 // Build lower hull
54 for (int i = 0; i < n; ++i)
55 {
56 Point p = Point::new_scale(points[i](0), points[i](1));
57 while (k >= 2)
58 {
59 Point k1 = Point::new_scale(hull[k - 1](0), hull[k - 1](1));
60 Point k2 = Point::new_scale(hull[k - 2](0), hull[k - 2](1));
61
62 if (Geometry::orient(p, k2, k1) != Geometry::ORIENTATION_CCW)
63 --k;
64 else
65 break;
66 }
67
68 hull[k++] = points[i];
69 }
70
71 // Build upper hull
72 for (int i = n - 2, t = k + 1; i >= 0; --i)
73 {
74 Point p = Point::new_scale(points[i](0), points[i](1));
75 while (k >= t)
76 {
77 Point k1 = Point::new_scale(hull[k - 1](0), hull[k - 1](1));
78 Point k2 = Point::new_scale(hull[k - 2](0), hull[k - 2](1));
79
80 if (Geometry::orient(p, k2, k1) != Geometry::ORIENTATION_CCW)
81 --k;
82 else
83 break;
84 }
85
86 hull[k++] = points[i];
87 }
88
89 hull.resize(k);
90
91 assert(hull.front() == hull.back());
92 hull.pop_back();
93 }
94
95 return hull;
96}
std::vector< Vec3d > Pointf3s
Definition Point.hpp:64
Kernel::Point_2 Point
Definition point_areas.cpp:20

References orient(), and ORIENTATION_CCW.

+ Here is the call graph for this function:

◆ convex_hull() [4/4]

Polygon Slic3r::Geometry::convex_hull ( Points  pts)
12{
13 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()); });
14 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());
15
16 Polygon hull;
17 int n = (int)pts.size();
18 if (n >= 3) {
19 int k = 0;
20 hull.points.resize(2 * n);
21 // Build lower hull
22 for (int i = 0; i < n; ++ i) {
23 while (k >= 2 && Geometry::orient(pts[i], hull[k-2], hull[k-1]) != Geometry::ORIENTATION_CCW)
24 -- k;
25 hull[k ++] = pts[i];
26 }
27 // Build upper hull
28 for (int i = n-2, t = k+1; i >= 0; i--) {
29 while (k >= t && Geometry::orient(pts[i], hull[k-2], hull[k-1]) != Geometry::ORIENTATION_CCW)
30 -- k;
31 hull[k ++] = pts[i];
32 }
33 hull.points.resize(k);
34 assert(hull.points.front() == hull.points.back());
35 hull.points.pop_back();
36 }
37 return hull;
38}
Points points
Definition MultiPoint.hpp:18
size_t size() const
Definition MultiPoint.hpp:39
Definition Polygon.hpp:24

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

Referenced by Slic3r::BuildVolume::BuildVolume(), Slic3r::Print::_make_skirt(), Slic3r::TriangleMesh::convex_hull(), convex_hull(), convex_hull(), 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::its_convex_hull_2d_above(), Slic3r::GUI::update_arrangepoly_slaprint(), Slic3r::GUI::GLGizmoFlatten::update_planes(), and Slic3r::GUI::GLCanvas3D::update_sequential_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)
120{
121 Points pp;
122 size_t sz = 0;
123 for (const auto &polyline : polylines)
124 sz += polyline.points.size();
125 pp.reserve(sz);
126 for (const auto &polyline : polylines)
127 pp.insert(pp.end(), polyline.points.begin(), polyline.points.end());
128 return convex_hull(pp);
129}

References convex_hull(), and Slic3r::MultiPoint::points.

+ Here is the call graph for this function:

◆ convex_polygons_intersect()

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

References Slic3r::MultiPoint::size().

+ Here is the call graph for this function:

◆ cubic_interpolate()

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

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

+ Here is the call 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)
336{
337 std::pair<std::vector<Vec2d>, std::vector<Vec2d>> out;
338 std::vector<Vec2d> &bottom = out.first;
339 std::vector<Vec2d> &top = out.second;
340
341 // Find the minimum point.
342 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()); });
343 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()); });
344 if (left_bottom != src.end() && left_bottom != right_top) {
345 // Produce the bottom and bottom chains.
346 if (left_bottom < right_top) {
347 bottom.assign(left_bottom, right_top + 1);
348 size_t cnt = (src.end() - right_top) + (left_bottom + 1 - src.begin());
349 top.reserve(cnt);
350 top.assign(right_top, src.end());
351 top.insert(top.end(), src.begin(), left_bottom + 1);
352 } else {
353 size_t cnt = (src.end() - left_bottom) + (right_top + 1 - src.begin());
354 bottom.reserve(cnt);
355 bottom.assign(left_bottom, src.end());
356 bottom.insert(bottom.end(), src.begin(), right_top + 1);
357 top.assign(right_top, left_bottom + 1);
358 }
359 // Remove strictly vertical segments at the end.
360 if (bottom.size() > 1) {
361 auto it = bottom.end();
362 for (-- it; it != bottom.begin() && (it - 1)->x() == bottom.back().x(); -- it) ;
363 bottom.erase(it + 1, bottom.end());
364 }
365 if (top.size() > 1) {
366 auto it = top.end();
367 for (-- it; it != top.begin() && (it - 1)->x() == top.back().x(); -- it) ;
368 top.erase(it + 1, top.end());
369 }
370 std::reverse(top.begin(), top.end());
371 }
372
373 if (top.size() < 2 || bottom.size() < 2) {
374 // invalid
375 top.clear();
376 bottom.clear();
377 }
378 return out;
379}
TCoord< P > x(const P &p)
Definition geometry_traits.hpp:297

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

+ Here is the caller graph for this function:

◆ deg2rad()

◆ dir_to_spheric()

template<class Tout = double, class Tin >
std::pair< Tout, Tout > Slic3r::Geometry::dir_to_spheric ( const Vec< 3, Tin > &  n,
Tout  norm = 1. 
)
510{
511 Tout z = n.z();
512 Tout r = norm;
513 Tout polar = std::acos(z / r);
514 Tout azimuth = std::atan2(n(1), n(0));
515 return {polar, azimuth};
516}

References dir_to_spheric().

Referenced by dir_to_spheric().

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

◆ directions_parallel()

bool Slic3r::Geometry::directions_parallel ( double  angle1,
double  angle2,
double  max_diff 
)
30{
31 double diff = fabs(angle1 - angle2);
32 max_diff += EPSILON;
33 return diff < max_diff || fabs(diff - PI) < max_diff;
34}
Slic3r::Polygons diff(const Slic3r::Polygon &subject, const Slic3r::Polygon &clip, ApplySafetyOffset do_safety_offset)
Definition ClipperUtils.cpp:672

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 
)
37{
38 double diff = fabs(angle1 - angle2);
39 max_diff += EPSILON;
40 return fabs(diff - 0.5 * PI) < max_diff || fabs(diff - 1.5 * PI) < max_diff;
41}

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 
)
281{
282 T dx = p2(0) - p1(0);
283 T dy = p2(1) - p1(1);
284 return sqrt(dx*dx+dy*dy);
285}
EIGEN_DEVICE_FUNC const SqrtReturnType sqrt() const
Definition ArrayCwiseUnaryOps.h:152

References sqrt().

Referenced by arrange(), Slic3r::GUI::get_arrange_params(), measure_edge_thickness(), Slic3r::GUI::CommonGizmosDataObjects::ObjectClipper::set_position_by_ratio(), and Slic3r::GUI::GLGizmoCut3D::update_clipper().

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

◆ extract_rotation() [1/2]

Vec3d Slic3r::Geometry::extract_rotation ( const Eigen::Matrix< double, 3, 3, Eigen::DontAlign > &  rotation_matrix)
378{
379 // The extracted "rotation" is a triplet of numbers such that Geometry::rotation_transform
380 // returns the original transform. Because of the chosen order of rotations, the triplet
381 // is not equivalent to Euler angles in the usual sense.
382 Vec3d angles = rotation_matrix.eulerAngles(2,1,0);
383 std::swap(angles(0), angles(2));
384 return angles;
385}

Referenced by extract_rotation(), Slic3r::Geometry::Transformation::get_rotation(), and Slic3r::Geometry::Transformation::set_rotation().

+ Here is the caller graph for this function:

◆ extract_rotation() [2/2]

Vec3d Slic3r::Geometry::extract_rotation ( const Transform3d transform)
388{
389 // use only the non-translational part of the transform
390 Eigen::Matrix<double, 3, 3, Eigen::DontAlign> m = transform.matrix().block(0, 0, 3, 3);
391 // remove scale
392 m.col(0).normalize();
393 m.col(1).normalize();
394 m.col(2).normalize();
395 return extract_rotation(m);
396}
Vec3d extract_rotation(const Eigen::Matrix< double, 3, 3, Eigen::DontAlign > &rotation_matrix)
Definition Geometry.cpp:377

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

+ Here is the call graph for this function:

◆ extract_rotation_matrix()

static Transform3d Slic3r::Geometry::extract_rotation_matrix ( const Transform3d trafo)
static
404{
405 Matrix3d rotation;
407 trafo.computeRotationScaling(&rotation, &scale);
408 return Transform3d(rotation);
409}

References Eigen::Transform< _Scalar, _Dim, _Mode, _Options >::computeRotationScaling(), and 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()

static std::pair< Transform3d, Transform3d > Slic3r::Geometry::extract_rotation_scale ( const Transform3d trafo)
static
420{
421 Matrix3d rotation;
423 trafo.computeRotationScaling(&rotation, &scale);
424 return { Transform3d(rotation), Transform3d(scale) };
425}

References Eigen::Transform< _Scalar, _Dim, _Mode, _Options >::computeRotationScaling(), and scale().

Referenced by 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()

static Transform3d Slic3r::Geometry::extract_scale ( const Transform3d trafo)
static
412{
413 Matrix3d rotation;
415 trafo.computeRotationScaling(&rotation, &scale);
416 return Transform3d(scale);
417}

References Eigen::Transform< _Scalar, _Dim, _Mode, _Options >::computeRotationScaling(), and scale().

Referenced by 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 
)
210 {
211 return fit_curve<CubicCatmulRomKernel<NumberType>>(observations, observation_points, weights, segments_count,
212 endpoints_level_of_freedom);
213}

◆ 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 
)
198 {
199 return fit_curve<CubicBSplineKernel<NumberType>>(observations, observation_points, weights, segments_count,
200 endpoints_level_of_freedom);
201}

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

References floor(), segment(), and sqrt().

+ Here is the call 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 
)
186 {
187 return fit_curve<LinearKernel<NumberType>>(observations, observation_points, weights, segments_count,
188 endpoints_level_of_freedom);
189}

◆ 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 
)
32 {
33 // check to make sure inputs are correct
34 size_t cols = order + 1;
35 assert(observation_points.size() >= cols);
36 assert(observation_points.size() == weights.size());
37 assert(observations.size() == weights.size());
38
39 Eigen::MatrixXf data_points(Dimension, observations.size());
40 Eigen::MatrixXf T(observations.size(), cols);
41 for (size_t i = 0; i < weights.size(); ++i) {
42 auto squared_weight = sqrt(weights[i]);
43 data_points.col(i) = observations[i] * squared_weight;
44 // Populate the matrix
45 auto x = squared_weight;
46 auto c = observation_points[i];
47 for (size_t j = 0; j < cols; ++j, x *= c)
48 T(i, j) = x;
49 }
50
51 const auto QR = T.householderQr();
52 Eigen::MatrixXf coefficients(Dimension, cols);
53 // Solve for linear least square fit
54 for (size_t dim = 0; dim < Dimension; ++dim) {
55 coefficients.row(dim) = QR.solve(data_points.row(dim).transpose());
56 }
57
58 return {std::move(coefficients)};
59}

References sqrt().

+ Here is the call graph for this function:

◆ foot_pt() [1/2]

Vec2d Slic3r::Geometry::foot_pt ( const Line iline,
const Point ipt 
)
inline
173{
174 return foot_pt<Vec2d>(iline.a.cast<double>(), (iline.b - iline.a).cast<double>(), ipt.cast<double>());
175}
Point b
Definition Line.hpp:198
Point a
Definition Line.hpp:197

References Slic3r::Line::a, and Slic3r::Line::b.

◆ foot_pt() [2/2]

template<typename T >
T Slic3r::Geometry::foot_pt ( const T &  line_pt,
const T &  line_dir,
const T &  pt 
)
inline
165{
166 T v = pt - line_pt;
167 auto l2 = line_dir.squaredNorm();
168 auto t = (l2 == 0) ? 0 : v.dot(line_dir) / l2;
169 return line_pt + line_dir * t;
170}
T l2(const boost::geometry::model::d2::point_xy< T > &v)
Definition ExtrusionSimulator.cpp:166

References Slic3r::l2().

Referenced by Slic3r::Voronoi::detail::line_point_equal_distance_points(), Slic3r::Voronoi::detail::point_segment_dr_dl_thresholds(), Slic3r::Voronoi::detail::point_segment_skeleton_thresholds(), 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:

◆ get_parabolic_segment()

static ParabolicSegment Slic3r::Geometry::get_parabolic_segment ( const VD::edge_type &  edge,
const std::vector< VoronoiUtils::Segment > &  segments 
)
inlinestatic
178{
179 assert(edge.is_curved());
180
181 const VD::cell_type *left_cell = edge.cell();
182 const VD::cell_type *right_cell = edge.twin()->cell();
183
184 const Point focus_pt = VoronoiUtils::getSourcePoint(*(left_cell->contains_point() ? left_cell : right_cell), segments);
185 const VoronoiUtils::Segment &directrix = VoronoiUtils::getSourceSegment(*(left_cell->contains_point() ? right_cell : left_cell), segments);
186 CGAL::Orientation focus_side = CGAL::opposite(CGAL::orientation(to_cgal_point(edge.vertex0()), to_cgal_point(edge.vertex1()), to_cgal_point(focus_pt)));
187
188 assert(focus_side == CGAL::Orientation::LEFT_TURN || focus_side == CGAL::Orientation::RIGHT_TURN);
189 return {focus_pt, Line(directrix.from(), directrix.to()), make_linef(edge), focus_side};
190}
Definition PolygonsSegmentIndex.hpp:18
Point to() const
Definition PolygonsSegmentIndex.hpp:25
Point from() const
Definition PolygonsSegmentIndex.hpp:23
static Point getSourcePoint(const vd_t::cell_type &cell, const std::vector< Segment > &segments)
Definition VoronoiUtils.cpp:24
static const Segment & getSourceSegment(const vd_t::cell_type &cell, const std::vector< Segment > &segments)
Definition VoronoiUtils.cpp:81
Definition Line.hpp:155
static CGAL_Point to_cgal_point(const VD::vertex_type *pt)
Definition VoronoiUtilsCgal.cpp:120
static Linef make_linef(const VD::edge_type &edge)
Definition VoronoiUtilsCgal.cpp:124

References Slic3r::Arachne::PolygonsSegmentIndex::from(), Slic3r::Arachne::VoronoiUtils::getSourcePoint(), Slic3r::Arachne::VoronoiUtils::getSourceSegment(), make_linef(), Slic3r::Arachne::PolygonsSegmentIndex::to(), 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 
)
383{
384 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(); });
385 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(); });
386 if (it_bottom == top_bottom_decomposition.first.end()) {
387 // Above max x.
388 assert(it_top == top_bottom_decomposition.second.end());
389 return false;
390 }
391 if (it_bottom == top_bottom_decomposition.first.begin()) {
392 // Below or at min x.
393 if (pt.x() < it_bottom->x()) {
394 // Below min x.
395 assert(pt.x() < it_top->x());
396 return false;
397 }
398 // At min x.
399 assert(pt.x() == it_bottom->x());
400 assert(pt.x() == it_top->x());
401 assert(it_bottom->y() <= pt.y() && pt.y() <= it_top->y());
402 return pt.y() >= it_bottom->y() && pt.y() <= it_top->y();
403 }
404
405 // Trapezoid or a triangle.
406 assert(it_bottom != top_bottom_decomposition.first .begin() && it_bottom != top_bottom_decomposition.first .end());
407 assert(it_top != top_bottom_decomposition.second.begin() && it_top != top_bottom_decomposition.second.end());
408 assert(pt.x() <= it_bottom->x());
409 assert(pt.x() <= it_top->x());
410 auto it_top_prev = it_top - 1;
411 auto it_bottom_prev = it_bottom - 1;
412 assert(pt.x() >= it_top_prev->x());
413 assert(pt.x() >= it_bottom_prev->x());
414 double det = cross2(*it_bottom - *it_bottom_prev, pt - *it_bottom_prev);
415 if (det < 0)
416 return false;
417 det = cross2(*it_top - *it_top_prev, pt - *it_top_prev);
418 return det <= 0;
419}
Derived::Scalar cross2(const Eigen::MatrixBase< Derived > &v1, const Eigen::MatrixBase< Derived2 > &v2)
Definition Point.hpp:93

References Slic3r::cross2().

Referenced by Slic3r::BuildVolume::all_paths_inside_vertices_and_normals_interleaved(), and Slic3r::BuildVolume::object_state().

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

◆ is_ccw()

static bool Slic3r::Geometry::is_ccw ( const Polygon poly)
inlinestatic
45{
46 // The polygon shall be at least a triangle.
47 assert(poly.points.size() >= 3);
48 if (poly.points.size() < 3)
49 return true;
50
51 // 1) Find the lowest lexicographical point.
52 unsigned int imin = 0;
53 for (unsigned int i = 1; i < poly.points.size(); ++ i) {
54 const Point &pmin = poly.points[imin];
55 const Point &p = poly.points[i];
56 if (p(0) < pmin(0) || (p(0) == pmin(0) && p(1) < pmin(1)))
57 imin = i;
58 }
59
60 // 2) Detect the orientation of the corner imin.
61 size_t iPrev = ((imin == 0) ? poly.points.size() : imin) - 1;
62 size_t iNext = ((imin + 1 == poly.points.size()) ? 0 : imin + 1);
63 Orientation o = orient(poly.points[iPrev], poly.points[imin], poly.points[iNext]);
64 // The lowest bottom point must not be collinear if the polygon does not contain duplicate points
65 // or overlapping segments.
66 assert(o != ORIENTATION_COLINEAR);
67 return o == ORIENTATION_CCW;
68}

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

Referenced by Slic3r::ExPolygonWithOffset::ExPolygonWithOffset().

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

◆ is_equal()

static bool Slic3r::Geometry::is_equal ( const VD::vertex_type &  first,
const VD::vertex_type &  second 
)
inlinestatic
131{ return first.x() == second.x() && first.y() == second.y(); }

Referenced by check_if_three_edges_are_ccw(), and orientation_of_two_edges().

+ 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
497{
498 return is_rotation_ninety_degrees(rotation.x()) && is_rotation_ninety_degrees(rotation.y()) && is_rotation_ninety_degrees(rotation.z());
499}
bool is_rotation_ninety_degrees(double a)
Definition Geometry.hpp:487

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
488{
489 a = fmod(std::abs(a), 0.5 * PI);
490 if (a > 0.25 * PI)
491 a = 0.5 * PI - a;
492 return a < 0.001;
493}

References PI.

Referenced by Slic3r::GUI::Selection::bake_transform_if_needed(), and is_rotation_ninety_degrees().

+ 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 
)
279{
280 x0clip = x0src;
281 x1clip = x1src;
282 return liang_barsky_line_clipping(x0clip, x1clip, bbox);
283}
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:250

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
256{
258 std::pair<double, double> interval;
259 if (liang_barsky_line_clipping_interval(x0, v, bbox, interval)) {
260 // Clipped successfully.
261 x1 = x0 + interval.second * v;
262 x0 += interval.first * v;
263 return true;
264 }
265 return false;
266}
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:199

References liang_barsky_line_clipping_interval().

Referenced by liang_barsky_line_clipping(), 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
206{
207 double t0 = 0.0;
208 double t1 = 1.0;
209 // Traverse through left, right, bottom, top edges.
210 auto clip_side = [&t0, &t1](double p, double q) -> bool {
211 if (p == 0) {
212 if (q < 0)
213 // Line parallel to the bounding box edge is fully outside of the bounding box.
214 return false;
215 // else don't clip
216 } else {
217 double r = q / p;
218 if (p < 0) {
219 if (r > t1)
220 // Fully clipped.
221 return false;
222 if (r > t0)
223 // Partially clipped.
224 t0 = r;
225 } else {
226 assert(p > 0);
227 if (r < t0)
228 // Fully clipped.
229 return false;
230 if (r < t1)
231 // Partially clipped.
232 t1 = r;
233 }
234 }
235 return true;
236 };
237
238 if (clip_side(- v.x(), - bbox.min.x() + x0.x()) &&
239 clip_side( v.x(), bbox.max.x() - x0.x()) &&
240 clip_side(- v.y(), - bbox.min.y() + x0.y()) &&
241 clip_side( v.y(), bbox.max.y() - x0.y())) {
242 out_interval.first = t0;
243 out_interval.second = t1;
244 return true;
245 }
246 return false;
247}
PointType max
Definition BoundingBox.hpp:17

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 
)
67{
68 return (value - oldmin) * (newmax - newmin) / (oldmax - oldmin) + newmin;
69}

Referenced by arrange().

+ Here is the caller graph for this function:

◆ make_linef()

static Linef Slic3r::Geometry::make_linef ( const VD::edge_type &  edge)
inlinestatic
125{
126 const VD::vertex_type *v0 = edge.vertex0();
127 const VD::vertex_type *v1 = edge.vertex1();
128 return {Vec2d(v0->x(), v0->y()), Vec2d(v1->x(), v1->y())};
129}

Referenced by get_parabolic_segment().

+ 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
397{
398 typedef typename VD::coord_type T;
399 const typename VD::point_type pa(edge.vertex0()->x(), edge.vertex0()->y());
400 const typename VD::point_type pb(edge.vertex1()->x(), edge.vertex1()->y());
401 const typename VD::cell_type &cell1 = *edge.cell();
402 const typename VD::cell_type &cell2 = *edge.twin()->cell();
403 if (cell1.contains_segment()) {
404 if (cell2.contains_segment()) {
405 // Both cells contain a linear segment, the left / right cells are symmetric.
406 // Project pa, pb to the left segment.
407 const typename VD::segment_type segment1 = segments[cell1.source_index()];
408 const typename VD::point_type p1a = project_point_to_segment(segment1, pa);
409 const typename VD::point_type p1b = project_point_to_segment(segment1, pb);
410 return std::pair<T, T>(T(2.)*dist(pa, p1a), T(2.)*dist(pb, p1b));
411 } else {
412 // 1st cell contains a linear segment, 2nd cell contains a point.
413 // The medial axis between the cells is a parabolic arc.
414 // Project pa, pb to the left segment.
415 const typename VD::point_type p2 = retrieve_cell_point<VD>(cell2, segments);
416 return std::pair<T, T>(T(2.)*dist(pa, p2), T(2.)*dist(pb, p2));
417 }
418 } else if (cell2.contains_segment()) {
419 // 1st cell contains a point, 2nd cell contains a linear segment.
420 // The medial axis between the cells is a parabolic arc.
421 const typename VD::point_type p1 = retrieve_cell_point<VD>(cell1, segments);
422 return std::pair<T, T>(T(2.)*dist(pa, p1), T(2.)*dist(pb, p1));
423 } else {
424 // Both cells contain a point. The left / right regions are triangular and symmetric.
425 const typename VD::point_type p1 = retrieve_cell_point<VD>(cell1, segments);
426 return std::pair<T, T>(T(2.)*dist(pa, p1), T(2.)*dist(pb, p1));
427 }
428}
double coord_type
Definition Voronoi.hpp:25
boost::polygon::point_data< coordinate_type > point_type
Definition Voronoi.hpp:26
boost::polygon::segment_data< coordinate_type > segment_type
Definition Voronoi.hpp:27
point_type project_point_to_segment(segment_type &seg, point_type &px)
Definition Geometry.cpp:289

References dist(), and project_point_to_segment().

+ Here is the call graph for this function:

◆ orient()

static Orientation Slic3r::Geometry::orient ( const Point a,
const Point b,
const Point c 
)
inlinestatic
32{
33 static_assert(sizeof(coord_t) * 2 == sizeof(int64_t), "orient works with 32 bit coordinates");
34 int64_t u = int64_t(b.x()) * int64_t(c.y()) - int64_t(b.y()) * int64_t(c.x());
35 int64_t v = int64_t(a.x()) * int64_t(c.y()) - int64_t(a.y()) * int64_t(c.x());
36 int64_t w = int64_t(a.x()) * int64_t(b.y()) - int64_t(a.y()) * int64_t(b.x());
37 int64_t d = u - v + w;
38 return (d > 0) ? ORIENTATION_CCW : ((d == 0) ? ORIENTATION_COLINEAR : ORIENTATION_CW);
39}
int32_t coord_t
Definition libslic3r.h:39
__int64 int64_t
Definition unistd.h:76

References ORIENTATION_CCW, ORIENTATION_COLINEAR, and ORIENTATION_CW.

Referenced by convex_hull(), convex_hull(), and is_ccw().

+ Here is the caller graph for this function:

◆ orientation_of_two_edges()

static CGAL::Orientation Slic3r::Geometry::orientation_of_two_edges ( const VD::edge_type &  edge_a,
const VD::edge_type &  edge_b,
const std::vector< VoronoiUtils::Segment > &  segments 
)
inlinestatic
192 {
193 assert(is_equal(*edge_a.vertex0(), *edge_b.vertex0()));
194 CGAL::Orientation orientation;
195 if (edge_a.is_linear() && edge_b.is_linear()) {
196 orientation = CGAL::orientation(to_cgal_point(edge_a.vertex0()), to_cgal_point(edge_a.vertex1()), to_cgal_point(edge_b.vertex1()));
197 } else if (edge_a.is_curved() && edge_b.is_curved()) {
198 const ParabolicSegment parabolic_a = get_parabolic_segment(edge_a, segments);
199 const ParabolicSegment parabolic_b = get_parabolic_segment(edge_b, segments);
200 orientation = ParabolicTangentToParabolicTangentOrientation{}(to_cgal_point(parabolic_a.segment.a),
201 to_cgal_point(parabolic_a.focus),
202 to_cgal_point(parabolic_a.directrix.a),
203 to_cgal_point(parabolic_a.directrix.b),
204 parabolic_a.is_focus_on_left,
205 to_cgal_point(parabolic_b.focus),
206 to_cgal_point(parabolic_b.directrix.a),
207 to_cgal_point(parabolic_b.directrix.b),
208 parabolic_b.is_focus_on_left);
209 return orientation;
210 } else {
211 assert(edge_a.is_curved() != edge_b.is_curved());
212
213 const VD::edge_type &linear_edge = edge_a.is_curved() ? edge_b : edge_a;
214 const VD::edge_type &parabolic_edge = edge_a.is_curved() ? edge_a : edge_b;
215 const ParabolicSegment parabolic = get_parabolic_segment(parabolic_edge, segments);
216 orientation = ParabolicTangentToSegmentOrientation{}(to_cgal_point(parabolic.segment.a), to_cgal_point(linear_edge.vertex1()),
217 to_cgal_point(parabolic.focus),
218 to_cgal_point(parabolic.directrix.a),
219 to_cgal_point(parabolic.directrix.b),
220 parabolic.is_focus_on_left);
221
222 if (edge_b.is_curved())
223 orientation = CGAL::opposite(orientation);
224 }
225
226 return orientation;
227}
impl::ParabolicTangentToSegmentOrientationPredicateFiltered ParabolicTangentToSegmentOrientation
Definition VoronoiUtilsCgal.cpp:116
static ParabolicSegment get_parabolic_segment(const VD::edge_type &edge, const std::vector< VoronoiUtils::Segment > &segments)
Definition VoronoiUtilsCgal.cpp:177

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
290{
291 typedef typename point_type::coordinate_type T;
292 const point_type &p0 = low(seg);
293 const point_type &p1 = high(seg);
294 const point_type dir(p1(0)-p0(0), p1(1)-p0(1));
295 const point_type dproj(px(0)-p0(0), px(1)-p0(1));
296 const T t = (dir(0)*dproj(0) + dir(1)*dproj(1)) / (dir(0)*dir(0) + dir(1)*dir(1));
297 assert(t >= T(-1e-6) && t <= T(1. + 1e-6));
298 return point_type(p0(0) + t*dir(0), p0(1) + t*dir(1));
299}

Referenced by measure_edge_thickness().

+ Here is the caller graph for this function:

◆ rad2deg()

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

References Slic3r::angle(), and PI.

Referenced by Slic3r::BridgeDetector::detect_angle(), Slic3r::GUI::Camera::get_fov(), Slic3r::GUI::GLGizmoCut3D::get_tooltip(), Slic3r::GUI::GLGizmoRotate::get_tooltip(), Slic3r::GUI::GLGizmoMeasure::on_render_input_window(), Slic3r::GUI::Plater::priv::on_wipetower_rotated(), Slic3r::GUI::GLGizmoMeasure::render_dimensioning(), Slic3r::TriangleMesh::rotate(), Slic3r::GUI::Camera::rotate_on_sphere(), and Slic3r::GUI::Camera::update_zenit().

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

◆ ray_circle_intersections()

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

References SCALED_EPSILON.

◆ ray_circle_intersections_r2_lv2_c()

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

References sqrt().

Referenced by Slic3r::line_rounded_thick_segment_collision().

+ Here is the call graph for this function:
+ 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
193{
194 return (foot_pt(iline, ipt) - ipt.cast<double>()).norm();
195}
T foot_pt(const T &line_pt, const T &line_dir, const T &pt)
Definition Geometry.hpp:164

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
183{
184 return (foot_pt(ray_pt, ray_dir, pt) - pt).norm();
185}

References foot_pt().

+ Here is the call graph for this function:

◆ ray_point_distance_squared() [1/2]

double Slic3r::Geometry::ray_point_distance_squared ( const Line iline,
const Point ipt 
)
inline
188{
189 return (foot_pt(iline, ipt) - ipt.cast<double>()).squaredNorm();
190}

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
178{
179 return (foot_pt(ray_pt, ray_dir, pt) - pt).squaredNorm();
180}

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
71{
72 double denom = v1(0) * v2(1) - v2(0) * v1(1);
73 if (std::abs(denom) < EPSILON)
74 return false;
75 double t = (v2(0) * (p1(1) - p2(1)) - v2(1) * (p1(0) - p2(0))) / denom;
76 res(0) = p1(0) + t * v1(0);
77 res(1) = p1(1) + t * v1(1);
78 return true;
79}

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
390{
391 assert(cell.source_category() == boost::polygon::SOURCE_CATEGORY_SEGMENT_START_POINT || cell.source_category() == boost::polygon::SOURCE_CATEGORY_SEGMENT_END_POINT);
392 return (cell.source_category() == boost::polygon::SOURCE_CATEGORY_SEGMENT_START_POINT) ? low(segments[cell.source_index()]) : high(segments[cell.source_index()]);
393}

◆ rotation_diff_z()

double Slic3r::Geometry::rotation_diff_z ( const Transform3d trafo_from,
const Transform3d trafo_to 
)
713{
714 auto m = trafo_to.linear() * trafo_from.linear().inverse();
715 assert(std::abs(m.determinant() - 1) < EPSILON);
716 Vec3d vx = m * Vec3d(1., 0., 0);
717 // Verify that the linear part of rotation from trafo_from to trafo_to rotates around Z and is unity.
718 assert(std::abs(std::hypot(vx.x(), vx.y()) - 1.) < 1e-5);
719 assert(std::abs(vx.z()) < 1e-5);
720 return atan2(vx.y(), vx.x());
721}
EIGEN_DEVICE_FUNC ConstLinearPart linear() const
Definition Transform.h:400

References EPSILON, and Eigen::Transform< _Scalar, _Dim, _Mode, _Options >::linear().

Referenced by Slic3r::PrintObject::PrintObject(), Slic3r::Print::sequential_print_horizontal_clearance_valid(), Slic3r::sla_instances(), and Slic3r::GUI::GLCanvas3D::update_sequential_clearance().

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

◆ rotation_transform() [1/2]

Transform3d Slic3r::Geometry::rotation_transform ( const Vec3d rotation)
348{
349 Transform3d transform;
350 rotation_transform(transform, rotation);
351 return transform;
352}
void rotation_transform(Transform3d &transform, const Vec3d &rotation)
Definition Geometry.cpp:341

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 
)
342{
343 transform = Transform3d::Identity();
344 transform.rotate(Eigen::AngleAxisd(rotation.z(), Vec3d::UnitZ()) * Eigen::AngleAxisd(rotation.y(), Vec3d::UnitY()) * Eigen::AngleAxisd(rotation.x(), Vec3d::UnitX()));
345}

References Eigen::Transform< double, 3, Eigen::Affine, Eigen::DontAlign >::Identity(), and Slic3r::transform().

Referenced by Slic3r::GUI::GLCanvas3D::_render_sla_slices(), Slic3r::GUI::GLGizmoCut3D::dragging_grabber_xy(), Slic3r::GUI::GLGizmoCut3D::flip_cut_plane(), Slic3r::GUI::GLGizmoRotate::local_transform(), Slic3r::GUI::CoordAxes::render(), Slic3r::GUI::GLGizmoBase::Grabber::render(), Slic3r::GUI::GLGizmoCut3D::render_cut_plane_grabbers(), Slic3r::GUI::GLGizmoSlaSupports::render_points(), Slic3r::GUI::GLGizmoCut3D::render_rotation_snapping(), Slic3r::GUI::Selection::render_sidebar_position_hints(), Slic3r::GUI::Selection::render_sidebar_rotation_hints(), Slic3r::GUI::Selection::render_sidebar_scale_hints(), Slic3r::GUI::Selection::rotate(), rotation_transform(), Slic3r::Geometry::Transformation::set_rotation(), Slic3r::Geometry::Transformation::set_rotation(), Slic3r::GUI::GCodeViewer::SequentialView::Marker::set_world_position(), Slic3r::GUI::GLGizmoCut3D::update_raycasters_for_picking_transform(), and Slic3r::GUI::GLCanvas3D::update_sequential_clearance().

+ 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 
)
703{
704 return
705 // From the current coordinate system to world.
706 Eigen::AngleAxisd(rot_xyz_to.z(), Vec3d::UnitZ()) * Eigen::AngleAxisd(rot_xyz_to.y(), Vec3d::UnitY()) * Eigen::AngleAxisd(rot_xyz_to.x(), Vec3d::UnitX()) *
707 // From world to the initial coordinate system.
708 Eigen::AngleAxisd(-rot_xyz_from.x(), Vec3d::UnitX()) * Eigen::AngleAxisd(-rot_xyz_from.y(), Vec3d::UnitY()) * Eigen::AngleAxisd(-rot_xyz_from.z(), Vec3d::UnitZ());
709}
AngleAxis< double > AngleAxisd
Definition AngleAxis.h:160

Referenced by Slic3r::GUI::is_rotation_xy_synchronized().

+ Here is the caller graph for this function:

◆ scale_transform() [1/4]

Transform3d Slic3r::Geometry::scale_transform ( const Vec3d scale)
371{
372 Transform3d transform;
373 scale_transform(transform, scale);
374 return transform;
375}
void scale_transform(Transform3d &transform, double scale)
Definition Geometry.cpp:354

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)
366{
367 return scale_transform(scale * Vec3d::Ones());
368}

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 
)
360{
361 transform = Transform3d::Identity();
362 transform.scale(scale);
363}

References Eigen::Transform< double, 3, Eigen::Affine, Eigen::DontAlign >::Identity(), scale(), Slic3r::Linef3::scale(), and Slic3r::transform().

+ Here is the call graph for this function:

◆ scale_transform() [4/4]

void Slic3r::Geometry::scale_transform ( Transform3d transform,
double  scale 
)
355{
356 return scale_transform(transform, scale * Vec3d::Ones());
357}

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

Referenced by Slic3r::GUI::GLCanvas3D::_render_sla_slices(), Slic3r::GUI::GLGizmoCut3D::is_conflict_for_connector(), Slic3r::GUI::GCodeViewer::load_toolpaths(), Slic3r::GUI::GLGizmoMeasure::on_render(), Slic3r::GUI::GCodeViewer::COG::render(), Slic3r::GUI::GLGizmoBase::Grabber::render(), Slic3r::GUI::GLGizmoCut3D::render_connectors(), Slic3r::GUI::GLGizmoPainterBase::render_cursor_circle(), Slic3r::GUI::GLGizmoPainterBase::render_cursor_sphere(), Slic3r::GUI::GLGizmoCut3D::render_cut_plane_grabbers(), Slic3r::GUI::GLGizmoMeasure::render_dimensioning(), Slic3r::GUI::GLGizmoCut3D::render_grabber_connection(), Slic3r::GUI::GLGizmoHollow::render_points(), Slic3r::GUI::GLGizmoSlaSupports::render_points(), Slic3r::Geometry::Transformation::reset_skew(), Slic3r::GUI::Selection::scale_and_translate(), scale_transform(), scale_transform(), scale_transform(), Slic3r::Geometry::Transformation::set_scaling_factor(), Slic3r::GUI::GLGizmoHollow::update_hole_raycasters_for_picking_transform(), Slic3r::GUI::GLGizmoFlatten::update_planes(), Slic3r::GUI::GLGizmoSlaSupports::update_point_raycasters_for_picking_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:

◆ segment_segment_intersection()

bool Slic3r::Geometry::segment_segment_intersection ( const Vec2d p1,
const Vec2d v1,
const Vec2d p2,
const Vec2d v2,
Vec2d res 
)
inline
82{
83 double denom = v1(0) * v2(1) - v2(0) * v1(1);
84 if (std::abs(denom) < EPSILON)
85 // Lines are collinear.
86 return false;
87 double s12_x = p1(0) - p2(0);
88 double s12_y = p1(1) - p2(1);
89 double s_numer = v1(0) * s12_y - v1(1) * s12_x;
90 bool denom_is_positive = false;
91 if (denom < 0.) {
92 denom_is_positive = true;
93 denom = - denom;
94 s_numer = - s_numer;
95 }
96 if (s_numer < 0.)
97 // Intersection outside of the 1st segment.
98 return false;
99 double t_numer = v2(0) * s12_y - v2(1) * s12_x;
100 if (! denom_is_positive)
101 t_numer = - t_numer;
102 if (t_numer < 0. || s_numer > denom || t_numer > denom)
103 // Intersection outside of the 1st or 2nd segment.
104 return false;
105 // Intersection inside both of the segments.
106 double t = t_numer / denom;
107 res(0) = p1(0) + t * v1(0);
108 res(1) = p1(1) + t * v1(1);
109 return true;
110}

References EPSILON.

◆ segments_intersect()

bool Slic3r::Geometry::segments_intersect ( const Slic3r::Point ip1,
const Slic3r::Point ip2,
const Slic3r::Point jp1,
const Slic3r::Point jp2 
)
inline
115{
116 assert(ip1 != ip2);
117 assert(jp1 != jp2);
118
119 auto segments_could_intersect = [](
120 const Slic3r::Point &ip1, const Slic3r::Point &ip2,
121 const Slic3r::Point &jp1, const Slic3r::Point &jp2) -> std::pair<int, int>
122 {
123 Vec2i64 iv = (ip2 - ip1).cast<int64_t>();
124 Vec2i64 vij1 = (jp1 - ip1).cast<int64_t>();
125 Vec2i64 vij2 = (jp2 - ip1).cast<int64_t>();
126 int64_t tij1 = cross2(iv, vij1);
127 int64_t tij2 = cross2(iv, vij2);
128 return std::make_pair(
129 // signum
130 (tij1 > 0) ? 1 : ((tij1 < 0) ? -1 : 0),
131 (tij2 > 0) ? 1 : ((tij2 < 0) ? -1 : 0));
132 };
133
134 std::pair<int, int> sign1 = segments_could_intersect(ip1, ip2, jp1, jp2);
135 std::pair<int, int> sign2 = segments_could_intersect(jp1, jp2, ip1, ip2);
136 int test1 = sign1.first * sign1.second;
137 int test2 = sign2.first * sign2.second;
138 if (test1 <= 0 && test2 <= 0) {
139 // The segments possibly intersect. They may also be collinear, but not intersect.
140 if (test1 != 0 || test2 != 0)
141 // Certainly not collinear, then the segments intersect.
142 return true;
143 // If the first segment is collinear with the other, the other is collinear with the first segment.
144 assert((sign1.first == 0 && sign1.second == 0) == (sign2.first == 0 && sign2.second == 0));
145 if (sign1.first == 0 && sign1.second == 0) {
146 // The segments are certainly collinear. Now verify whether they overlap.
147 Slic3r::Point vi = ip2 - ip1;
148 // Project both on the longer coordinate of vi.
149 int axis = std::abs(vi.x()) > std::abs(vi.y()) ? 0 : 1;
150 coord_t i = ip1(axis);
151 coord_t j = ip2(axis);
152 coord_t k = jp1(axis);
153 coord_t l = jp2(axis);
154 if (i > j)
155 std::swap(i, j);
156 if (k > l)
157 std::swap(k, l);
158 return (k >= i && k <= j) || (i >= k && i <= l);
159 }
160 }
161 return false;
162}

References Slic3r::cross2().

Referenced by Slic3r::EdgeGrid::Grid::has_intersecting_edges(), Slic3r::EdgeGrid::Grid::intersecting_edges(), and Slic3r::FirstIntersectionVisitor::operator()().

+ 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 
)
54{
55 Polygons simplified_raw;
56 for (const Polygon &source_polygon : polygons) {
57 Points simplified = MultiPoint::douglas_peucker(to_polyline(source_polygon).points, tolerance);
58 if (simplified.size() > 3) {
59 simplified.pop_back();
60 simplified_raw.push_back(Polygon{ std::move(simplified) });
61 }
62 }
63 *retval = Slic3r::simplify_polygons(simplified_raw);
64}
std::vector< Polygon, PointsAllocator< Polygon > > Polygons
Definition Polygon.hpp:15
Polygons simplify_polygons(const Polygons &subject)
Definition ClipperUtils.cpp:969
Polyline to_polyline(const Polygon &polygon)
Definition Polygon.hpp:214

References Slic3r::MultiPoint::douglas_peucker(), Slic3r::simplify_polygons(), and Slic3r::to_polyline().

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 
)
110{
111 using Scalar = typename Vector::Scalar;
112 CircleSq<Vector> circle;
113
114 if (! points.empty()) {
115 const auto &p0 = points[0].template cast<Scalar>();
116 if (points.size() == 1) {
117 circle.center = p0;
118 circle.radius2 = epsilon * epsilon;
119 } else {
120 circle = CircleSq<Vector>(p0, points[1].template cast<Scalar>()).inflated(epsilon);
121 for (size_t i = 2; i < points.size(); ++ i)
122 if (const Vector &p = points[i].template cast<Scalar>(); ! circle.contains(p)) {
123 // p is the first point on the smallest circle enclosing points[0..i]
124 circle = CircleSq<Vector>(p0, p).inflated(epsilon);
125 for (size_t j = 1; j < i; ++ j)
126 if (const Vector &q = points[j].template cast<Scalar>(); ! circle.contains(q)) {
127 // q is the second point on the smallest circle enclosing points[0..i]
128 circle = CircleSq<Vector>(p, q).inflated(epsilon);
129 for (size_t k = 0; k < j; ++ k)
130 if (const Vector &r = points[k].template cast<Scalar>(); ! circle.contains(r))
131 circle = CircleSq<Vector>(p, q, r, epsilon).inflated(epsilon);
132 }
133 }
134 }
135 }
136
137 return circle;
138}
Definition Circle.hpp:35
bool contains(const Vector &p) const
Definition Circle.hpp:51
Vector center
Definition Circle.hpp:38
Scalar radius2
Definition Circle.hpp:39
CircleSq inflated(Scalar epsilon) const
Definition Circle.hpp:54

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

+ Here is the call graph for this function:

◆ smallest_enclosing_circle_welzl() [1/2]

Circled Slic3r::Geometry::smallest_enclosing_circle_welzl ( const Points points)
inline
149{
150 return smallest_enclosing_circle_welzl<Vec2d, Points>(points, SCALED_EPSILON);
151}

References SCALED_EPSILON.

◆ 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 
)
143{
144 return Circle<Vector>(smallest_enclosing_circle2_welzl<Vector, Points>(points, epsilon));
145}

Referenced by Slic3r::BuildVolume::BuildVolume(), and Slic3r::GUI::Selection::scale_to_fit_print_volume().

+ Here is the caller graph for this function:

◆ spheric_to_dir() [1/2]

template<class T = double, class Pair >
Vec< 3, T > Slic3r::Geometry::spheric_to_dir ( const Pair &  v)
527{
528 double plr = std::get<0>(v), azm = std::get<1>(v);
529 return spheric_to_dir<T>(plr, azm);
530}

References spheric_to_dir().

+ Here is the call graph for this function:

◆ spheric_to_dir() [2/2]

template<class T = double>
Vec< 3, T > Slic3r::Geometry::spheric_to_dir ( double  polar,
double  azimuth 
)
520{
521 return {T(std::cos(azimuth) * std::sin(polar)),
522 T(std::sin(azimuth) * std::sin(polar)), T(std::cos(polar))};
523}

References spheric_to_dir().

Referenced by spheric_to_dir(), and spheric_to_dir().

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

◆ to_cgal_point() [1/3]

static CGAL_Point Slic3r::Geometry::to_cgal_point ( const Point pt)
inlinestatic
121{ return {pt.x(), pt.y()}; }

◆ to_cgal_point() [2/3]

static CGAL_Point Slic3r::Geometry::to_cgal_point ( const VD::vertex_type *  pt)
inlinestatic
120{ 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]

static CGAL_Point Slic3r::Geometry::to_cgal_point ( const Vec2d pt)
inlinestatic
122{ return {pt.x(), pt.y()}; }

◆ trafos_differ_in_rotation_by_z_and_mirroring_by_xy_only() [1/2]

bool Slic3r::Geometry::trafos_differ_in_rotation_by_z_and_mirroring_by_xy_only ( const Transform3d t1,
const Transform3d t2 
)
724{
725 if (std::abs(t1.translation().z() - t2.translation().z()) > EPSILON)
726 // One of the object is higher than the other above the build plate (or below the build plate).
727 return false;
728 Matrix3d m1 = t1.matrix().block<3, 3>(0, 0);
729 Matrix3d m2 = t2.matrix().block<3, 3>(0, 0);
730 Matrix3d m = m2.inverse() * m1;
731 Vec3d z = m.block<3, 1>(0, 2);
732 if (std::abs(z.x()) > EPSILON || std::abs(z.y()) > EPSILON || std::abs(z.z() - 1.) > EPSILON)
733 // Z direction or length changed.
734 return false;
735 // Z still points in the same direction and it has the same length.
736 Vec3d x = m.block<3, 1>(0, 0);
737 Vec3d y = m.block<3, 1>(0, 1);
738 if (std::abs(x.z()) > EPSILON || std::abs(y.z()) > EPSILON)
739 return false;
740 double lx2 = x.squaredNorm();
741 double ly2 = y.squaredNorm();
742 if (lx2 - 1. > EPSILON * EPSILON || ly2 - 1. > EPSILON * EPSILON)
743 return false;
744 // Verify whether the vectors x, y are still perpendicular.
745 double d = x.dot(y);
746 return std::abs(d * d) < EPSILON * lx2 * ly2;
747}
EIGEN_DEVICE_FUNC ConstTranslationPart translation() const
Definition Transform.h:410

References EPSILON, Eigen::Transform< _Scalar, _Dim, _Mode, _Options >::matrix(), and Eigen::Transform< _Scalar, _Dim, _Mode, _Options >::translation().

Referenced by trafos_differ_in_rotation_by_z_and_mirroring_by_xy_only().

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

◆ trafos_differ_in_rotation_by_z_and_mirroring_by_xy_only() [2/2]

bool Slic3r::Geometry::trafos_differ_in_rotation_by_z_and_mirroring_by_xy_only ( const Transformation t1,
const Transformation t2 
)
inline
const Transform3d & get_matrix() const
Definition Geometry.hpp:437
bool trafos_differ_in_rotation_by_z_and_mirroring_by_xy_only(const Transform3d &t1, const Transform3d &t2)
Definition Geometry.cpp:723

References Slic3r::Geometry::Transformation::get_matrix(), and trafos_differ_in_rotation_by_z_and_mirroring_by_xy_only().

+ Here is the call graph for this function:

◆ transform3d_from_string()

Transform3d Slic3r::Geometry::transform3d_from_string ( const std::string &  transform_str)
680{
681 assert(is_decimal_separator_point()); // for atof
682 Transform3d transform = Transform3d::Identity();
683
684 if (!transform_str.empty()) {
685 std::vector<std::string> mat_elements_str;
686 boost::split(mat_elements_str, transform_str, boost::is_any_of(" "), boost::token_compress_on);
687
688 const unsigned int size = (unsigned int)mat_elements_str.size();
689 if (size == 16) {
690 unsigned int i = 0;
691 for (unsigned int r = 0; r < 4; ++r) {
692 for (unsigned int c = 0; c < 4; ++c) {
693 transform(r, c) = ::atof(mat_elements_str[i++].c_str());
694 }
695 }
696 }
697 }
698
699 return transform;
700}
void transform(ExPolygon &ep, const sla::RasterBase::Trafo &tr, const BoundingBox &bb)
Definition SL1_SVG.cpp:59
bool is_decimal_separator_point()
Definition LocalesUtils.cpp:47

References Eigen::Transform< double, 3, Eigen::Affine, Eigen::DontAlign >::Identity(), Slic3r::is_decimal_separator_point(), and Slic3r::transform().

Referenced by Slic3r::_3MF_Importer::_generate_volumes(), and Slic3r::AMFParserContext::endElement().

+ 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)
335{
336 Transform3d transform;
337 translation_transform(transform, translation);
338 return transform;
339}
void translation_transform(Transform3d &transform, const Vec3d &translation)
Definition Geometry.cpp:328

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 
)
329{
330 transform = Transform3d::Identity();
331 transform.translate(translation);
332}

References Eigen::Transform< double, 3, Eigen::Affine, Eigen::DontAlign >::Identity(), and Slic3r::transform().

Referenced by Slic3r::GUI::GLGizmoCut3D::PartSelection::PartSelection(), Slic3r::GUI::GLCanvas3D::_render_sla_slices(), Slic3r::GUI::GLGizmoCut3D::dragging_grabber_z(), Slic3r::GUI::GLGizmoCut3D::get_cut_matrix(), Slic3r::Geometry::Transformation::get_offset_matrix(), Slic3r::GUI::init_torus_data(), Slic3r::GUI::GLGizmoCut3D::is_conflict_for_connector(), Slic3r::GUI::GLGizmoCut3D::is_outside_of_cut_contour(), Slic3r::GUI::GCodeViewer::load_toolpaths(), Slic3r::GUI::GLGizmoMove3D::local_transform(), Slic3r::GUI::GLGizmoFlatten::on_register_raycasters_for_picking(), Slic3r::GUI::GLGizmoFlatten::on_render(), Slic3r::GUI::GLGizmoMeasure::on_render(), Slic3r::GUI::Plater::priv::reload_from_disk(), Slic3r::GLVolume::SinkingContours::render(), Slic3r::GUI::GCodeViewer::COG::render(), Slic3r::GUI::CoordAxes::render(), Slic3r::GUI::GLGizmoCut3D::PartSelection::render(), Slic3r::GUI::GLGizmoBase::Grabber::render(), Slic3r::GUI::GLGizmoCut3D::render_connectors(), Slic3r::GUI::GLGizmoPainterBase::render_cursor_circle(), Slic3r::GUI::GLGizmoPainterBase::render_cursor_sphere(), Slic3r::GUI::GLGizmoCut3D::render_cut_plane(), Slic3r::GUI::GLGizmoCut3D::render_cut_plane_grabbers(), Slic3r::GUI::GLGizmoMeasure::render_dimensioning(), Slic3r::GUI::Bed3D::render_model(), Slic3r::GUI::GLGizmoHollow::render_points(), Slic3r::GUI::GLGizmoSlaSupports::render_points(), Slic3r::GUI::GLGizmoCut3D::render_rotation_snapping(), Slic3r::GUI::Selection::render_sidebar_hints(), Slic3r::GUI::Selection::render_sidebar_scale_hints(), Slic3r::GUI::Selection::rotate(), Slic3r::GUI::GLGizmoCut3D::rotate_vec3d_around_plane_center(), Slic3r::CLI::run(), Slic3r::GUI::Selection::scale_and_translate(), Slic3r::GUI::GCodeViewer::SequentialView::Marker::set_world_position(), 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(), Slic3r::GUI::Selection::translate(), translation_transform(), Slic3r::GUI::GLGizmoHollow::update_hole_raycasters_for_picking_transform(), Slic3r::GUI::GLGizmoMeasure::update_if_needed(), Slic3r::GUI::GLGizmoSlaSupports::update_point_raycasters_for_picking_transform(), Slic3r::GUI::GLGizmoCut3D::update_raycasters_for_picking_transform(), and Slic3r::GUI::GLCanvas3D::update_sequential_clearance().

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