From f34252a27b810023186ebf116e91f19f8b70624f Mon Sep 17 00:00:00 2001 From: bubnikv Date: Tue, 14 Aug 2018 21:33:41 +0200 Subject: [PATCH] Changing the internal representation of Point / Pointf / Point3 / Pointf3 to Eigen Matrix types: Changed the Point3 / Pointf3 to composite Eigen Vec3crd / Vec3d. Point3 is no more derived from Point, Pointf3 is no more derived from Pointf. Introduced Transform2f/3f/2d/3d types as aliases to Eigen::Transform. --- xs/src/libslic3r/BoundingBox.cpp | 8 +- xs/src/libslic3r/BoundingBox.hpp | 2 +- xs/src/libslic3r/GCodeWriter.cpp | 2 +- xs/src/libslic3r/Line.cpp | 4 +- xs/src/libslic3r/Model.cpp | 24 ++-- xs/src/libslic3r/MultiPoint.cpp | 48 +++----- xs/src/libslic3r/Point.cpp | 162 ++++----------------------- xs/src/libslic3r/Point.hpp | 118 +++++++++++++------ xs/src/libslic3r/Print.cpp | 2 +- xs/src/libslic3r/Print.hpp | 2 +- xs/src/libslic3r/SupportMaterial.cpp | 2 +- xs/src/libslic3r/TriangleMesh.cpp | 100 ++++++++--------- xs/src/slic3r/GUI/3DScene.cpp | 18 +-- xs/src/slic3r/GUI/3DScene.hpp | 4 +- xs/src/slic3r/GUI/GLGizmo.cpp | 4 +- 15 files changed, 197 insertions(+), 303 deletions(-) diff --git a/xs/src/libslic3r/BoundingBox.cpp b/xs/src/libslic3r/BoundingBox.cpp index 7ab45c9d2..239300fb4 100644 --- a/xs/src/libslic3r/BoundingBox.cpp +++ b/xs/src/libslic3r/BoundingBox.cpp @@ -253,9 +253,9 @@ void BoundingBox::align_to_grid(const coord_t cell_size) } } -BoundingBoxf3 BoundingBoxf3::transformed(const std::vector& matrix) const +BoundingBoxf3 BoundingBoxf3::transformed(const Transform3f& matrix) const { - Eigen::Matrix vertices; + Eigen::Matrix vertices; vertices(0, 0) = (float)min.x(); vertices(1, 0) = (float)min.y(); vertices(2, 0) = (float)min.z(); vertices(0, 1) = (float)max.x(); vertices(1, 1) = (float)min.y(); vertices(2, 1) = (float)min.z(); @@ -266,9 +266,7 @@ BoundingBoxf3 BoundingBoxf3::transformed(const std::vector& matrix) const vertices(0, 6) = (float)max.x(); vertices(1, 6) = (float)max.y(); vertices(2, 6) = (float)max.z(); vertices(0, 7) = (float)min.x(); vertices(1, 7) = (float)max.y(); vertices(2, 7) = (float)max.z(); - Eigen::Transform m; - ::memcpy((void*)m.data(), (const void*)matrix.data(), 16 * sizeof(float)); - Eigen::Matrix transf_vertices = m * vertices.colwise().homogeneous(); + Eigen::Matrix transf_vertices = matrix * vertices.colwise().homogeneous(); float min_x = transf_vertices(0, 0); float max_x = transf_vertices(0, 0); diff --git a/xs/src/libslic3r/BoundingBox.hpp b/xs/src/libslic3r/BoundingBox.hpp index 13f1de5bd..06ef15bab 100644 --- a/xs/src/libslic3r/BoundingBox.hpp +++ b/xs/src/libslic3r/BoundingBox.hpp @@ -153,7 +153,7 @@ public: BoundingBoxf3(const Pointf3 &pmin, const Pointf3 &pmax) : BoundingBox3Base(pmin, pmax) {}; BoundingBoxf3(const std::vector &points) : BoundingBox3Base(points) {}; - BoundingBoxf3 transformed(const std::vector& matrix) const; + BoundingBoxf3 transformed(const Transform3f& matrix) const; }; template diff --git a/xs/src/libslic3r/GCodeWriter.cpp b/xs/src/libslic3r/GCodeWriter.cpp index 39c431169..6ebb181f5 100644 --- a/xs/src/libslic3r/GCodeWriter.cpp +++ b/xs/src/libslic3r/GCodeWriter.cpp @@ -299,7 +299,7 @@ std::string GCodeWriter::travel_to_xyz(const Pointf3 &point, const std::string & if (!this->will_move_z(point.z())) { double nominal_z = m_pos.z() - m_lifted; m_lifted = m_lifted - (point.z() - nominal_z); - return this->travel_to_xy(point); + return this->travel_to_xy(point.xy()); } /* In all the other cases, we perform an actual XYZ move and cancel diff --git a/xs/src/libslic3r/Line.cpp b/xs/src/libslic3r/Line.cpp index c40bc1c7b..e2108af22 100644 --- a/xs/src/libslic3r/Line.cpp +++ b/xs/src/libslic3r/Line.cpp @@ -220,12 +220,12 @@ Line::ccw(const Point& point) const double Line3::length() const { - return a.distance_to(b); + return (b.data - a.data).norm(); } Vector3 Line3::vector() const { - return Vector3(b.x() - a.x(), b.y() - a.y(), b.z() - a.z()); + return Vector3(b.data - a.data); } Pointf3 diff --git a/xs/src/libslic3r/Model.cpp b/xs/src/libslic3r/Model.cpp index dfd407632..a04ab7317 100644 --- a/xs/src/libslic3r/Model.cpp +++ b/xs/src/libslic3r/Model.cpp @@ -396,7 +396,7 @@ using ShapeData2D = ShapeData2D projectModelFromTop(const Slic3r::Model &model) { ShapeData2D ret; - auto s = std::accumulate(model.objects.begin(), model.objects.end(), 0, + auto s = std::accumulate(model.objects.begin(), model.objects.end(), size_t(0), [](size_t s, ModelObject* o){ return s + o->instances.size(); }); @@ -648,8 +648,8 @@ bool Model::arrange_objects(coordf_t dist, const BoundingBoxf* bb, for (size_t i = 0; i < o->instances.size(); ++ i) { // an accurate snug bounding box around the transformed mesh. BoundingBoxf3 bbox(o->instance_bounding_box(i, true)); - instance_sizes.push_back(bbox.size()); - instance_centers.push_back(bbox.center()); + instance_sizes.push_back(bbox.size().xy()); + instance_centers.push_back(bbox.center().xy()); } Pointfs positions; @@ -672,7 +672,7 @@ bool Model::arrange_objects(coordf_t dist, const BoundingBoxf* bb, // Duplicate the entire model preserving instance relative positions. void Model::duplicate(size_t copies_num, coordf_t dist, const BoundingBoxf* bb) { - Pointfs model_sizes(copies_num-1, this->bounding_box().size()); + Pointfs model_sizes(copies_num-1, this->bounding_box().size().xy()); Pointfs positions; if (! _arrange(model_sizes, dist, bb, positions)) CONFESS("Cannot duplicate part as the resulting objects would not fit on the print bed.\n"); @@ -1081,10 +1081,10 @@ void ModelObject::center_around_origin() for (ModelInstance *i : this->instances) { // apply rotation and scaling to vector as well before translating instance, // in order to leave final position unaltered - Vectorf3 v = vector.negative(); + Vectorf v = vector.negative().xy(); v.rotate(i->rotation); v.scale(i->scaling_factor); - i->offset.translate(v.x(), v.y()); + i->offset.translate(v); } this->invalidate_bounding_box(); } @@ -1440,16 +1440,12 @@ BoundingBoxf3 ModelInstance::transform_mesh_bounding_box(const TriangleMesh* mes BoundingBoxf3 ModelInstance::transform_bounding_box(const BoundingBoxf3 &bbox, bool dont_translate) const { - Eigen::Transform matrix = Eigen::Transform::Identity(); + auto matrix = Transform3f::Identity(); if (!dont_translate) - matrix.translate(Eigen::Vector3f((float)offset.x(), (float)offset.y(), 0.0f)); - - matrix.rotate(Eigen::AngleAxisf(rotation, Eigen::Vector3f::UnitZ())); + matrix.translate(Vec3f((float)offset.x(), (float)offset.y(), 0.0f)); + matrix.rotate(Eigen::AngleAxisf(rotation, Vec3f::UnitZ())); matrix.scale(scaling_factor); - - std::vector m(16, 0.0f); - ::memcpy((void*)m.data(), (const void*)matrix.data(), 16 * sizeof(float)); - return bbox.transformed(m); + return bbox.transformed(matrix); } void ModelInstance::transform_polygon(Polygon* polygon) const diff --git a/xs/src/libslic3r/MultiPoint.cpp b/xs/src/libslic3r/MultiPoint.cpp index d094c2893..f19d37644 100644 --- a/xs/src/libslic3r/MultiPoint.cpp +++ b/xs/src/libslic3r/MultiPoint.cpp @@ -8,24 +8,19 @@ MultiPoint::operator Points() const return this->points; } -void -MultiPoint::scale(double factor) +void MultiPoint::scale(double factor) { - for (Points::iterator it = points.begin(); it != points.end(); ++it) { - (*it).scale(factor); - } + for (Point &pt : points) + pt.scale(factor); } -void -MultiPoint::translate(double x, double y) +void MultiPoint::translate(double x, double y) { - for (Points::iterator it = points.begin(); it != points.end(); ++it) { - (*it).translate(x, y); - } + for (Point &pt : points) + pt.translate(x, y); } -void -MultiPoint::translate(const Point &vector) +void MultiPoint::translate(const Point &vector) { this->translate(vector.x(), vector.y()); } @@ -40,27 +35,23 @@ void MultiPoint::rotate(double cos_angle, double sin_angle) } } -void -MultiPoint::rotate(double angle, const Point ¢er) +void MultiPoint::rotate(double angle, const Point ¢er) { double s = sin(angle); double c = cos(angle); - for (Points::iterator it = points.begin(); it != points.end(); ++it) { - double dx = double(it->x() - center.x()); - double dy = double(it->y() - center.y()); - it->x() = (coord_t)round(double(center.x()) + c * dx - s * dy); - it->y() = (coord_t)round(double(center.y()) + c * dy + s * dx); + for (Point &pt : points) { + Vec2crd dif(pt.data - center.data); + pt.x() = (coord_t)round(double(center.x()) + c * dif[0] - s * dif[1]); + pt.y() = (coord_t)round(double(center.y()) + c * dif[1] + s * dif[0]); } } -void -MultiPoint::reverse() +void MultiPoint::reverse() { std::reverse(this->points.begin(), this->points.end()); } -Point -MultiPoint::first_point() const +Point MultiPoint::first_point() const { return this->points.front(); } @@ -216,9 +207,9 @@ MultiPoint::_douglas_peucker(const Points &points, const double tolerance) void MultiPoint3::translate(double x, double y) { - for (Point3& p : points) - { - p.translate(x, y); + for (Point3 &p : points) { + p.x() += x; + p.y() += y; } } @@ -229,12 +220,9 @@ void MultiPoint3::translate(const Point& vector) double MultiPoint3::length() const { - Lines3 lines = this->lines(); double len = 0.0; - for (const Line3& line : lines) - { + for (const Line3& line : this->lines()) len += line.length(); - } return len; } diff --git a/xs/src/libslic3r/Point.cpp b/xs/src/libslic3r/Point.cpp index 3d92959e1..4c3fb2d94 100644 --- a/xs/src/libslic3r/Point.cpp +++ b/xs/src/libslic3r/Point.cpp @@ -13,36 +13,14 @@ std::string Point::wkt() const return ss.str(); } -std::string -Point::dump_perl() const +std::string Point::dump_perl() const { std::ostringstream ss; ss << "[" << this->x() << "," << this->y() << "]"; return ss.str(); } -void -Point::scale(double factor) -{ - this->x() *= factor; - this->y() *= factor; -} - -void -Point::translate(double x, double y) -{ - this->x() += x; - this->y() += y; -} - -void -Point::translate(const Vector &vector) -{ - this->translate(vector.x(), vector.y()); -} - -void -Point::rotate(double angle) +void Point::rotate(double angle) { double cur_x = (double)this->x(); double cur_y = (double)this->y(); @@ -52,8 +30,7 @@ Point::rotate(double angle) this->y() = (coord_t)round(c * cur_y + s * cur_x); } -void -Point::rotate(double angle, const Point ¢er) +void Point::rotate(double angle, const Point ¢er) { double cur_x = (double)this->x(); double cur_y = (double)this->y(); @@ -65,14 +42,12 @@ Point::rotate(double angle, const Point ¢er) this->y() = (coord_t)round( (double)center.y() + c * dy + s * dx ); } -bool -Point::coincides_with_epsilon(const Point &point) const +bool Point::coincides_with_epsilon(const Point &point) const { return std::abs(this->x() - point.x()) < SCALED_EPSILON && std::abs(this->y() - point.y()) < SCALED_EPSILON; } -int -Point::nearest_point_index(const Points &points) const +int Point::nearest_point_index(const Points &points) const { PointConstPtrs p; p.reserve(points.size()); @@ -106,8 +81,7 @@ int Point::nearest_point_index(const PointConstPtrs &points) const return idx; } -int -Point::nearest_point_index(const PointPtrs &points) const +int Point::nearest_point_index(const PointPtrs &points) const { PointConstPtrs p; p.reserve(points.size()); @@ -116,8 +90,7 @@ Point::nearest_point_index(const PointPtrs &points) const return this->nearest_point_index(p); } -bool -Point::nearest_point(const Points &points, Point* point) const +bool Point::nearest_point(const Points &points, Point* point) const { int idx = this->nearest_point_index(points); if (idx == -1) return false; @@ -126,8 +99,7 @@ Point::nearest_point(const Points &points, Point* point) const } /* distance to the closest point of line */ -double -Point::distance_to(const Line &line) const +double Point::distance_to(const Line &line) const { const double dx = line.b.x() - line.a.x(); const double dy = line.b.y() - line.a.y(); @@ -148,8 +120,7 @@ Point::distance_to(const Line &line) const return this->distance_to(projection); } -double -Point::perp_distance_to(const Line &line) const +double Point::perp_distance_to(const Line &line) const { if (line.a.coincides_with(line.b)) return this->distance_to(line.a); @@ -166,22 +137,19 @@ Point::perp_distance_to(const Line &line) const * z-component of their 3D cross product. * We return double because it must be big enough to hold 2*max(|coordinate|)^2 */ -double -Point::ccw(const Point &p1, const Point &p2) const +double Point::ccw(const Point &p1, const Point &p2) const { return (double)(p2.x() - p1.x())*(double)(this->y() - p1.y()) - (double)(p2.y() - p1.y())*(double)(this->x() - p1.x()); } -double -Point::ccw(const Line &line) const +double Point::ccw(const Line &line) const { return this->ccw(line.a, line.b); } // returns the CCW angle between this-p1 and this-p2 // i.e. this assumes a CCW rotation from p1 to p2 around this -double -Point::ccw_angle(const Point &p1, const Point &p2) const +double Point::ccw_angle(const Point &p1, const Point &p2) const { double angle = atan2(p1.x() - this->x(), p1.y() - this->y()) - atan2(p2.x() - this->x(), p2.y() - this->y()); @@ -190,8 +158,7 @@ Point::ccw_angle(const Point &p1, const Point &p2) const return angle <= 0 ? angle + 2*PI : angle; } -Point -Point::projection_onto(const MultiPoint &poly) const +Point Point::projection_onto(const MultiPoint &poly) const { Point running_projection = poly.first_point(); double running_min = this->distance_to(running_projection); @@ -207,8 +174,7 @@ Point::projection_onto(const MultiPoint &poly) const return running_projection; } -Point -Point::projection_onto(const Line &line) const +Point Point::projection_onto(const Line &line) const { if (line.a.coincides_with(line.b)) return line.a; @@ -237,62 +203,26 @@ Point::projection_onto(const Line &line) const } } -Point -Point::negative() const -{ - return Point(-this->x(), -this->y()); -} - -Vector -Point::vector_to(const Point &point) const -{ - return Vector(point.x() - this->x(), point.y() - this->y()); -} - -std::ostream& -operator<<(std::ostream &stm, const Pointf &pointf) +std::ostream& operator<<(std::ostream &stm, const Pointf &pointf) { return stm << pointf.x() << "," << pointf.y(); } -std::string -Pointf::wkt() const +std::string Pointf::wkt() const { std::ostringstream ss; ss << "POINT(" << this->x() << " " << this->y() << ")"; return ss.str(); } -std::string -Pointf::dump_perl() const +std::string Pointf::dump_perl() const { std::ostringstream ss; ss << "[" << this->x() << "," << this->y() << "]"; return ss.str(); } -void -Pointf::scale(double factor) -{ - this->x() *= factor; - this->y() *= factor; -} - -void -Pointf::translate(double x, double y) -{ - this->x() += x; - this->y() += y; -} - -void -Pointf::translate(const Vectorf &vector) -{ - this->translate(vector.x(), vector.y()); -} - -void -Pointf::rotate(double angle) +void Pointf::rotate(double angle) { double cur_x = this->x(); double cur_y = this->y(); @@ -302,8 +232,7 @@ Pointf::rotate(double angle) this->y() = c * cur_y + s * cur_x; } -void -Pointf::rotate(double angle, const Pointf ¢er) +void Pointf::rotate(double angle, const Pointf ¢er) { double cur_x = this->x(); double cur_y = this->y(); @@ -315,59 +244,6 @@ Pointf::rotate(double angle, const Pointf ¢er) this->y() = center.y() + c * dy + s * dx; } -Pointf -Pointf::negative() const -{ - return Pointf(-this->x(), -this->y()); -} - -Vectorf -Pointf::vector_to(const Pointf &point) const -{ - return Vectorf(point.x() - this->x(), point.y() - this->y()); -} - -void -Pointf3::scale(double factor) -{ - Pointf::scale(factor); - this->z() *= factor; -} - -void -Pointf3::translate(const Vectorf3 &vector) -{ - this->translate(vector.x(), vector.y(), vector.z()); -} - -void -Pointf3::translate(double x, double y, double z) -{ - Pointf::translate(x, y); - this->z() += z; -} - -double -Pointf3::distance_to(const Pointf3 &point) const -{ - double dx = ((double)point.x() - this->x()); - double dy = ((double)point.y() - this->y()); - double dz = ((double)point.z() - this->z()); - return sqrt(dx*dx + dy*dy + dz*dz); -} - -Pointf3 -Pointf3::negative() const -{ - return Pointf3(-this->x(), -this->y(), -this->z()); -} - -Vectorf3 -Pointf3::vector_to(const Pointf3 &point) const -{ - return Vectorf3(point.x() - this->x(), point.y() - this->y(), point.z() - this->z()); -} - namespace int128 { int orient(const Point &p1, const Point &p2, const Point &p3) diff --git a/xs/src/libslic3r/Point.hpp b/xs/src/libslic3r/Point.hpp index 2630f58a5..568dfb1ff 100644 --- a/xs/src/libslic3r/Point.hpp +++ b/xs/src/libslic3r/Point.hpp @@ -36,9 +36,16 @@ typedef std::vector Pointf3s; typedef Eigen::Matrix Vec2crd; typedef Eigen::Matrix Vec3crd; // Vector types with a double coordinate base type. +typedef Eigen::Matrix Vec2f; +typedef Eigen::Matrix Vec3f; typedef Eigen::Matrix Vec2d; typedef Eigen::Matrix Vec3d; +typedef Eigen::Transform Transform2f; +typedef Eigen::Transform Transform2d; +typedef Eigen::Transform Transform3f; +typedef Eigen::Transform Transform3d; + class Point { public: @@ -48,6 +55,8 @@ public: Point(coord_t x = 0, coord_t y = 0) { data(0) = x; data(1) = y; } Point(int64_t x, int64_t y) : Point(coord_t(x), coord_t(y)) {} // for Clipper Point(double x, double y) : Point(lrint(x), lrint(y)) {} + explicit Point(const Vec2crd &rhs) { this->data = rhs; } + explicit Point(Vec2crd &&rhs) { this->data = std::move(rhs); } static Point new_scale(coordf_t x, coordf_t y) { return Point(coord_t(scale_(x)), coord_t(scale_(y))); } const coord_t& x() const { return this->data[0]; } @@ -55,6 +64,13 @@ public: const coord_t& y() const { return this->data[1]; } coord_t& y() { return this->data[1]; } + operator const Vec2crd& () const { return this->data; } + operator Vec2crd& () { return this->data; } + template Eigen::Matrix cast() const { return this->data.cast(); } + + Point& operator=(const Vec2crd &rhs) { this->data = rhs; return *this; } + Point& operator=(Vec2crd &&rhs) { this->data = std::move(rhs); return *this; } + bool operator==(const Point& rhs) const { return this->x() == rhs.x() && this->y() == rhs.y(); } bool operator!=(const Point& rhs) const { return ! (*this == rhs); } bool operator<(const Point& rhs) const { return this->x() < rhs.x() || (this->x() == rhs.x() && this->y() < rhs.y()); } @@ -65,9 +81,9 @@ public: std::string wkt() const; std::string dump_perl() const; - void scale(double factor); - void translate(double x, double y); - void translate(const Vector &vector); + void scale(double factor) { this->data *= factor; } + void translate(double x, double y) { this->data += Vec2crd(x, y); } + void translate(const Vector &vector) { this->data += vector.data; } void rotate(double angle); void rotate(double angle, const Point ¢er); Point rotated(double angle) const { Point res(*this); res.rotate(angle); return res; } @@ -87,8 +103,8 @@ public: double ccw_angle(const Point &p1, const Point &p2) const; Point projection_onto(const MultiPoint &poly) const; Point projection_onto(const Line &line) const; - Point negative() const; - Vector vector_to(const Point &point) const; + Point negative() const { return Point(- this->data); } + Vector vector_to(const Point &point) const { return Vector(point.data - this->data); } }; inline Point operator+(const Point& point1, const Point& point2) { return Point(point1.x() + point2.x(), point1.y() + point2.y()); } @@ -207,23 +223,34 @@ private: coord_t m_grid_log2; }; -class Point3 : public Point +class Point3 { public: - coord_t m_z; + typedef coord_t coord_type; + Vec3crd data; - const coord_t& z() const { return this->m_z; } - coord_t& z() { return this->m_z; } + const coord_t& x() const { return this->data[0]; } + coord_t& x() { return this->data[0]; } + const coord_t& y() const { return this->data[1]; } + coord_t& y() { return this->data[1]; } + const coord_t& z() const { return this->data[2]; } + coord_t& z() { return this->data[2]; } - explicit Point3(coord_t _x = 0, coord_t _y = 0, coord_t _z = 0): Point(_x, _y), m_z(_z) {}; + operator const Vec3crd& () const { return this->data; } + operator Vec3crd& () { return this->data; } + template Eigen::Matrix cast() const { return this->data.cast(); } + + explicit Point3(coord_t _x = 0, coord_t _y = 0, coord_t _z = 0) { this->data[0] = _x; this->data[1] = _y; this->data[2] = _z; } + explicit Point3(const Vec3crd &rhs) { this->data = rhs; } + explicit Point3(Vec3crd &&rhs) { this->data = std::move(rhs); } static Point3 new_scale(coordf_t x, coordf_t y, coordf_t z) { return Point3(coord_t(scale_(x)), coord_t(scale_(y)), coord_t(scale_(z))); } + Point3& operator=(const Vec3crd &rhs) { this->data = rhs; return *this; } + Point3& operator=(Vec3crd &&rhs) { this->data = std::move(rhs); return *this; } bool operator==(const Point3 &rhs) const { return this->x() == rhs.x() && this->y() == rhs.y() && this->z() == rhs.z(); } bool operator!=(const Point3 &rhs) const { return ! (*this == rhs); } bool coincides_with(const Point3& rhs) const { return this->x() == rhs.x() && this->y() == rhs.y() && this->z() == rhs.z(); } -private: - // Hide the following inherited methods: - bool operator==(const Point &rhs) const; - bool operator!=(const Point &rhs) const; + + Point xy() const { return Point(this->x(), this->y()); } }; std::ostream& operator<<(std::ostream &stm, const Pointf &pointf); @@ -235,24 +262,31 @@ public: Vec2d data; explicit Pointf(coordf_t x = 0, coordf_t y = 0) { data(0) = x; data(1) = y; } + explicit Pointf(const Vec2d &rhs) { this->data = rhs; } + explicit Pointf(Vec2d &&rhs) { this->data = std::move(rhs); } static Pointf new_unscale(coord_t x, coord_t y) { return Pointf(unscale(x), unscale(y)); } static Pointf new_unscale(const Point &p) { return Pointf(unscale(p.x()), unscale(p.y())); } + Pointf& operator=(const Vec2d &rhs) { this->data = rhs; return *this; } + Pointf& operator=(Vec2d &&rhs) { this->data = std::move(rhs); return *this; } const coordf_t& x() const { return this->data[0]; } coordf_t& x() { return this->data[0]; } const coordf_t& y() const { return this->data[1]; } coordf_t& y() { return this->data[1]; } + operator const Vec2d& () const { return this->data; } + operator Vec2d& () { return this->data; } + template Eigen::Matrix cast() const { return this->data.cast(); } + std::string wkt() const; std::string dump_perl() const; - void scale(double factor); - void translate(double x, double y); - void translate(const Vectorf &vector); + void scale(double factor) { this->data *= factor; } + void translate(double x, double y) { this->data += Vec2d(x, y); } + void translate(const Vectorf &vector) { this->data += vector.data; } void rotate(double angle); void rotate(double angle, const Pointf ¢er); - Pointf negative() const; - Vectorf vector_to(const Pointf &point) const; - + Pointf negative() const { return Pointf(- this->data); } + Vectorf vector_to(const Pointf &point) const { return Vectorf(point.data - this->data); } Pointf& operator+=(const Pointf& rhs) { this->x() += rhs.x(); this->y() += rhs.y(); return *this; } Pointf& operator-=(const Pointf& rhs) { this->x() -= rhs.x(); this->y() -= rhs.y(); return *this; } Pointf& operator*=(const coordf_t& rhs) { this->x() *= rhs; this->y() *= rhs; return *this; } @@ -277,31 +311,42 @@ inline Vectorf normalize(const Vectorf& v) return (len != 0.0) ? 1.0 / len * v : Vectorf(0.0, 0.0); } -class Pointf3 : public Pointf +class Pointf3 { public: - coordf_t m_z; + typedef coordf_t coord_type; + Vec3d data; - const coordf_t& z() const { return this->m_z; } - coordf_t& z() { return this->m_z; } + const coordf_t& x() const { return this->data[0]; } + coordf_t& x() { return this->data[0]; } + const coordf_t& y() const { return this->data[1]; } + coordf_t& y() { return this->data[1]; } + const coordf_t& z() const { return this->data[2]; } + coordf_t& z() { return this->data[2]; } - explicit Pointf3(coordf_t _x = 0, coordf_t _y = 0, coordf_t _z = 0): Pointf(_x, _y), m_z(_z) {}; + operator const Vec3d& () const { return this->data; } + operator Vec3d& () { return this->data; } + template Eigen::Matrix cast() const { return this->data.cast(); } + + explicit Pointf3(coordf_t _x = 0, coordf_t _y = 0, coordf_t _z = 0) { this->data[0] = _x; this->data[1] = _y; this->data[2] = _z; } + explicit Pointf3(const Vec3d &rhs) { this->data = rhs; } + explicit Pointf3(Vec3d &&rhs) { this->data = std::move(rhs); } static Pointf3 new_unscale(coord_t x, coord_t y, coord_t z) { return Pointf3(unscale(x), unscale(y), unscale(z)); } static Pointf3 new_unscale(const Point3& p) { return Pointf3(unscale(p.x()), unscale(p.y()), unscale(p.z())); } - void scale(double factor); - void translate(const Vectorf3 &vector); - void translate(double x, double y, double z); - double distance_to(const Pointf3 &point) const; - Pointf3 negative() const; - Vectorf3 vector_to(const Pointf3 &point) const; + Pointf3& operator=(const Vec3d &rhs) { this->data = rhs; return *this; } + Pointf3& operator=(Vec3d &&rhs) { this->data = std::move(rhs); return *this; } + + void scale(double factor) { this->data *= factor; } + void translate(const Vectorf3 &vector) { this->data += vector.data; } + void translate(double x, double y, double z) { this->data += Vec3d(x, y, z); } + double distance_to(const Pointf3 &point) const { return (point.data - this->data).norm(); } + Pointf3 negative() const { return Pointf3(- this->data); } + Vectorf3 vector_to(const Pointf3 &point) const { return Vectorf3(point.data - this->data); } bool operator==(const Pointf3 &rhs) const { return this->x() == rhs.x() && this->y() == rhs.y() && this->z() == rhs.z(); } bool operator!=(const Pointf3 &rhs) const { return ! (*this == rhs); } -private: - // Hide the following inherited methods: - bool operator==(const Pointf &rhs) const; - bool operator!=(const Pointf &rhs) const; + Pointf xy() const { return Pointf(this->x(), this->y()); } }; inline Pointf3 operator+(const Pointf3& p1, const Pointf3& p2) { return Pointf3(p1.x() + p2.x(), p1.y() + p2.y(), p1.z() + p2.z()); } @@ -311,6 +356,9 @@ inline Pointf3 operator*(double scalar, const Pointf3& p) { return Pointf3(scala inline Pointf3 operator*(const Pointf3& p, double scalar) { return Pointf3(scalar * p.x(), scalar * p.y(), scalar * p.z()); } inline Pointf3 cross(const Pointf3& v1, const Pointf3& v2) { return Pointf3(v1.y() * v2.z() - v1.z() * v2.y(), v1.z() * v2.x() - v1.x() * v2.z(), v1.x() * v2.y() - v1.y() * v2.x()); } inline coordf_t dot(const Pointf3& v1, const Pointf3& v2) { return v1.x() * v2.x() + v1.y() * v2.y() + v1.z() * v2.z(); } +inline coordf_t dot(const Pointf3& v) { return v.x() * v.x() + v.y() * v.y() + v.z() * v.z(); } +inline double length(const Vectorf3 &v) { return sqrt(dot(v)); } +inline double l2(const Vectorf3 &v) { return dot(v); } inline Pointf3 normalize(const Pointf3& v) { coordf_t len = ::sqrt(sqr(v.x()) + sqr(v.y()) + sqr(v.z())); diff --git a/xs/src/libslic3r/Print.cpp b/xs/src/libslic3r/Print.cpp index 987297251..0dabfdaa7 100644 --- a/xs/src/libslic3r/Print.cpp +++ b/xs/src/libslic3r/Print.cpp @@ -726,7 +726,7 @@ BoundingBox Print::bounding_box() const for (const PrintObject *object : this->objects) for (Point copy : object->_shifted_copies) { bb.merge(copy); - copy.translate(object->size); + copy.translate(object->size.xy()); bb.merge(copy); } return bb; diff --git a/xs/src/libslic3r/Print.hpp b/xs/src/libslic3r/Print.hpp index bcd61ea02..470e47011 100644 --- a/xs/src/libslic3r/Print.hpp +++ b/xs/src/libslic3r/Print.hpp @@ -144,7 +144,7 @@ public: bool set_copies(const Points &points); bool reload_model_instances(); // since the object is aligned to origin, bounding box coincides with size - BoundingBox bounding_box() const { return BoundingBox(Point(0,0), this->size); } + BoundingBox bounding_box() const { return BoundingBox(Point(0,0), this->size.xy()); } // adds region_id, too, if necessary void add_region_volume(unsigned int region_id, int volume_id) { diff --git a/xs/src/libslic3r/SupportMaterial.cpp b/xs/src/libslic3r/SupportMaterial.cpp index f5cee401c..3fcefcff0 100644 --- a/xs/src/libslic3r/SupportMaterial.cpp +++ b/xs/src/libslic3r/SupportMaterial.cpp @@ -2359,7 +2359,7 @@ void modulate_extrusion_by_overlapping_layers( (fragment_end.is_start ? &polyline.points.front() : &polyline.points.back()); } private: - ExtrusionPathFragmentEndPointAccessor& operator=(const ExtrusionPathFragmentEndPointAccessor&); + ExtrusionPathFragmentEndPointAccessor& operator=(const ExtrusionPathFragmentEndPointAccessor&) = delete; const std::vector &m_path_fragments; }; const coord_t search_radius = 7; diff --git a/xs/src/libslic3r/TriangleMesh.cpp b/xs/src/libslic3r/TriangleMesh.cpp index d0d2f5fcb..9d4edc352 100644 --- a/xs/src/libslic3r/TriangleMesh.cpp +++ b/xs/src/libslic3r/TriangleMesh.cpp @@ -502,7 +502,7 @@ TriangleMesh::split() const int facet_idx = facet_queue.front(); facet_queue.pop(); if (seen_facets.find(facet_idx) != seen_facets.end()) continue; - facets.push_back(facet_idx); + facets.emplace_back(facet_idx); for (int j = 0; j <= 2; j++) { facet_queue.push(this->stl.neighbors_start[facet_idx].neighbor[j]); } @@ -510,7 +510,7 @@ TriangleMesh::split() const } TriangleMesh* mesh = new TriangleMesh; - meshes.push_back(mesh); + meshes.emplace_back(mesh); mesh->stl.stats.type = inmemory; mesh->stl.stats.number_of_facets = facets.size(); mesh->stl.stats.original_num_facets = mesh->stl.stats.number_of_facets; @@ -564,7 +564,7 @@ ExPolygons TriangleMesh::horizontal_projection() const p.points[1] = Point::new_scale(facet->vertex[1].x, facet->vertex[1].y); p.points[2] = Point::new_scale(facet->vertex[2].x, facet->vertex[2].y); p.make_counter_clockwise(); // do this after scaling, as winding order might change while doing that - pp.push_back(p); + pp.emplace_back(p); } // the offset factor was tuned using groovemount.stl @@ -819,10 +819,10 @@ void TriangleMeshSlicer::_slice_do(size_t facet_idx, std::vectory; il.a_id = a_id; il.b_id = b_id; - (*lines)[layer_idx].push_back(il); + (*lines)[layer_idx].emplace_back(il); } } else - (*lines)[layer_idx].push_back(il); + (*lines)[layer_idx].emplace_back(il); } } } @@ -1229,9 +1229,9 @@ void TriangleMeshSlicer::make_expolygons_simple(std::vector &l if (loop->area() >= 0.) { ExPolygon ex; ex.contour = *loop; - slices->push_back(ex); + slices->emplace_back(ex); } else { - holes.push_back(*loop); + holes.emplace_back(*loop); } } @@ -1322,8 +1322,8 @@ void TriangleMeshSlicer::make_expolygons(const Polygons &loops, ExPolygons* slic //std::vector area; //std::vector sorted_area; // vector of indices //for (Polygons::const_iterator loop = loops.begin(); loop != loops.end(); ++ loop) { - // area.push_back(loop->area()); - // sorted_area.push_back(loop - loops.begin()); + // area.emplace_back(loop->area()); + // sorted_area.emplace_back(loop - loops.begin()); //} // //// outer first @@ -1338,7 +1338,7 @@ void TriangleMeshSlicer::make_expolygons(const Polygons &loops, ExPolygons* slic // would do the same, thus repeating the calculation */ // Polygons::const_iterator loop = loops.begin() + *loop_idx; // if (area[*loop_idx] > +EPSILON) - // p_slices.push_back(*loop); + // p_slices.emplace_back(*loop); // else if (area[*loop_idx] < -EPSILON) // //FIXME This is arbitrary and possibly very slow. // // If the hole is inside a polygon, then there is no need to diff. @@ -1396,12 +1396,12 @@ void TriangleMeshSlicer::cut(float z, TriangleMesh* upper, TriangleMesh* lower) if (this->slice_facet(scaled_z, *facet, facet_idx, min_z, max_z, &line)) { // Save intersection lines for generating correct triangulations. if (line.edge_type == feTop) { - lower_lines.push_back(line); + lower_lines.emplace_back(line); } else if (line.edge_type == feBottom) { - upper_lines.push_back(line); + upper_lines.emplace_back(line); } else if (line.edge_type != feHorizontal) { - lower_lines.push_back(line); - upper_lines.push_back(line); + lower_lines.emplace_back(line); + upper_lines.emplace_back(line); } } @@ -1560,8 +1560,8 @@ TriangleMesh make_cylinder(double r, double h, double fa) { std::vector facets; // 2 special vertices, top and bottom center, rest are relative to this - vertices.push_back(Pointf3(0.0, 0.0, 0.0)); - vertices.push_back(Pointf3(0.0, 0.0, h)); + vertices.emplace_back(Pointf3(0.0, 0.0, 0.0)); + vertices.emplace_back(Pointf3(0.0, 0.0, h)); // adjust via rounding to get an even multiple for any provided angle. double angle = (2*PI / floor(2*PI / fa)); @@ -1571,26 +1571,24 @@ TriangleMesh make_cylinder(double r, double h, double fa) { // top and bottom. // Special case: Last line shares 2 vertices with the first line. unsigned id = vertices.size() - 1; - vertices.push_back(Pointf3(sin(0) * r , cos(0) * r, 0)); - vertices.push_back(Pointf3(sin(0) * r , cos(0) * r, h)); + vertices.emplace_back(Pointf3(sin(0) * r , cos(0) * r, 0)); + vertices.emplace_back(Pointf3(sin(0) * r , cos(0) * r, h)); for (double i = 0; i < 2*PI; i+=angle) { - Pointf3 b(0, r, 0); - Pointf3 t(0, r, h); - b.rotate(i, Pointf3(0,0,0)); - t.rotate(i, Pointf3(0,0,h)); - vertices.push_back(b); - vertices.push_back(t); + Pointf p(0, r); + p.rotate(i); + vertices.emplace_back(Pointf3(p.x(), p.y(), 0.)); + vertices.emplace_back(Pointf3(p.x(), p.y(), h)); id = vertices.size() - 1; - facets.push_back(Point3( 0, id - 1, id - 3)); // top - facets.push_back(Point3(id, 1, id - 2)); // bottom - facets.push_back(Point3(id, id - 2, id - 3)); // upper-right of side - facets.push_back(Point3(id, id - 3, id - 1)); // bottom-left of side + facets.emplace_back(Point3( 0, id - 1, id - 3)); // top + facets.emplace_back(Point3(id, 1, id - 2)); // bottom + facets.emplace_back(Point3(id, id - 2, id - 3)); // upper-right of side + facets.emplace_back(Point3(id, id - 3, id - 1)); // bottom-left of side } // Connect the last set of vertices with the first. - facets.push_back(Point3( 2, 0, id - 1)); - facets.push_back(Point3( 1, 3, id)); - facets.push_back(Point3(id, 3, 2)); - facets.push_back(Point3(id, 2, id - 1)); + facets.emplace_back(Point3( 2, 0, id - 1)); + facets.emplace_back(Point3( 1, 3, id)); + facets.emplace_back(Point3(id, 3, 2)); + facets.emplace_back(Point3(id, 2, id - 1)); TriangleMesh mesh(vertices, facets); return mesh; @@ -1613,29 +1611,25 @@ TriangleMesh make_sphere(double rho, double fa) { // Ring to be scaled to generate the steps of the sphere std::vector ring; for (double i = 0; i < 2*PI; i+=angle) { - ring.push_back(i); + ring.emplace_back(i); } const size_t steps = ring.size(); const double increment = (double)(1.0 / (double)steps); // special case: first ring connects to 0,0,0 // insert and form facets. - vertices.push_back(Pointf3(0.0, 0.0, -rho)); + vertices.emplace_back(Pointf3(0.0, 0.0, -rho)); size_t id = vertices.size(); for (size_t i = 0; i < ring.size(); i++) { // Fixed scaling const double z = -rho + increment*rho*2.0; // radius of the circle for this step. const double r = sqrt(abs(rho*rho - z*z)); - Pointf3 b(0, r, z); - b.rotate(ring[i], Pointf3(0,0,z)); - vertices.push_back(b); - if (i == 0) { - facets.push_back(Point3(1, 0, ring.size())); - } else { - facets.push_back(Point3(id, 0, id - 1)); - } - id++; + Pointf b(0, r); + b.rotate(ring[i]); + vertices.emplace_back(Pointf3(b.x(), b.y(), z)); + facets.emplace_back((i == 0) ? Point3(1, 0, ring.size()) : Point3(id, 0, id - 1)); + ++ id; } // General case: insert and form facets for each step, joining it to the ring below it. @@ -1644,16 +1638,16 @@ TriangleMesh make_sphere(double rho, double fa) { const double r = sqrt(abs(rho*rho - z*z)); for (size_t i = 0; i < ring.size(); i++) { - Pointf3 b(0, r, z); - b.rotate(ring[i], Pointf3(0,0,z)); - vertices.push_back(b); + Pointf b(0, r); + b.rotate(ring[i]); + vertices.emplace_back(Pointf3(b.x(), b.y(), z)); if (i == 0) { // wrap around - facets.push_back(Point3(id + ring.size() - 1 , id, id - 1)); - facets.push_back(Point3(id, id - ring.size(), id - 1)); + facets.emplace_back(Point3(id + ring.size() - 1 , id, id - 1)); + facets.emplace_back(Point3(id, id - ring.size(), id - 1)); } else { - facets.push_back(Point3(id , id - ring.size(), (id - 1) - ring.size())); - facets.push_back(Point3(id, id - 1 - ring.size() , id - 1)); + facets.emplace_back(Point3(id , id - ring.size(), (id - 1) - ring.size())); + facets.emplace_back(Point3(id, id - 1 - ring.size() , id - 1)); } id++; } @@ -1662,13 +1656,13 @@ TriangleMesh make_sphere(double rho, double fa) { // special case: last ring connects to 0,0,rho*2.0 // only form facets. - vertices.push_back(Pointf3(0.0, 0.0, rho)); + vertices.emplace_back(Pointf3(0.0, 0.0, rho)); for (size_t i = 0; i < ring.size(); i++) { if (i == 0) { // third vertex is on the other side of the ring. - facets.push_back(Point3(id, id - ring.size(), id - 1)); + facets.emplace_back(Point3(id, id - ring.size(), id - 1)); } else { - facets.push_back(Point3(id, id - ring.size() + i, id - ring.size() + (i - 1))); + facets.emplace_back(Point3(id, id - ring.size() + i, id - ring.size() + (i - 1))); } } id++; diff --git a/xs/src/slic3r/GUI/3DScene.cpp b/xs/src/slic3r/GUI/3DScene.cpp index 51e915a57..618cdbb1a 100644 --- a/xs/src/slic3r/GUI/3DScene.cpp +++ b/xs/src/slic3r/GUI/3DScene.cpp @@ -26,11 +26,6 @@ #include "GUI.hpp" -static const float UNIT_MATRIX[] = { 1.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 1.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 1.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f }; - namespace Slic3r { void GLIndexedVertexArray::load_mesh_flat_shading(const TriangleMesh &mesh) @@ -218,7 +213,7 @@ GLVolume::GLVolume(float r, float g, float b, float a) , tverts_range(0, size_t(-1)) , qverts_range(0, size_t(-1)) { - m_world_mat = std::vector(UNIT_MATRIX, std::end(UNIT_MATRIX)); + m_world_mat = Transform3f::Identity(); color[0] = r; color[1] = g; @@ -279,15 +274,14 @@ void GLVolume::set_scale_factor(float scale_factor) m_dirty = true; } -const std::vector& GLVolume::world_matrix() const +const Transform3f& GLVolume::world_matrix() const { if (m_dirty) { - Eigen::Transform m = Eigen::Transform::Identity(); - m.translate(Eigen::Vector3f((float)m_origin.x(), (float)m_origin.y(), (float)m_origin.z())); - m.rotate(Eigen::AngleAxisf(m_angle_z, Eigen::Vector3f::UnitZ())); - m.scale(m_scale_factor); - ::memcpy((void*)m_world_mat.data(), (const void*)m.data(), 16 * sizeof(float)); + m_world_mat = Transform3f::Identity(); + m_world_mat.translate(Vec3f(m_origin.x(), m_origin.y(), 0)); + m_world_mat.rotate(Eigen::AngleAxisf(m_angle_z, Eigen::Vector3f::UnitZ())); + m_world_mat.scale(m_scale_factor); m_dirty = false; } diff --git a/xs/src/slic3r/GUI/3DScene.hpp b/xs/src/slic3r/GUI/3DScene.hpp index 42666a955..1d56f2f73 100644 --- a/xs/src/slic3r/GUI/3DScene.hpp +++ b/xs/src/slic3r/GUI/3DScene.hpp @@ -261,7 +261,7 @@ private: // Scale factor of the volume to be rendered. float m_scale_factor; // World matrix of the volume to be rendered. - std::vector m_world_mat; + mutable Transform3f m_world_mat; // Bounding box of this volume, in unscaled coordinates. mutable BoundingBoxf3 m_transformed_bounding_box; // Whether or not is needed to recalculate the world matrix. @@ -326,7 +326,7 @@ public: int volume_idx() const { return (this->composite_id / 1000) % 1000; } int instance_idx() const { return this->composite_id % 1000; } - const std::vector& world_matrix() const; + const Transform3f& world_matrix() const; BoundingBoxf3 transformed_bounding_box() const; bool empty() const { return this->indexed_vertex_array.empty(); } diff --git a/xs/src/slic3r/GUI/GLGizmo.cpp b/xs/src/slic3r/GUI/GLGizmo.cpp index b67a5bedc..d31965b74 100644 --- a/xs/src/slic3r/GUI/GLGizmo.cpp +++ b/xs/src/slic3r/GUI/GLGizmo.cpp @@ -262,8 +262,8 @@ void GLGizmoRotate::on_render(const BoundingBoxf3& box) const { ::glDisable(GL_DEPTH_TEST); - const Pointf3& size = box.size(); - m_center = box.center(); + const Pointf size = box.size().xy(); + m_center = box.center().xy(); if (!m_keep_radius) { m_radius = Offset + ::sqrt(sqr(0.5f * size.x()) + sqr(0.5f * size.y()));