Welcome to mirror list, hosted at ThFree Co, Russian Federation.

MinAreaBoundingBox.cpp « libslic3r « src - github.com/supermerill/SuperSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 15c04517d08c2c47cc84c3ae6da5c5bd07a5d311 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#include "MinAreaBoundingBox.hpp"

#include <libslic3r/ExPolygon.hpp>

#if defined(_MSC_VER) && defined(__clang__)
#define BOOST_NO_CXX17_HDR_STRING_VIEW
#endif

#include <boost/rational.hpp>

#include <libslic3r/Int128.hpp>

#if !defined(HAS_INTRINSIC_128_TYPE) || defined(__APPLE__)
#include <boost/multiprecision/integer.hpp>
#endif

#include <libnest2d/geometry_traits.hpp>
#include <libnest2d/utils/rotcalipers.hpp>

namespace libnest2d {

template<> struct PointType<Slic3r::Points>      { using Type = Slic3r::Point; };
template<> struct CoordType<Slic3r::Point>       { using Type = coord_t; };
template<> struct ShapeTag<Slic3r::ExPolygon>    { using Type = PolygonTag; };
template<> struct ShapeTag<Slic3r::Polygon>      { using Type = PolygonTag; };
template<> struct ShapeTag<Slic3r::Points>       { using Type = PathTag; };
template<> struct ShapeTag<Slic3r::Point>        { using Type = PointTag; };
template<> struct ContourType<Slic3r::ExPolygon> { using Type = Slic3r::Points; };
template<> struct ContourType<Slic3r::Polygon>   { using Type = Slic3r::Points; };

namespace pointlike {

template<> inline coord_t x(const Slic3r::Point& p) { return p.x(); }
template<> inline coord_t y(const Slic3r::Point& p) { return p.y(); }
template<> inline coord_t& x(Slic3r::Point& p)      { return p.x(); }
template<> inline coord_t& y(Slic3r::Point& p)      { return p.y(); }

} // pointlike

namespace shapelike {
template<> inline Slic3r::Points& contour(Slic3r::ExPolygon& sh) { return sh.contour.points; }
template<> inline const Slic3r::Points& contour(const Slic3r::ExPolygon& sh) { return sh.contour.points; }
template<> inline Slic3r::Points& contour(Slic3r::Polygon& sh) { return sh.points; }
template<> inline const Slic3r::Points& contour(const Slic3r::Polygon& sh) { return sh.points; }

template<> Slic3r::Points::iterator begin(Slic3r::Points& pts, const PathTag&) { return pts.begin();}
template<> Slic3r::Points::const_iterator cbegin(const Slic3r::Points& pts, const PathTag&) { return pts.cbegin(); }
template<> Slic3r::Points::iterator end(Slic3r::Points& pts, const PathTag&) { return pts.end();}
template<> Slic3r::Points::const_iterator cend(const Slic3r::Points& pts, const PathTag&) { return pts.cend(); }

template<> inline Slic3r::ExPolygon create<Slic3r::ExPolygon>(Slic3r::Points&& contour)
{
    Slic3r::ExPolygon expoly; expoly.contour.points.swap(contour);
    return expoly;
}

template<> inline Slic3r::Polygon create<Slic3r::Polygon>(Slic3r::Points&& contour)
{
    Slic3r::Polygon poly; poly.points.swap(contour);
    return poly;
}

} // shapelike
} // libnest2d

namespace Slic3r {

// Used as compute type.
using Unit = int64_t;

#if !defined(HAS_INTRINSIC_128_TYPE) || defined(__APPLE__)
using Rational = boost::rational<boost::multiprecision::int128_t>;
#else
using Rational = boost::rational<__int128>;
#endif

MinAreaBoundigBox::MinAreaBoundigBox(const Polygon &p, PolygonLevel pc)
{
    const Polygon &chull = pc == pcConvex ? p :
                                            libnest2d::sl::convexHull(p);

    libnest2d::RotatedBox<Point, Unit> box =
        libnest2d::minAreaBoundingBox<Polygon, Unit, Rational>(chull);

    m_right  = libnest2d::cast<long double>(box.right_extent());
    m_bottom = libnest2d::cast<long double>(box.bottom_extent());
    m_axis   = box.axis();
}

MinAreaBoundigBox::MinAreaBoundigBox(const ExPolygon &p, PolygonLevel pc)
{
    const ExPolygon &chull = pc == pcConvex ? p :
                                              libnest2d::sl::convexHull(p);

    libnest2d::RotatedBox<Point, Unit> box =
        libnest2d::minAreaBoundingBox<ExPolygon, Unit, Rational>(chull);

    m_right  = libnest2d::cast<long double>(box.right_extent());
    m_bottom = libnest2d::cast<long double>(box.bottom_extent());
    m_axis   = box.axis();
}

MinAreaBoundigBox::MinAreaBoundigBox(const Points &pts, PolygonLevel pc)
{
    const Points &chull = pc == pcConvex ? pts :
                                           libnest2d::sl::convexHull(pts);

    libnest2d::RotatedBox<Point, Unit> box =
        libnest2d::minAreaBoundingBox<Points, Unit, Rational>(chull);

    m_right  = libnest2d::cast<long double>(box.right_extent());
    m_bottom = libnest2d::cast<long double>(box.bottom_extent());
    m_axis   = box.axis();
}

double MinAreaBoundigBox::angle_to_X() const
{
    double ret = std::atan2(m_axis.y(), m_axis.x());
    auto   s   = std::signbit(ret);
    if (s) ret += 2 * PI;
    return -ret;
}

long double MinAreaBoundigBox::width() const
{
    return std::abs(m_bottom) /
           std::sqrt(libnest2d::pl::magnsq<Point, long double>(m_axis));
}

long double MinAreaBoundigBox::height() const
{
    return std::abs(m_right) /
           std::sqrt(libnest2d::pl::magnsq<Point, long double>(m_axis));
}

long double MinAreaBoundigBox::area() const
{
    long double asq = libnest2d::pl::magnsq<Point, long double>(m_axis);
    return m_bottom * m_right / asq;
}

void remove_collinear_points(Polygon &p)
{
    p = libnest2d::removeCollinearPoints<Polygon>(p, Unit(0));
}

void remove_collinear_points(ExPolygon &p)
{
    p = libnest2d::removeCollinearPoints<ExPolygon>(p, Unit(0));
}
} // namespace Slic3r