Replacing ClipperLib::IntPoint with Eigen point as a first step to

make the ClipperLib paths and polygons compatible with Slic3r paths
and polygons without conversions and memory allocations.
This commit is contained in:
Vojtech Bubnik 2021-04-14 09:22:51 +02:00
parent 29cd8aac26
commit 7112ac61b6
14 changed files with 416 additions and 401 deletions

View file

@ -56,8 +56,8 @@ template<class Tout = double, class = FloatingOnly<Tout>, int...EigenArgs>
inline constexpr Eigen::Matrix<Tout, 2, EigenArgs...> unscaled(
const ClipperLib::IntPoint &v) noexcept
{
return Eigen::Matrix<Tout, 2, EigenArgs...>{unscaled<Tout>(v.X),
unscaled<Tout>(v.Y)};
return Eigen::Matrix<Tout, 2, EigenArgs...>{unscaled<Tout>(v.x()),
unscaled<Tout>(v.y())};
}
namespace arrangement {
@ -644,7 +644,7 @@ void arrange(ArrangePolygons & arrangables,
for(size_t i = 0; i < items.size(); ++i) {
clppr::IntPoint tr = items[i].translation();
arrangables[i].translation = {coord_t(tr.X), coord_t(tr.Y)};
arrangables[i].translation = {coord_t(tr.x()), coord_t(tr.y())};
arrangables[i].rotation = items[i].rotation();
arrangables[i].bed_idx = items[i].binId();
}

View file

@ -78,7 +78,7 @@ static ConstPrintObjectPtrs get_top_level_objects_with_brim(const Print &print)
// Assign the maximum Z from four points. This values is valid index of the island
clipper.ZFillFunction([](const ClipperLib_Z::IntPoint &e1bot, const ClipperLib_Z::IntPoint &e1top, const ClipperLib_Z::IntPoint &e2bot,
const ClipperLib_Z::IntPoint &e2top, ClipperLib_Z::IntPoint &pt) {
pt.Z = std::max(std::max(e1bot.Z, e1top.Z), std::max(e2bot.Z, e2top.Z));
pt.z() = std::max(std::max(e1bot.z(), e1top.z()), std::max(e2bot.z(), e2top.z()));
});
// Add islands
clipper.AddPaths(islands_clip, ClipperLib_Z::ptSubject, true);
@ -90,9 +90,9 @@ static ConstPrintObjectPtrs get_top_level_objects_with_brim(const Print &print)
ConstPrintObjectPtrs top_level_objects_with_brim;
for (int i = 0; i < islands_polytree.ChildCount(); ++i) {
for (const ClipperLib_Z::IntPoint &point : islands_polytree.Childs[i]->Contour) {
if (point.Z != 0 && processed_objects_idx.find(island_to_object[point.Z - 1]->id().id) == processed_objects_idx.end()) {
top_level_objects_with_brim.emplace_back(island_to_object[point.Z - 1]);
processed_objects_idx.insert(island_to_object[point.Z - 1]->id().id);
if (point.z() != 0 && processed_objects_idx.find(island_to_object[point.z() - 1]->id().id) == processed_objects_idx.end()) {
top_level_objects_with_brim.emplace_back(island_to_object[point.z() - 1]);
processed_objects_idx.insert(island_to_object[point.z() - 1]->id().id);
}
}
}
@ -456,7 +456,7 @@ ExtrusionEntityCollection make_brim(const Print &print, PrintTryCancel try_cance
clipper.ZFillFunction([](const ClipperLib_Z::IntPoint& e1bot, const ClipperLib_Z::IntPoint& e1top, const ClipperLib_Z::IntPoint& e2bot, const ClipperLib_Z::IntPoint& e2top, ClipperLib_Z::IntPoint& pt) {
// Assign a valid input loop identifier. Such an identifier is strictly positive, the next line is safe even in case one side of a segment
// hat the Z coordinate not set to the contour coordinate.
pt.Z = std::max(std::max(e1bot.Z, e1top.Z), std::max(e2bot.Z, e2top.Z));
pt.z() = std::max(std::max(e1bot.z(), e1top.z()), std::max(e2bot.z(), e2top.z()));
});
// add polygons
clipper.AddPaths(input_clip, ClipperLib_Z::ptSubject, false);
@ -474,8 +474,8 @@ ExtrusionEntityCollection make_brim(const Print &print, PrintTryCancel try_cance
for (const ClipperLib_Z::Path &path : loops_trimmed) {
size_t input_idx = 0;
for (const ClipperLib_Z::IntPoint &pt : path)
if (pt.Z > 0) {
input_idx = (size_t)pt.Z;
if (pt.z() > 0) {
input_idx = (size_t)pt.z();
break;
}
assert(input_idx != 0);
@ -492,14 +492,14 @@ ExtrusionEntityCollection make_brim(const Print &print, PrintTryCancel try_cance
size_t j = i + 1;
for (; j < loops_trimmed_order.size() && loops_trimmed_order[i].second == loops_trimmed_order[j].second; ++ j) ;
const ClipperLib_Z::Path &first_path = *loops_trimmed_order[i].first;
if (i + 1 == j && first_path.size() > 3 && first_path.front().X == first_path.back().X && first_path.front().Y == first_path.back().Y) {
if (i + 1 == j && first_path.size() > 3 && first_path.front().x() == first_path.back().x() && first_path.front().y() == first_path.back().y()) {
auto *loop = new ExtrusionLoop();
brim.entities.emplace_back(loop);
loop->paths.emplace_back(erSkirt, float(flow.mm3_per_mm()), float(flow.width()), float(print.skirt_first_layer_height()));
Points &points = loop->paths.front().polyline.points;
points.reserve(first_path.size());
for (const ClipperLib_Z::IntPoint &pt : first_path)
points.emplace_back(coord_t(pt.X), coord_t(pt.Y));
points.emplace_back(coord_t(pt.x()), coord_t(pt.y()));
i = j;
} else {
//FIXME The path chaining here may not be optimal.
@ -511,7 +511,7 @@ ExtrusionEntityCollection make_brim(const Print &print, PrintTryCancel try_cance
Points &points = static_cast<ExtrusionPath*>(this_loop_trimmed.entities.back())->polyline.points;
points.reserve(path.size());
for (const ClipperLib_Z::IntPoint &pt : path)
points.emplace_back(coord_t(pt.X), coord_t(pt.Y));
points.emplace_back(coord_t(pt.x()), coord_t(pt.y()));
}
chain_and_reorder_extrusion_entities(this_loop_trimmed.entities, &last_pt);
brim.entities.reserve(brim.entities.size() + this_loop_trimmed.entities.size());

View file

@ -131,7 +131,7 @@ Slic3r::Polygon ClipperPath_to_Slic3rPolygon(const ClipperLib::Path &input)
{
Polygon retval;
for (ClipperLib::Path::const_iterator pit = input.begin(); pit != input.end(); ++pit)
retval.points.emplace_back(pit->X, pit->Y);
retval.points.emplace_back(pit->x(), pit->y());
return retval;
}
@ -139,7 +139,7 @@ Slic3r::Polyline ClipperPath_to_Slic3rPolyline(const ClipperLib::Path &input)
{
Polyline retval;
for (ClipperLib::Path::const_iterator pit = input.begin(); pit != input.end(); ++pit)
retval.points.emplace_back(pit->X, pit->Y);
retval.points.emplace_back(pit->x(), pit->y());
return retval;
}
@ -752,7 +752,7 @@ ClipperLib::PolyNodes order_nodes(const ClipperLib::PolyNodes &nodes)
for (const ClipperLib::PolyNode *node : nodes)
ordering_points.emplace_back(
Point(node->Contour.front().X, node->Contour.front().Y));
Point(node->Contour.front().x(), node->Contour.front().y()));
// perform the ordering
ClipperLib::PolyNodes ordered_nodes =
@ -777,7 +777,7 @@ static void traverse_pt_outside_in(const ClipperLib::PolyNodes &nodes, Polygons
Points ordering_points;
ordering_points.reserve(nodes.size());
for (const ClipperLib::PolyNode *node : nodes)
ordering_points.emplace_back(node->Contour.front().X, node->Contour.front().Y);
ordering_points.emplace_back(node->Contour.front().x(), node->Contour.front().y());
// Perform the ordering, push results recursively.
//FIXME pass the last point to chain_clipper_polynodes?

View file

@ -17,42 +17,42 @@ class BoundingBox;
class Line;
class MultiPoint;
class Point;
typedef Point Vector;
using Vector = Point;
// Eigen types, to replace the Slic3r's own types in the future.
// Vector types with a fixed point coordinate base type.
typedef Eigen::Matrix<coord_t, 2, 1, Eigen::DontAlign> Vec2crd;
typedef Eigen::Matrix<coord_t, 3, 1, Eigen::DontAlign> Vec3crd;
typedef Eigen::Matrix<int, 2, 1, Eigen::DontAlign> Vec2i;
typedef Eigen::Matrix<int, 3, 1, Eigen::DontAlign> Vec3i;
typedef Eigen::Matrix<int32_t, 2, 1, Eigen::DontAlign> Vec2i32;
typedef Eigen::Matrix<int64_t, 2, 1, Eigen::DontAlign> Vec2i64;
typedef Eigen::Matrix<int32_t, 3, 1, Eigen::DontAlign> Vec3i32;
typedef Eigen::Matrix<int64_t, 3, 1, Eigen::DontAlign> Vec3i64;
using Vec2crd = Eigen::Matrix<coord_t, 2, 1, Eigen::DontAlign>;
using Vec3crd = Eigen::Matrix<coord_t, 3, 1, Eigen::DontAlign>;
using Vec2i = Eigen::Matrix<int, 2, 1, Eigen::DontAlign>;
using Vec3i = Eigen::Matrix<int, 3, 1, Eigen::DontAlign>;
using Vec2i32 = Eigen::Matrix<int32_t, 2, 1, Eigen::DontAlign>;
using Vec2i64 = Eigen::Matrix<int64_t, 2, 1, Eigen::DontAlign>;
using Vec3i32 = Eigen::Matrix<int32_t, 3, 1, Eigen::DontAlign>;
using Vec3i64 = Eigen::Matrix<int64_t, 3, 1, Eigen::DontAlign>;
// Vector types with a double coordinate base type.
typedef Eigen::Matrix<float, 2, 1, Eigen::DontAlign> Vec2f;
typedef Eigen::Matrix<float, 3, 1, Eigen::DontAlign> Vec3f;
typedef Eigen::Matrix<double, 2, 1, Eigen::DontAlign> Vec2d;
typedef Eigen::Matrix<double, 3, 1, Eigen::DontAlign> Vec3d;
using Vec2f = Eigen::Matrix<float, 2, 1, Eigen::DontAlign>;
using Vec3f = Eigen::Matrix<float, 3, 1, Eigen::DontAlign>;
using Vec2d = Eigen::Matrix<double, 2, 1, Eigen::DontAlign>;
using Vec3d = Eigen::Matrix<double, 3, 1, Eigen::DontAlign>;
typedef std::vector<Point> Points;
typedef std::vector<Point*> PointPtrs;
typedef std::vector<const Point*> PointConstPtrs;
typedef std::vector<Vec3crd> Points3;
typedef std::vector<Vec2d> Pointfs;
typedef std::vector<Vec2d> Vec2ds;
typedef std::vector<Vec3d> Pointf3s;
using Points = std::vector<Point>;
using PointPtrs = std::vector<Point*>;
using PointConstPtrs = std::vector<const Point*>;
using Points3 = std::vector<Vec3crd>;
using Pointfs = std::vector<Vec2d>;
using Vec2ds = std::vector<Vec2d>;
using Pointf3s = std::vector<Vec3d>;
typedef Eigen::Matrix<float, 2, 2, Eigen::DontAlign> Matrix2f;
typedef Eigen::Matrix<double, 2, 2, Eigen::DontAlign> Matrix2d;
typedef Eigen::Matrix<float, 3, 3, Eigen::DontAlign> Matrix3f;
typedef Eigen::Matrix<double, 3, 3, Eigen::DontAlign> Matrix3d;
using Matrix2f = Eigen::Matrix<float, 2, 2, Eigen::DontAlign>;
using Matrix2d = Eigen::Matrix<double, 2, 2, Eigen::DontAlign>;
using Matrix3f = Eigen::Matrix<float, 3, 3, Eigen::DontAlign>;
using Matrix3d = Eigen::Matrix<double, 3, 3, Eigen::DontAlign>;
typedef Eigen::Transform<float, 2, Eigen::Affine, Eigen::DontAlign> Transform2f;
typedef Eigen::Transform<double, 2, Eigen::Affine, Eigen::DontAlign> Transform2d;
typedef Eigen::Transform<float, 3, Eigen::Affine, Eigen::DontAlign> Transform3f;
typedef Eigen::Transform<double, 3, Eigen::Affine, Eigen::DontAlign> Transform3d;
using Transform2f = Eigen::Transform<float, 2, Eigen::Affine, Eigen::DontAlign>;
using Transform2d = Eigen::Transform<double, 2, Eigen::Affine, Eigen::DontAlign>;
using Transform3f = Eigen::Transform<float, 3, Eigen::Affine, Eigen::DontAlign>;
using Transform3d = Eigen::Transform<double, 3, Eigen::Affine, Eigen::DontAlign>;
inline bool operator<(const Vec2d &lhs, const Vec2d &rhs) { return lhs(0) < rhs(0) || (lhs(0) == rhs(0) && lhs(1) < rhs(1)); }
@ -101,7 +101,7 @@ template<int N, class T> using Vec = Eigen::Matrix<T, N, 1, Eigen::DontAlign, N
class Point : public Vec2crd
{
public:
typedef coord_t coord_type;
using coord_type = coord_t;
Point() : Vec2crd(0, 0) {}
Point(int32_t x, int32_t y) : Vec2crd(coord_t(x), coord_t(y)) {}
@ -337,7 +337,7 @@ public:
}
private:
typedef typename std::unordered_multimap<Vec2crd, ValueType, PointHash> map_type;
using map_type = typename std::unordered_multimap<Vec2crd, ValueType, PointHash>;
PointAccessor m_point_accessor;
map_type m_map;
coord_t m_search_radius;
@ -439,11 +439,11 @@ inline Point align_to_grid(Point coord, Point spacing, Point base)
#include <boost/polygon/polygon.hpp>
namespace boost { namespace polygon {
template <>
struct geometry_concept<Slic3r::Point> { typedef point_concept type; };
struct geometry_concept<Slic3r::Point> { using type = point_concept; };
template <>
struct point_traits<Slic3r::Point> {
typedef coord_t coordinate_type;
using coordinate_type = coord_t;
static inline coordinate_type get(const Slic3r::Point& point, orientation_2d orient) {
return static_cast<coordinate_type>(point((orient == HORIZONTAL) ? 0 : 1));
@ -452,7 +452,7 @@ namespace boost { namespace polygon {
template <>
struct point_mutable_traits<Slic3r::Point> {
typedef coord_t coordinate_type;
using coordinate_type = coord_t;
static inline void set(Slic3r::Point& point, orientation_2d orient, coord_t value) {
point((orient == HORIZONTAL) ? 0 : 1) = value;
}

View file

@ -77,8 +77,8 @@ protected:
double getPx(const Point &p) { return p(0) * m_pxdim_scaled.w_mm; }
double getPy(const Point &p) { return p(1) * m_pxdim_scaled.h_mm; }
agg::path_storage to_path(const Polygon &poly) { return to_path(poly.points); }
double getPx(const ClipperLib::IntPoint &p) { return p.X * m_pxdim_scaled.w_mm; }
double getPy(const ClipperLib::IntPoint& p) { return p.Y * m_pxdim_scaled.h_mm; }
double getPx(const ClipperLib::IntPoint &p) { return p.x() * m_pxdim_scaled.w_mm; }
double getPy(const ClipperLib::IntPoint& p) { return p.y() * m_pxdim_scaled.h_mm; }
template<class PointVec> agg::path_storage _to_path(const PointVec& v)
{

View file

@ -806,8 +806,8 @@ static ClipperPolygons get_all_polygons(const SliceRecord& record, SliceOrigin o
}
if(is_lefthanded) {
for(auto& p : poly.Contour) p.X = -p.X;
for(auto& h : poly.Holes) for(auto& p : h) p.X = -p.X;
for(auto& p : poly.Contour) p.x() = -p.x();
for(auto& h : poly.Holes) for(auto& p : h) p.x() = -p.x();
}
sl::rotate(poly, double(instances[i].rotation));

View file

@ -273,8 +273,8 @@ std::string SVG::get_path_d(const ClipperLib::Path &path, double scale, bool clo
std::ostringstream d;
d << "M ";
for (ClipperLib::Path::const_iterator p = path.begin(); p != path.end(); ++p) {
d << to_svg_x(scale * p->X - origin(0)) << " ";
d << to_svg_y(scale * p->Y - origin(1)) << " ";
d << to_svg_x(scale * p->x() - origin(0)) << " ";
d << to_svg_y(scale * p->y() - origin(1)) << " ";
}
if (closed) d << "z";
return d.str();