mirror of
https://github.com/QIDITECH/QIDISlicer.git
synced 2026-02-04 09:58:44 +03:00
Merge prusa 2.6.1
This commit is contained in:
192
src/libslic3r/Arrange/Core/Beds.hpp
Normal file
192
src/libslic3r/Arrange/Core/Beds.hpp
Normal file
@@ -0,0 +1,192 @@
|
||||
|
||||
#ifndef BEDS_HPP
|
||||
#define BEDS_HPP
|
||||
|
||||
#include <numeric>
|
||||
|
||||
#include <libslic3r/Point.hpp>
|
||||
#include <libslic3r/ExPolygon.hpp>
|
||||
#include <libslic3r/BoundingBox.hpp>
|
||||
#include <libslic3r/ClipperUtils.hpp>
|
||||
|
||||
#include <boost/variant.hpp>
|
||||
|
||||
namespace Slic3r { namespace arr2 {
|
||||
|
||||
// Bed types to be used with arrangement. Most generic bed is a simple polygon
|
||||
// with holes, but other special bed types are also valid, like a bed without
|
||||
// boundaries, or a special case of a rectangular or circular bed which leaves
|
||||
// a lot of room for optimizations.
|
||||
|
||||
// Representing an unbounded bed.
|
||||
struct InfiniteBed {
|
||||
Point center;
|
||||
explicit InfiniteBed(const Point &p = {0, 0}): center{p} {}
|
||||
};
|
||||
|
||||
BoundingBox bounding_box(const InfiniteBed &bed);
|
||||
|
||||
inline InfiniteBed offset(const InfiniteBed &bed, coord_t) { return bed; }
|
||||
|
||||
struct RectangleBed {
|
||||
BoundingBox bb;
|
||||
|
||||
explicit RectangleBed(const BoundingBox &bedbb) : bb{bedbb} {}
|
||||
explicit RectangleBed(coord_t w, coord_t h, Point c = {0, 0}):
|
||||
bb{{c.x() - w / 2, c.y() - h / 2}, {c.x() + w / 2, c.y() + h / 2}}
|
||||
{}
|
||||
|
||||
coord_t width() const { return bb.size().x(); }
|
||||
coord_t height() const { return bb.size().y(); }
|
||||
};
|
||||
|
||||
inline BoundingBox bounding_box(const RectangleBed &bed) { return bed.bb; }
|
||||
inline RectangleBed offset(RectangleBed bed, coord_t v)
|
||||
{
|
||||
bed.bb.offset(v);
|
||||
return bed;
|
||||
}
|
||||
|
||||
Polygon to_rectangle(const BoundingBox &bb);
|
||||
|
||||
inline Polygon to_rectangle(const RectangleBed &bed)
|
||||
{
|
||||
return to_rectangle(bed.bb);
|
||||
}
|
||||
|
||||
class CircleBed {
|
||||
Point m_center;
|
||||
double m_radius;
|
||||
|
||||
public:
|
||||
CircleBed(): m_center(0, 0), m_radius(NaNd) {}
|
||||
explicit CircleBed(const Point& c, double r)
|
||||
: m_center(c)
|
||||
, m_radius(r)
|
||||
{}
|
||||
|
||||
double radius() const { return m_radius; }
|
||||
const Point& center() const { return m_center; }
|
||||
};
|
||||
|
||||
// Function to approximate a circle with a convex polygon
|
||||
Polygon approximate_circle_with_polygon(const CircleBed &bed, int nedges = 24);
|
||||
|
||||
inline BoundingBox bounding_box(const CircleBed &bed)
|
||||
{
|
||||
auto r = static_cast<coord_t>(std::round(bed.radius()));
|
||||
Point R{r, r};
|
||||
|
||||
return {bed.center() - R, bed.center() + R};
|
||||
}
|
||||
inline CircleBed offset(const CircleBed &bed, coord_t v)
|
||||
{
|
||||
return CircleBed{bed.center(), bed.radius() + v};
|
||||
}
|
||||
|
||||
struct IrregularBed { ExPolygons poly; };
|
||||
inline BoundingBox bounding_box(const IrregularBed &bed)
|
||||
{
|
||||
return get_extents(bed.poly);
|
||||
}
|
||||
|
||||
inline IrregularBed offset(IrregularBed bed, coord_t v)
|
||||
{
|
||||
bed.poly = offset_ex(bed.poly, v);
|
||||
return bed;
|
||||
}
|
||||
|
||||
using ArrangeBed =
|
||||
boost::variant<InfiniteBed, RectangleBed, CircleBed, IrregularBed>;
|
||||
|
||||
inline BoundingBox bounding_box(const ArrangeBed &bed)
|
||||
{
|
||||
BoundingBox ret;
|
||||
auto visitor = [&ret](const auto &b) { ret = bounding_box(b); };
|
||||
boost::apply_visitor(visitor, bed);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline ArrangeBed offset(ArrangeBed bed, coord_t v)
|
||||
{
|
||||
auto visitor = [v](auto &b) { b = offset(b, v); };
|
||||
boost::apply_visitor(visitor, bed);
|
||||
|
||||
return bed;
|
||||
}
|
||||
|
||||
inline double area(const BoundingBox &bb)
|
||||
{
|
||||
auto bbsz = bb.size();
|
||||
return double(bbsz.x()) * bbsz.y();
|
||||
}
|
||||
|
||||
inline double area(const RectangleBed &bed)
|
||||
{
|
||||
auto bbsz = bed.bb.size();
|
||||
return double(bbsz.x()) * bbsz.y();
|
||||
}
|
||||
|
||||
inline double area(const InfiniteBed &bed)
|
||||
{
|
||||
return std::numeric_limits<double>::infinity();
|
||||
}
|
||||
|
||||
inline double area(const IrregularBed &bed)
|
||||
{
|
||||
return std::accumulate(bed.poly.begin(), bed.poly.end(), 0.,
|
||||
[](double s, auto &p) { return s + p.area(); });
|
||||
}
|
||||
|
||||
inline double area(const CircleBed &bed)
|
||||
{
|
||||
return bed.radius() * bed.radius() * PI;
|
||||
}
|
||||
|
||||
inline double area(const ArrangeBed &bed)
|
||||
{
|
||||
double ret = 0.;
|
||||
auto visitor = [&ret](auto &b) { ret = area(b); };
|
||||
boost::apply_visitor(visitor, bed);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline ExPolygons to_expolygons(const InfiniteBed &bed)
|
||||
{
|
||||
return {ExPolygon{to_rectangle(RectangleBed{scaled(1000.), scaled(1000.)})}};
|
||||
}
|
||||
|
||||
inline ExPolygons to_expolygons(const RectangleBed &bed)
|
||||
{
|
||||
return {ExPolygon{to_rectangle(bed)}};
|
||||
}
|
||||
|
||||
inline ExPolygons to_expolygons(const CircleBed &bed)
|
||||
{
|
||||
return {ExPolygon{approximate_circle_with_polygon(bed)}};
|
||||
}
|
||||
|
||||
inline ExPolygons to_expolygons(const IrregularBed &bed) { return bed.poly; }
|
||||
|
||||
inline ExPolygons to_expolygons(const ArrangeBed &bed)
|
||||
{
|
||||
ExPolygons ret;
|
||||
auto visitor = [&ret](const auto &b) { ret = to_expolygons(b); };
|
||||
boost::apply_visitor(visitor, bed);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
ArrangeBed to_arrange_bed(const Points &bedpts);
|
||||
|
||||
} // namespace arr2
|
||||
|
||||
inline BoundingBox &bounding_box(BoundingBox &bb) { return bb; }
|
||||
inline const BoundingBox &bounding_box(const BoundingBox &bb) { return bb; }
|
||||
inline BoundingBox bounding_box(const Polygon &p) { return get_extents(p); }
|
||||
|
||||
} // namespace Slic3r
|
||||
|
||||
#endif // BEDS_HPP
|
||||
Reference in New Issue
Block a user