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.
This commit is contained in:
bubnikv 2018-08-14 21:33:41 +02:00
parent 86da661097
commit f34252a27b
15 changed files with 197 additions and 303 deletions

View file

@ -253,9 +253,9 @@ void BoundingBox::align_to_grid(const coord_t cell_size)
}
}
BoundingBoxf3 BoundingBoxf3::transformed(const std::vector<float>& matrix) const
BoundingBoxf3 BoundingBoxf3::transformed(const Transform3f& matrix) const
{
Eigen::Matrix<float, 3, 8> vertices;
Eigen::Matrix<float, 3, 8, Eigen::DontAlign> 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<float>& 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<float, 3, Eigen::Affine> m;
::memcpy((void*)m.data(), (const void*)matrix.data(), 16 * sizeof(float));
Eigen::Matrix<float, 3, 8> transf_vertices = m * vertices.colwise().homogeneous();
Eigen::Matrix<float, 3, 8, Eigen::DontAlign> transf_vertices = matrix * vertices.colwise().homogeneous();
float min_x = transf_vertices(0, 0);
float max_x = transf_vertices(0, 0);

View file

@ -153,7 +153,7 @@ public:
BoundingBoxf3(const Pointf3 &pmin, const Pointf3 &pmax) : BoundingBox3Base<Pointf3>(pmin, pmax) {};
BoundingBoxf3(const std::vector<Pointf3> &points) : BoundingBox3Base<Pointf3>(points) {};
BoundingBoxf3 transformed(const std::vector<float>& matrix) const;
BoundingBoxf3 transformed(const Transform3f& matrix) const;
};
template<typename VT>

View file

@ -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

View file

@ -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

View file

@ -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<float, 3, Eigen::Affine> matrix = Eigen::Transform<float, 3, Eigen::Affine>::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<float> 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

View file

@ -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 &center)
void MultiPoint::rotate(double angle, const Point &center)
{
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;
}

View file

@ -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 &center)
void Point::rotate(double angle, const Point &center)
{
double cur_x = (double)this->x();
double cur_y = (double)this->y();
@ -65,14 +42,12 @@ Point::rotate(double angle, const Point &center)
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 &center)
void Pointf::rotate(double angle, const Pointf &center)
{
double cur_x = this->x();
double cur_y = this->y();
@ -315,59 +244,6 @@ Pointf::rotate(double angle, const Pointf &center)
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)

View file

@ -36,9 +36,16 @@ typedef std::vector<Pointf3> Pointf3s;
typedef Eigen::Matrix<coord_t, 2, 1, Eigen::DontAlign> Vec2crd;
typedef Eigen::Matrix<coord_t, 3, 1, Eigen::DontAlign> Vec3crd;
// 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<coordf_t, 2, 1, Eigen::DontAlign> Vec2d;
typedef Eigen::Matrix<coordf_t, 3, 1, Eigen::DontAlign> Vec3d;
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;
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<typename T> Eigen::Matrix<T, 2, 1, Eigen::DontAlign> cast() const { return this->data.cast<T>(); }
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 &center);
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<typename T> Eigen::Matrix<T, 3, 1, Eigen::DontAlign> cast() const { return this->data.cast<T>(); }
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<typename T> Eigen::Matrix<T, 2, 1, Eigen::DontAlign> cast() const { return this->data.cast<T>(); }
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 &center);
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<typename T> Eigen::Matrix<T, 3, 1, Eigen::DontAlign> cast() const { return this->data.cast<T>(); }
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()));

View file

@ -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;

View file

@ -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) {

View file

@ -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<ExtrusionPathFragment> &m_path_fragments;
};
const coord_t search_radius = 7;

View file

@ -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::vector<IntersectionLin
il.b.y() = b->y;
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<IntersectionLine> &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<double> area;
//std::vector<size_t> 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<Point3> 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<double> 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++;

View file

@ -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<float>(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<float>& GLVolume::world_matrix() const
const Transform3f& GLVolume::world_matrix() const
{
if (m_dirty)
{
Eigen::Transform<float, 3, Eigen::Affine> m = Eigen::Transform<float, 3, Eigen::Affine>::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;
}

View file

@ -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<float> 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<float>& world_matrix() const;
const Transform3f& world_matrix() const;
BoundingBoxf3 transformed_bounding_box() const;
bool empty() const { return this->indexed_vertex_array.empty(); }

View file

@ -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()));