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

github.com/supermerill/SuperSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'xs/src/libslic3r')
-rw-r--r--xs/src/libslic3r/BoundingBox.cpp202
-rw-r--r--xs/src/libslic3r/BoundingBox.hpp92
-rw-r--r--xs/src/libslic3r/BridgeDetector.cpp26
-rw-r--r--xs/src/libslic3r/ClipperUtils.cpp16
-rw-r--r--xs/src/libslic3r/Config.hpp34
-rw-r--r--xs/src/libslic3r/EdgeGrid.cpp296
-rw-r--r--xs/src/libslic3r/ExPolygon.cpp163
-rw-r--r--xs/src/libslic3r/ExPolygon.hpp1
-rw-r--r--xs/src/libslic3r/ExtrusionEntity.cpp2
-rw-r--r--xs/src/libslic3r/ExtrusionEntity.hpp2
-rw-r--r--xs/src/libslic3r/ExtrusionEntityCollection.hpp11
-rw-r--r--xs/src/libslic3r/ExtrusionSimulator.cpp44
-rw-r--r--xs/src/libslic3r/Fill/Fill3DHoneycomb.cpp18
-rw-r--r--xs/src/libslic3r/Fill/FillBase.hpp4
-rw-r--r--xs/src/libslic3r/Fill/FillConcentric.cpp4
-rw-r--r--xs/src/libslic3r/Fill/FillGyroid.cpp54
-rw-r--r--xs/src/libslic3r/Fill/FillHoneycomb.cpp8
-rw-r--r--xs/src/libslic3r/Fill/FillPlanePath.cpp60
-rw-r--r--xs/src/libslic3r/Fill/FillRectilinear.cpp28
-rw-r--r--xs/src/libslic3r/Fill/FillRectilinear2.cpp72
-rw-r--r--xs/src/libslic3r/Fill/FillRectilinear3.cpp122
-rw-r--r--xs/src/libslic3r/Format/3mf.cpp14
-rw-r--r--xs/src/libslic3r/Format/AMF.cpp16
-rw-r--r--xs/src/libslic3r/Format/OBJ.cpp34
-rw-r--r--xs/src/libslic3r/Format/PRUS.cpp22
-rw-r--r--xs/src/libslic3r/GCode.cpp127
-rw-r--r--xs/src/libslic3r/GCode.hpp13
-rw-r--r--xs/src/libslic3r/GCode/Analyzer.cpp40
-rw-r--r--xs/src/libslic3r/GCode/Analyzer.hpp16
-rw-r--r--xs/src/libslic3r/GCode/CoolingBuffer.cpp8
-rw-r--r--xs/src/libslic3r/GCode/PreviewData.cpp2
-rw-r--r--xs/src/libslic3r/GCode/PreviewData.hpp4
-rw-r--r--xs/src/libslic3r/GCode/PrintExtents.cpp57
-rw-r--r--xs/src/libslic3r/GCode/WipeTower.hpp3
-rw-r--r--xs/src/libslic3r/GCodeWriter.cpp58
-rw-r--r--xs/src/libslic3r/GCodeWriter.hpp12
-rw-r--r--xs/src/libslic3r/Geometry.cpp248
-rw-r--r--xs/src/libslic3r/Geometry.hpp36
-rw-r--r--xs/src/libslic3r/Layer.cpp8
-rw-r--r--xs/src/libslic3r/LayerRegion.cpp8
-rw-r--r--xs/src/libslic3r/Line.cpp265
-rw-r--r--xs/src/libslic3r/Line.hpp101
-rw-r--r--xs/src/libslic3r/Model.cpp151
-rw-r--r--xs/src/libslic3r/Model.hpp20
-rw-r--r--xs/src/libslic3r/ModelArrange.hpp26
-rw-r--r--xs/src/libslic3r/MotionPlanner.cpp10
-rw-r--r--xs/src/libslic3r/MultiPoint.cpp125
-rw-r--r--xs/src/libslic3r/MultiPoint.hpp12
-rw-r--r--xs/src/libslic3r/PerimeterGenerator.cpp158
-rw-r--r--xs/src/libslic3r/PlaceholderParser.cpp2
-rw-r--r--xs/src/libslic3r/Point.cpp317
-rw-r--r--xs/src/libslic3r/Point.hpp296
-rw-r--r--xs/src/libslic3r/Polygon.cpp67
-rw-r--r--xs/src/libslic3r/Polygon.hpp12
-rw-r--r--xs/src/libslic3r/Polyline.cpp126
-rw-r--r--xs/src/libslic3r/Polyline.hpp27
-rw-r--r--xs/src/libslic3r/PolylineCollection.cpp10
-rw-r--r--xs/src/libslic3r/Print.cpp14
-rw-r--r--xs/src/libslic3r/Print.hpp6
-rw-r--r--xs/src/libslic3r/PrintConfig.cpp6
-rw-r--r--xs/src/libslic3r/PrintObject.cpp23
-rw-r--r--xs/src/libslic3r/SVG.cpp52
-rw-r--r--xs/src/libslic3r/Slicing.cpp54
-rw-r--r--xs/src/libslic3r/SlicingAdaptive.cpp6
-rw-r--r--xs/src/libslic3r/SupportMaterial.cpp60
-rw-r--r--xs/src/libslic3r/Surface.cpp6
-rw-r--r--xs/src/libslic3r/SurfaceCollection.cpp4
-rw-r--r--xs/src/libslic3r/TriangleMesh.cpp553
-rw-r--r--xs/src/libslic3r/TriangleMesh.hpp44
-rw-r--r--xs/src/libslic3r/libslic3r.h15
70 files changed, 1938 insertions, 2615 deletions
diff --git a/xs/src/libslic3r/BoundingBox.cpp b/xs/src/libslic3r/BoundingBox.cpp
index 4355cd61b..d3cca7ff2 100644
--- a/xs/src/libslic3r/BoundingBox.cpp
+++ b/xs/src/libslic3r/BoundingBox.cpp
@@ -7,9 +7,9 @@
namespace Slic3r {
template BoundingBoxBase<Point>::BoundingBoxBase(const std::vector<Point> &points);
-template BoundingBoxBase<Pointf>::BoundingBoxBase(const std::vector<Pointf> &points);
+template BoundingBoxBase<Vec2d>::BoundingBoxBase(const std::vector<Vec2d> &points);
-template BoundingBox3Base<Pointf3>::BoundingBox3Base(const std::vector<Pointf3> &points);
+template BoundingBox3Base<Vec3d>::BoundingBox3Base(const std::vector<Vec3d> &points);
BoundingBox::BoundingBox(const Lines &lines)
{
@@ -22,23 +22,21 @@ BoundingBox::BoundingBox(const Lines &lines)
*this = BoundingBox(points);
}
-void
-BoundingBox::polygon(Polygon* polygon) const
+void BoundingBox::polygon(Polygon* polygon) const
{
polygon->points.clear();
polygon->points.resize(4);
- polygon->points[0].x = this->min.x;
- polygon->points[0].y = this->min.y;
- polygon->points[1].x = this->max.x;
- polygon->points[1].y = this->min.y;
- polygon->points[2].x = this->max.x;
- polygon->points[2].y = this->max.y;
- polygon->points[3].x = this->min.x;
- polygon->points[3].y = this->max.y;
+ polygon->points[0](0) = this->min(0);
+ polygon->points[0](1) = this->min(1);
+ polygon->points[1](0) = this->max(0);
+ polygon->points[1](1) = this->min(1);
+ polygon->points[2](0) = this->max(0);
+ polygon->points[2](1) = this->max(1);
+ polygon->points[3](0) = this->min(0);
+ polygon->points[3](1) = this->max(1);
}
-Polygon
-BoundingBox::polygon() const
+Polygon BoundingBox::polygon() const
{
Polygon p;
this->polygon(&p);
@@ -50,8 +48,8 @@ BoundingBox BoundingBox::rotated(double angle) const
BoundingBox out;
out.merge(this->min.rotated(angle));
out.merge(this->max.rotated(angle));
- out.merge(Point(this->min.x, this->max.y).rotated(angle));
- out.merge(Point(this->max.x, this->min.y).rotated(angle));
+ out.merge(Point(this->min(0), this->max(1)).rotated(angle));
+ out.merge(Point(this->max(0), this->min(1)).rotated(angle));
return out;
}
@@ -60,36 +58,35 @@ BoundingBox BoundingBox::rotated(double angle, const Point &center) const
BoundingBox out;
out.merge(this->min.rotated(angle, center));
out.merge(this->max.rotated(angle, center));
- out.merge(Point(this->min.x, this->max.y).rotated(angle, center));
- out.merge(Point(this->max.x, this->min.y).rotated(angle, center));
+ out.merge(Point(this->min(0), this->max(1)).rotated(angle, center));
+ out.merge(Point(this->max(0), this->min(1)).rotated(angle, center));
return out;
}
template <class PointClass> void
BoundingBoxBase<PointClass>::scale(double factor)
{
- this->min.scale(factor);
- this->max.scale(factor);
+ this->min *= factor;
+ this->max *= factor;
}
template void BoundingBoxBase<Point>::scale(double factor);
-template void BoundingBoxBase<Pointf>::scale(double factor);
-template void BoundingBoxBase<Pointf3>::scale(double factor);
+template void BoundingBoxBase<Vec2d>::scale(double factor);
+template void BoundingBoxBase<Vec3d>::scale(double factor);
template <class PointClass> void
BoundingBoxBase<PointClass>::merge(const PointClass &point)
{
if (this->defined) {
- this->min.x = std::min(point.x, this->min.x);
- this->min.y = std::min(point.y, this->min.y);
- this->max.x = std::max(point.x, this->max.x);
- this->max.y = std::max(point.y, this->max.y);
+ this->min = this->min.cwiseMin(point);
+ this->max = this->max.cwiseMax(point);
} else {
- this->min = this->max = point;
+ this->min = point;
+ this->max = point;
this->defined = true;
}
}
template void BoundingBoxBase<Point>::merge(const Point &point);
-template void BoundingBoxBase<Pointf>::merge(const Pointf &point);
+template void BoundingBoxBase<Vec2d>::merge(const Vec2d &point);
template <class PointClass> void
BoundingBoxBase<PointClass>::merge(const std::vector<PointClass> &points)
@@ -97,18 +94,16 @@ BoundingBoxBase<PointClass>::merge(const std::vector<PointClass> &points)
this->merge(BoundingBoxBase(points));
}
template void BoundingBoxBase<Point>::merge(const Points &points);
-template void BoundingBoxBase<Pointf>::merge(const Pointfs &points);
+template void BoundingBoxBase<Vec2d>::merge(const Pointfs &points);
template <class PointClass> void
BoundingBoxBase<PointClass>::merge(const BoundingBoxBase<PointClass> &bb)
{
- assert(bb.defined || bb.min.x >= bb.max.x || bb.min.y >= bb.max.y);
+ assert(bb.defined || bb.min(0) >= bb.max(0) || bb.min(1) >= bb.max(1));
if (bb.defined) {
if (this->defined) {
- this->min.x = std::min(bb.min.x, this->min.x);
- this->min.y = std::min(bb.min.y, this->min.y);
- this->max.x = std::max(bb.max.x, this->max.x);
- this->max.y = std::max(bb.max.y, this->max.y);
+ this->min = this->min.cwiseMin(bb.min);
+ this->max = this->max.cwiseMax(bb.max);
} else {
this->min = bb.min;
this->max = bb.max;
@@ -117,120 +112,121 @@ BoundingBoxBase<PointClass>::merge(const BoundingBoxBase<PointClass> &bb)
}
}
template void BoundingBoxBase<Point>::merge(const BoundingBoxBase<Point> &bb);
-template void BoundingBoxBase<Pointf>::merge(const BoundingBoxBase<Pointf> &bb);
+template void BoundingBoxBase<Vec2d>::merge(const BoundingBoxBase<Vec2d> &bb);
template <class PointClass> void
BoundingBox3Base<PointClass>::merge(const PointClass &point)
{
if (this->defined) {
- this->min.z = std::min(point.z, this->min.z);
- this->max.z = std::max(point.z, this->max.z);
+ this->min = this->min.cwiseMin(point);
+ this->max = this->max.cwiseMax(point);
+ } else {
+ this->min = point;
+ this->max = point;
+ this->defined = true;
}
- BoundingBoxBase<PointClass>::merge(point);
}
-template void BoundingBox3Base<Pointf3>::merge(const Pointf3 &point);
+template void BoundingBox3Base<Vec3d>::merge(const Vec3d &point);
template <class PointClass> void
BoundingBox3Base<PointClass>::merge(const std::vector<PointClass> &points)
{
this->merge(BoundingBox3Base(points));
}
-template void BoundingBox3Base<Pointf3>::merge(const Pointf3s &points);
+template void BoundingBox3Base<Vec3d>::merge(const Pointf3s &points);
template <class PointClass> void
BoundingBox3Base<PointClass>::merge(const BoundingBox3Base<PointClass> &bb)
{
- assert(bb.defined || bb.min.x >= bb.max.x || bb.min.y >= bb.max.y || bb.min.z >= bb.max.z);
+ assert(bb.defined || bb.min(0) >= bb.max(0) || bb.min(1) >= bb.max(1) || bb.min(2) >= bb.max(2));
if (bb.defined) {
if (this->defined) {
- this->min.z = std::min(bb.min.z, this->min.z);
- this->max.z = std::max(bb.max.z, this->max.z);
+ this->min = this->min.cwiseMin(bb.min);
+ this->max = this->max.cwiseMax(bb.max);
+ } else {
+ this->min = bb.min;
+ this->max = bb.max;
+ this->defined = true;
}
- BoundingBoxBase<PointClass>::merge(bb);
}
}
-template void BoundingBox3Base<Pointf3>::merge(const BoundingBox3Base<Pointf3> &bb);
+template void BoundingBox3Base<Vec3d>::merge(const BoundingBox3Base<Vec3d> &bb);
template <class PointClass> PointClass
BoundingBoxBase<PointClass>::size() const
{
- return PointClass(this->max.x - this->min.x, this->max.y - this->min.y);
+ return PointClass(this->max(0) - this->min(0), this->max(1) - this->min(1));
}
template Point BoundingBoxBase<Point>::size() const;
-template Pointf BoundingBoxBase<Pointf>::size() const;
+template Vec2d BoundingBoxBase<Vec2d>::size() const;
template <class PointClass> PointClass
BoundingBox3Base<PointClass>::size() const
{
- return PointClass(this->max.x - this->min.x, this->max.y - this->min.y, this->max.z - this->min.z);
+ return PointClass(this->max(0) - this->min(0), this->max(1) - this->min(1), this->max(2) - this->min(2));
}
-template Pointf3 BoundingBox3Base<Pointf3>::size() const;
+template Vec3d BoundingBox3Base<Vec3d>::size() const;
template <class PointClass> double BoundingBoxBase<PointClass>::radius() const
{
assert(this->defined);
- double x = this->max.x - this->min.x;
- double y = this->max.y - this->min.y;
+ double x = this->max(0) - this->min(0);
+ double y = this->max(1) - this->min(1);
return 0.5 * sqrt(x*x+y*y);
}
template double BoundingBoxBase<Point>::radius() const;
-template double BoundingBoxBase<Pointf>::radius() const;
+template double BoundingBoxBase<Vec2d>::radius() const;
template <class PointClass> double BoundingBox3Base<PointClass>::radius() const
{
- double x = this->max.x - this->min.x;
- double y = this->max.y - this->min.y;
- double z = this->max.z - this->min.z;
+ double x = this->max(0) - this->min(0);
+ double y = this->max(1) - this->min(1);
+ double z = this->max(2) - this->min(2);
return 0.5 * sqrt(x*x+y*y+z*z);
}
-template double BoundingBox3Base<Pointf3>::radius() const;
+template double BoundingBox3Base<Vec3d>::radius() const;
template <class PointClass> void
BoundingBoxBase<PointClass>::offset(coordf_t delta)
{
- this->min.translate(-delta, -delta);
- this->max.translate(delta, delta);
+ PointClass v(delta, delta);
+ this->min -= v;
+ this->max += v;
}
template void BoundingBoxBase<Point>::offset(coordf_t delta);
-template void BoundingBoxBase<Pointf>::offset(coordf_t delta);
+template void BoundingBoxBase<Vec2d>::offset(coordf_t delta);
template <class PointClass> void
BoundingBox3Base<PointClass>::offset(coordf_t delta)
{
- this->min.translate(-delta, -delta, -delta);
- this->max.translate(delta, delta, delta);
+ PointClass v(delta, delta, delta);
+ this->min -= v;
+ this->max += v;
}
-template void BoundingBox3Base<Pointf3>::offset(coordf_t delta);
+template void BoundingBox3Base<Vec3d>::offset(coordf_t delta);
template <class PointClass> PointClass
BoundingBoxBase<PointClass>::center() const
{
- return PointClass(
- (this->max.x + this->min.x)/2,
- (this->max.y + this->min.y)/2
- );
+ return (this->min + this->max) / 2;
}
template Point BoundingBoxBase<Point>::center() const;
-template Pointf BoundingBoxBase<Pointf>::center() const;
+template Vec2d BoundingBoxBase<Vec2d>::center() const;
template <class PointClass> PointClass
BoundingBox3Base<PointClass>::center() const
{
- return PointClass(
- (this->max.x + this->min.x)/2,
- (this->max.y + this->min.y)/2,
- (this->max.z + this->min.z)/2
- );
+ return (this->min + this->max) / 2;
}
-template Pointf3 BoundingBox3Base<Pointf3>::center() const;
+template Vec3d BoundingBox3Base<Vec3d>::center() const;
template <class PointClass> coordf_t
BoundingBox3Base<PointClass>::max_size() const
{
PointClass s = size();
- return std::max(s.x, std::max(s.y, s.z));
+ return std::max(s(0), std::max(s(1), s(2)));
}
-template coordf_t BoundingBox3Base<Pointf3>::max_size() const;
+template coordf_t BoundingBox3Base<Vec3d>::max_size() const;
// Align a coordinate to a grid. The coordinate may be negative,
// the aligned value will never be bigger than the original one.
@@ -248,46 +244,40 @@ static inline coord_t _align_to_grid(const coord_t coord, const coord_t spacing)
void BoundingBox::align_to_grid(const coord_t cell_size)
{
if (this->defined) {
- min.x = _align_to_grid(min.x, cell_size);
- min.y = _align_to_grid(min.y, cell_size);
+ min(0) = _align_to_grid(min(0), cell_size);
+ min(1) = _align_to_grid(min(1), cell_size);
}
}
-BoundingBoxf3 BoundingBoxf3::transformed(const std::vector<float>& matrix) const
+BoundingBoxf3 BoundingBoxf3::transformed(const Transform3d& matrix) const
{
- Eigen::Matrix<float, 3, 8> 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;
- vertices(0, 2) = (float)max.x; vertices(1, 2) = (float)max.y; vertices(2, 2) = (float)min.z;
- vertices(0, 3) = (float)min.x; vertices(1, 3) = (float)max.y; vertices(2, 3) = (float)min.z;
- vertices(0, 4) = (float)min.x; vertices(1, 4) = (float)min.y; vertices(2, 4) = (float)max.z;
- vertices(0, 5) = (float)max.x; vertices(1, 5) = (float)min.y; vertices(2, 5) = (float)max.z;
- 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();
-
- float min_x = transf_vertices(0, 0);
- float max_x = transf_vertices(0, 0);
- float min_y = transf_vertices(1, 0);
- float max_y = transf_vertices(1, 0);
- float min_z = transf_vertices(2, 0);
- float max_z = transf_vertices(2, 0);
+ typedef Eigen::Matrix<double, 3, 8, Eigen::DontAlign> Vertices;
+
+ Vertices src_vertices;
+ src_vertices(0, 0) = min(0); src_vertices(1, 0) = min(1); src_vertices(2, 0) = min(2);
+ src_vertices(0, 1) = max(0); src_vertices(1, 1) = min(1); src_vertices(2, 1) = min(2);
+ src_vertices(0, 2) = max(0); src_vertices(1, 2) = max(1); src_vertices(2, 2) = min(2);
+ src_vertices(0, 3) = min(0); src_vertices(1, 3) = max(1); src_vertices(2, 3) = min(2);
+ src_vertices(0, 4) = min(0); src_vertices(1, 4) = min(1); src_vertices(2, 4) = max(2);
+ src_vertices(0, 5) = max(0); src_vertices(1, 5) = min(1); src_vertices(2, 5) = max(2);
+ src_vertices(0, 6) = max(0); src_vertices(1, 6) = max(1); src_vertices(2, 6) = max(2);
+ src_vertices(0, 7) = min(0); src_vertices(1, 7) = max(1); src_vertices(2, 7) = max(2);
+
+ Vertices dst_vertices = matrix * src_vertices.colwise().homogeneous();
+
+ Vec3d v_min(dst_vertices(0, 0), dst_vertices(1, 0), dst_vertices(2, 0));
+ Vec3d v_max = v_min;
for (int i = 1; i < 8; ++i)
{
- min_x = std::min(min_x, transf_vertices(0, i));
- max_x = std::max(max_x, transf_vertices(0, i));
- min_y = std::min(min_y, transf_vertices(1, i));
- max_y = std::max(max_y, transf_vertices(1, i));
- min_z = std::min(min_z, transf_vertices(2, i));
- max_z = std::max(max_z, transf_vertices(2, i));
+ for (int j = 0; j < 3; ++j)
+ {
+ v_min(j) = std::min(v_min(j), dst_vertices(j, i));
+ v_max(j) = std::max(v_max(j), dst_vertices(j, i));
+ }
}
- return BoundingBoxf3(Pointf3((coordf_t)min_x, (coordf_t)min_y, (coordf_t)min_z), Pointf3((coordf_t)max_x, (coordf_t)max_y, (coordf_t)max_z));
+ return BoundingBoxf3(v_min, v_max);
}
}
diff --git a/xs/src/libslic3r/BoundingBox.hpp b/xs/src/libslic3r/BoundingBox.hpp
index 5324dbe3b..db56c765c 100644
--- a/xs/src/libslic3r/BoundingBox.hpp
+++ b/xs/src/libslic3r/BoundingBox.hpp
@@ -7,11 +7,6 @@
namespace Slic3r {
-typedef Point Size;
-typedef Point3 Size3;
-typedef Pointf Sizef;
-typedef Pointf3 Sizef3;
-
template <class PointClass>
class BoundingBoxBase
{
@@ -20,25 +15,22 @@ public:
PointClass max;
bool defined;
- BoundingBoxBase() : defined(false) {};
+ BoundingBoxBase() : defined(false), min(PointClass::Zero()), max(PointClass::Zero()) {}
BoundingBoxBase(const PointClass &pmin, const PointClass &pmax) :
- min(pmin), max(pmax), defined(pmin.x < pmax.x && pmin.y < pmax.y) {}
- BoundingBoxBase(const std::vector<PointClass>& points)
+ min(pmin), max(pmax), defined(pmin(0) < pmax(0) && pmin(1) < pmax(1)) {}
+ BoundingBoxBase(const std::vector<PointClass>& points) : min(PointClass::Zero()), max(PointClass::Zero())
{
if (points.empty())
CONFESS("Empty point set supplied to BoundingBoxBase constructor");
typename std::vector<PointClass>::const_iterator it = points.begin();
- this->min.x = this->max.x = it->x;
- this->min.y = this->max.y = it->y;
- for (++it; it != points.end(); ++it)
- {
- this->min.x = std::min(it->x, this->min.x);
- this->min.y = std::min(it->y, this->min.y);
- this->max.x = std::max(it->x, this->max.x);
- this->max.y = std::max(it->y, this->max.y);
+ this->min = *it;
+ this->max = *it;
+ for (++ it; it != points.end(); ++ it) {
+ this->min = this->min.cwiseMin(*it);
+ this->max = this->max.cwiseMax(*it);
}
- this->defined = (this->min.x < this->max.x) && (this->min.y < this->max.y);
+ this->defined = (this->min(0) < this->max(0)) && (this->min(1) < this->max(1));
}
void merge(const PointClass &point);
void merge(const std::vector<PointClass> &points);
@@ -46,17 +38,17 @@ public:
void scale(double factor);
PointClass size() const;
double radius() const;
- void translate(coordf_t x, coordf_t y) { assert(this->defined); this->min.translate(x, y); this->max.translate(x, y); }
- void translate(const Pointf &pos) { this->translate(pos.x, pos.y); }
+ void translate(coordf_t x, coordf_t y) { assert(this->defined); PointClass v(x, y); this->min += v; this->max += v; }
+ void translate(const Vec2d &v) { this->min += v; this->max += v; }
void offset(coordf_t delta);
PointClass center() const;
bool contains(const PointClass &point) const {
- return point.x >= this->min.x && point.x <= this->max.x
- && point.y >= this->min.y && point.y <= this->max.y;
+ return point(0) >= this->min(0) && point(0) <= this->max(0)
+ && point(1) >= this->min(1) && point(1) <= this->max(1);
}
bool overlap(const BoundingBoxBase<PointClass> &other) const {
- return ! (this->max.x < other.min.x || this->min.x > other.max.x ||
- this->max.y < other.min.y || this->min.y > other.max.y);
+ return ! (this->max(0) < other.min(0) || this->min(0) > other.max(0) ||
+ this->max(1) < other.min(1) || this->min(1) > other.max(1));
}
bool operator==(const BoundingBoxBase<PointClass> &rhs) { return this->min == rhs.min && this->max == rhs.max; }
bool operator!=(const BoundingBoxBase<PointClass> &rhs) { return ! (*this == rhs); }
@@ -69,35 +61,33 @@ public:
BoundingBox3Base() : BoundingBoxBase<PointClass>() {};
BoundingBox3Base(const PointClass &pmin, const PointClass &pmax) :
BoundingBoxBase<PointClass>(pmin, pmax)
- { if (pmin.z >= pmax.z) BoundingBoxBase<PointClass>::defined = false; }
+ { if (pmin(2) >= pmax(2)) BoundingBoxBase<PointClass>::defined = false; }
BoundingBox3Base(const std::vector<PointClass>& points)
- : BoundingBoxBase<PointClass>(points)
{
if (points.empty())
CONFESS("Empty point set supplied to BoundingBox3Base constructor");
-
typename std::vector<PointClass>::const_iterator it = points.begin();
- this->min.z = this->max.z = it->z;
- for (++it; it != points.end(); ++it)
- {
- this->min.z = std::min(it->z, this->min.z);
- this->max.z = std::max(it->z, this->max.z);
+ this->min = *it;
+ this->max = *it;
+ for (++ it; it != points.end(); ++ it) {
+ this->min = this->min.cwiseMin(*it);
+ this->max = this->max.cwiseMax(*it);
}
- this->defined &= (this->min.z < this->max.z);
+ this->defined = (this->min(0) < this->max(0)) && (this->min(1) < this->max(1)) && (this->min(2) < this->max(2));
}
void merge(const PointClass &point);
void merge(const std::vector<PointClass> &points);
void merge(const BoundingBox3Base<PointClass> &bb);
PointClass size() const;
double radius() const;
- void translate(coordf_t x, coordf_t y, coordf_t z) { this->min.translate(x, y, z); this->max.translate(x, y, z); }
- void translate(const Pointf3 &pos) { this->translate(pos.x, pos.y, pos.z); }
+ void translate(coordf_t x, coordf_t y, coordf_t z) { assert(this->defined); PointClass v(x, y, z); this->min += v; this->max += v; }
+ void translate(const Vec3d &v) { this->min += v; this->max += v; }
void offset(coordf_t delta);
PointClass center() const;
coordf_t max_size() const;
bool contains(const PointClass &point) const {
- return BoundingBoxBase<PointClass>::contains(point) && point.z >= this->min.z && point.z <= this->max.z;
+ return BoundingBoxBase<PointClass>::contains(point) && point(2) >= this->min(2) && point(2) <= this->max(2);
}
bool contains(const BoundingBox3Base<PointClass>& other) const {
@@ -105,7 +95,7 @@ public:
}
bool intersects(const BoundingBox3Base<PointClass>& other) const {
- return (this->min.x < other.max.x) && (this->max.x > other.min.x) && (this->min.y < other.max.y) && (this->max.y > other.min.y) && (this->min.z < other.max.z) && (this->max.z > other.min.z);
+ return (this->min(0) < other.max(0)) && (this->max(0) > other.min(0)) && (this->min(1) < other.max(1)) && (this->max(1) > other.min(1)) && (this->min(2) < other.max(2)) && (this->max(2) > other.min(2));
}
};
@@ -130,42 +120,42 @@ public:
friend BoundingBox get_extents_rotated(const Points &points, double angle);
};
-class BoundingBox3 : public BoundingBox3Base<Point3>
+class BoundingBox3 : public BoundingBox3Base<Vec3crd>
{
public:
- BoundingBox3() : BoundingBox3Base<Point3>() {};
- BoundingBox3(const Point3 &pmin, const Point3 &pmax) : BoundingBox3Base<Point3>(pmin, pmax) {};
- BoundingBox3(const Points3& points) : BoundingBox3Base<Point3>(points) {};
+ BoundingBox3() : BoundingBox3Base<Vec3crd>() {};
+ BoundingBox3(const Vec3crd &pmin, const Vec3crd &pmax) : BoundingBox3Base<Vec3crd>(pmin, pmax) {};
+ BoundingBox3(const Points3& points) : BoundingBox3Base<Vec3crd>(points) {};
};
-class BoundingBoxf : public BoundingBoxBase<Pointf>
+class BoundingBoxf : public BoundingBoxBase<Vec2d>
{
public:
- BoundingBoxf() : BoundingBoxBase<Pointf>() {};
- BoundingBoxf(const Pointf &pmin, const Pointf &pmax) : BoundingBoxBase<Pointf>(pmin, pmax) {};
- BoundingBoxf(const std::vector<Pointf> &points) : BoundingBoxBase<Pointf>(points) {};
+ BoundingBoxf() : BoundingBoxBase<Vec2d>() {};
+ BoundingBoxf(const Vec2d &pmin, const Vec2d &pmax) : BoundingBoxBase<Vec2d>(pmin, pmax) {};
+ BoundingBoxf(const std::vector<Vec2d> &points) : BoundingBoxBase<Vec2d>(points) {};
};
-class BoundingBoxf3 : public BoundingBox3Base<Pointf3>
+class BoundingBoxf3 : public BoundingBox3Base<Vec3d>
{
public:
- BoundingBoxf3() : BoundingBox3Base<Pointf3>() {};
- BoundingBoxf3(const Pointf3 &pmin, const Pointf3 &pmax) : BoundingBox3Base<Pointf3>(pmin, pmax) {};
- BoundingBoxf3(const std::vector<Pointf3> &points) : BoundingBox3Base<Pointf3>(points) {};
+ BoundingBoxf3() : BoundingBox3Base<Vec3d>() {};
+ BoundingBoxf3(const Vec3d &pmin, const Vec3d &pmax) : BoundingBox3Base<Vec3d>(pmin, pmax) {};
+ BoundingBoxf3(const std::vector<Vec3d> &points) : BoundingBox3Base<Vec3d>(points) {};
- BoundingBoxf3 transformed(const std::vector<float>& matrix) const;
+ BoundingBoxf3 transformed(const Transform3d& matrix) const;
};
template<typename VT>
inline bool empty(const BoundingBoxBase<VT> &bb)
{
- return ! bb.defined || bb.min.x >= bb.max.x || bb.min.y >= bb.max.y;
+ return ! bb.defined || bb.min(0) >= bb.max(0) || bb.min(1) >= bb.max(1);
}
template<typename VT>
inline bool empty(const BoundingBox3Base<VT> &bb)
{
- return ! bb.defined || bb.min.x >= bb.max.x || bb.min.y >= bb.max.y || bb.min.z >= bb.max.z;
+ return ! bb.defined || bb.min(0) >= bb.max(0) || bb.min(1) >= bb.max(1) || bb.min(2) >= bb.max(2);
}
} // namespace Slic3r
diff --git a/xs/src/libslic3r/BridgeDetector.cpp b/xs/src/libslic3r/BridgeDetector.cpp
index a5272683f..ccc3505ce 100644
--- a/xs/src/libslic3r/BridgeDetector.cpp
+++ b/xs/src/libslic3r/BridgeDetector.cpp
@@ -102,16 +102,16 @@ bool BridgeDetector::detect_angle(double bridge_direction_override)
// Get an oriented bounding box around _anchor_regions.
BoundingBox bbox = get_extents_rotated(this->_anchor_regions, - angle);
// Cover the region with line segments.
- lines.reserve((bbox.max.y - bbox.min.y + this->spacing) / this->spacing);
+ lines.reserve((bbox.max(1) - bbox.min(1) + this->spacing) / this->spacing);
double s = sin(angle);
double c = cos(angle);
//FIXME Vojtech: The lines shall be spaced half the line width from the edge, but then
// some of the test cases fail. Need to adjust the test cases then?
-// for (coord_t y = bbox.min.y + this->spacing / 2; y <= bbox.max.y; y += this->spacing)
- for (coord_t y = bbox.min.y; y <= bbox.max.y; y += this->spacing)
+// for (coord_t y = bbox.min(1) + this->spacing / 2; y <= bbox.max(1); y += this->spacing)
+ for (coord_t y = bbox.min(1); y <= bbox.max(1); y += this->spacing)
lines.push_back(Line(
- Point((coord_t)round(c * bbox.min.x - s * y), (coord_t)round(c * y + s * bbox.min.x)),
- Point((coord_t)round(c * bbox.max.x - s * y), (coord_t)round(c * y + s * bbox.max.x))));
+ Point((coord_t)round(c * bbox.min(0) - s * y), (coord_t)round(c * y + s * bbox.min(0))),
+ Point((coord_t)round(c * bbox.max(0) - s * y), (coord_t)round(c * y + s * bbox.max(0)))));
}
double total_length = 0;
@@ -182,9 +182,9 @@ std::vector<double> BridgeDetector::bridge_direction_candidates() const
/* we also test angles of each open supporting edge
(this finds the optimal angle for C-shaped supports) */
- for (Polylines::const_iterator edge = this->_edges.begin(); edge != this->_edges.end(); ++edge)
- if (! edge->first_point().coincides_with(edge->last_point()))
- angles.push_back(Line(edge->first_point(), edge->last_point()).direction());
+ for (const Polyline &edge : this->_edges)
+ if (edge.first_point() != edge.last_point())
+ angles.push_back(Line(edge.first_point(), edge.last_point()).direction());
// remove duplicates
double min_resolution = PI/180.0; // 1 degree
@@ -282,10 +282,12 @@ BridgeDetector::unsupported_edges(double angle, Polylines* unsupported) const
extrusions would be anchored within such length (i.e. a slightly non-parallel bridging
direction might still benefit from anchors if long enough)
double angle_tolerance = PI / 180.0 * 5.0; */
- for (Lines::const_iterator line = unsupported_lines.begin(); line != unsupported_lines.end(); ++line) {
- if (!Slic3r::Geometry::directions_parallel(line->direction(), angle))
- unsupported->push_back(*line);
- }
+ for (const Line &line : unsupported_lines)
+ if (! Slic3r::Geometry::directions_parallel(line.direction(), angle)) {
+ unsupported->emplace_back(Polyline());
+ unsupported->back().points.emplace_back(line.a);
+ unsupported->back().points.emplace_back(line.b);
+ }
}
/*
diff --git a/xs/src/libslic3r/ClipperUtils.cpp b/xs/src/libslic3r/ClipperUtils.cpp
index 31a12aa77..f00e908ce 100644
--- a/xs/src/libslic3r/ClipperUtils.cpp
+++ b/xs/src/libslic3r/ClipperUtils.cpp
@@ -171,7 +171,7 @@ Slic3rMultiPoint_to_ClipperPath(const MultiPoint &input)
{
ClipperLib::Path retval;
for (Points::const_iterator pit = input.points.begin(); pit != input.points.end(); ++pit)
- retval.push_back(ClipperLib::IntPoint( (*pit).x, (*pit).y ));
+ retval.push_back(ClipperLib::IntPoint( (*pit)(0), (*pit)(1) ));
return retval;
}
@@ -181,7 +181,7 @@ Slic3rMultiPoint_to_ClipperPath_reversed(const Slic3r::MultiPoint &input)
ClipperLib::Path output;
output.reserve(input.points.size());
for (Slic3r::Points::const_reverse_iterator pit = input.points.rbegin(); pit != input.points.rend(); ++pit)
- output.push_back(ClipperLib::IntPoint( (*pit).x, (*pit).y ));
+ output.push_back(ClipperLib::IntPoint( (*pit)(0), (*pit)(1) ));
return output;
}
@@ -595,26 +595,26 @@ Polylines _clipper_pl(ClipperLib::ClipType clipType, const Polygons &subject, co
to recombine continuous polylines. */
for (size_t i = 0; i < retval.size(); ++i) {
for (size_t j = i+1; j < retval.size(); ++j) {
- if (retval[i].points.back().coincides_with(retval[j].points.front())) {
+ if (retval[i].points.back() == retval[j].points.front()) {
/* If last point of i coincides with first point of j,
append points of j to i and delete j */
retval[i].points.insert(retval[i].points.end(), retval[j].points.begin()+1, retval[j].points.end());
retval.erase(retval.begin() + j);
--j;
- } else if (retval[i].points.front().coincides_with(retval[j].points.back())) {
+ } else if (retval[i].points.front() == retval[j].points.back()) {
/* If first point of i coincides with last point of j,
prepend points of j to i and delete j */
retval[i].points.insert(retval[i].points.begin(), retval[j].points.begin(), retval[j].points.end()-1);
retval.erase(retval.begin() + j);
--j;
- } else if (retval[i].points.front().coincides_with(retval[j].points.front())) {
+ } else if (retval[i].points.front() == retval[j].points.front()) {
/* Since Clipper does not preserve orientation of polylines,
also check the case when first point of i coincides with first point of j. */
retval[j].reverse();
retval[i].points.insert(retval[i].points.begin(), retval[j].points.begin(), retval[j].points.end()-1);
retval.erase(retval.begin() + j);
--j;
- } else if (retval[i].points.back().coincides_with(retval[j].points.back())) {
+ } else if (retval[i].points.back() == retval[j].points.back()) {
/* Since Clipper does not preserve orientation of polylines,
also check the case when last point of i coincides with last point of j. */
retval[j].reverse();
@@ -634,8 +634,8 @@ _clipper_ln(ClipperLib::ClipType clipType, const Lines &subject, const Polygons
// convert Lines to Polylines
Polylines polylines;
polylines.reserve(subject.size());
- for (Lines::const_iterator line = subject.begin(); line != subject.end(); ++line)
- polylines.push_back(*line);
+ for (const Line &line : subject)
+ polylines.emplace_back(Polyline(line.a, line.b));
// perform operation
polylines = _clipper_pl(clipType, polylines, clip, safety_offset_);
diff --git a/xs/src/libslic3r/Config.hpp b/xs/src/libslic3r/Config.hpp
index 377bdbea4..7f75f815d 100644
--- a/xs/src/libslic3r/Config.hpp
+++ b/xs/src/libslic3r/Config.hpp
@@ -622,11 +622,11 @@ public:
}
};
-class ConfigOptionPoint : public ConfigOptionSingle<Pointf>
+class ConfigOptionPoint : public ConfigOptionSingle<Vec2d>
{
public:
- ConfigOptionPoint() : ConfigOptionSingle<Pointf>(Pointf(0,0)) {}
- explicit ConfigOptionPoint(const Pointf &value) : ConfigOptionSingle<Pointf>(value) {}
+ ConfigOptionPoint() : ConfigOptionSingle<Vec2d>(Vec2d(0,0)) {}
+ explicit ConfigOptionPoint(const Vec2d &value) : ConfigOptionSingle<Vec2d>(value) {}
static ConfigOptionType static_type() { return coPoint; }
ConfigOptionType type() const override { return static_type(); }
@@ -637,9 +637,9 @@ public:
std::string serialize() const override
{
std::ostringstream ss;
- ss << this->value.x;
+ ss << this->value(0);
ss << ",";
- ss << this->value.y;
+ ss << this->value(1);
return ss.str();
}
@@ -647,18 +647,18 @@ public:
{
UNUSED(append);
char dummy;
- return sscanf(str.data(), " %lf , %lf %c", &this->value.x, &this->value.y, &dummy) == 2 ||
- sscanf(str.data(), " %lf x %lf %c", &this->value.x, &this->value.y, &dummy) == 2;
+ return sscanf(str.data(), " %lf , %lf %c", &this->value(0), &this->value(1), &dummy) == 2 ||
+ sscanf(str.data(), " %lf x %lf %c", &this->value(0), &this->value(1), &dummy) == 2;
}
};
-class ConfigOptionPoints : public ConfigOptionVector<Pointf>
+class ConfigOptionPoints : public ConfigOptionVector<Vec2d>
{
public:
- ConfigOptionPoints() : ConfigOptionVector<Pointf>() {}
- explicit ConfigOptionPoints(size_t n, const Pointf &value) : ConfigOptionVector<Pointf>(n, value) {}
- explicit ConfigOptionPoints(std::initializer_list<Pointf> il) : ConfigOptionVector<Pointf>(std::move(il)) {}
- explicit ConfigOptionPoints(const std::vector<Pointf> &values) : ConfigOptionVector<Pointf>(values) {}
+ ConfigOptionPoints() : ConfigOptionVector<Vec2d>() {}
+ explicit ConfigOptionPoints(size_t n, const Vec2d &value) : ConfigOptionVector<Vec2d>(n, value) {}
+ explicit ConfigOptionPoints(std::initializer_list<Vec2d> il) : ConfigOptionVector<Vec2d>(std::move(il)) {}
+ explicit ConfigOptionPoints(const std::vector<Vec2d> &values) : ConfigOptionVector<Vec2d>(values) {}
static ConfigOptionType static_type() { return coPoints; }
ConfigOptionType type() const override { return static_type(); }
@@ -671,9 +671,9 @@ public:
std::ostringstream ss;
for (Pointfs::const_iterator it = this->values.begin(); it != this->values.end(); ++it) {
if (it - this->values.begin() != 0) ss << ",";
- ss << it->x;
+ ss << (*it)(0);
ss << "x";
- ss << it->y;
+ ss << (*it)(1);
}
return ss.str();
}
@@ -696,13 +696,13 @@ public:
std::istringstream is(str);
std::string point_str;
while (std::getline(is, point_str, ',')) {
- Pointf point;
+ Vec2d point(Vec2d::Zero());
std::istringstream iss(point_str);
std::string coord_str;
if (std::getline(iss, coord_str, 'x')) {
- std::istringstream(coord_str) >> point.x;
+ std::istringstream(coord_str) >> point(0);
if (std::getline(iss, coord_str, 'x')) {
- std::istringstream(coord_str) >> point.y;
+ std::istringstream(coord_str) >> point(1);
}
}
this->values.push_back(point);
diff --git a/xs/src/libslic3r/EdgeGrid.cpp b/xs/src/libslic3r/EdgeGrid.cpp
index 733ff2ad7..50f424e6d 100644
--- a/xs/src/libslic3r/EdgeGrid.cpp
+++ b/xs/src/libslic3r/EdgeGrid.cpp
@@ -117,15 +117,15 @@ void EdgeGrid::Grid::create_from_m_contours(coord_t resolution)
m_bbox.merge(pts[j]);
}
coord_t eps = 16;
- m_bbox.min.x -= eps;
- m_bbox.min.y -= eps;
- m_bbox.max.x += eps;
- m_bbox.max.y += eps;
+ m_bbox.min(0) -= eps;
+ m_bbox.min(1) -= eps;
+ m_bbox.max(0) += eps;
+ m_bbox.max(1) += eps;
// 2) Initialize the edge grid.
m_resolution = resolution;
- m_cols = (m_bbox.max.x - m_bbox.min.x + m_resolution - 1) / m_resolution;
- m_rows = (m_bbox.max.y - m_bbox.min.y + m_resolution - 1) / m_resolution;
+ m_cols = (m_bbox.max(0) - m_bbox.min(0) + m_resolution - 1) / m_resolution;
+ m_rows = (m_bbox.max(1) - m_bbox.min(1) + m_resolution - 1) / m_resolution;
m_cells.assign(m_rows * m_cols, Cell());
// 3) First round of contour rasterization, count the edges per grid cell.
@@ -135,15 +135,15 @@ void EdgeGrid::Grid::create_from_m_contours(coord_t resolution)
// End points of the line segment.
Slic3r::Point p1(pts[j]);
Slic3r::Point p2 = pts[(j + 1 == pts.size()) ? 0 : j + 1];
- p1.x -= m_bbox.min.x;
- p1.y -= m_bbox.min.y;
- p2.x -= m_bbox.min.x;
- p2.y -= m_bbox.min.y;
+ p1(0) -= m_bbox.min(0);
+ p1(1) -= m_bbox.min(1);
+ p2(0) -= m_bbox.min(0);
+ p2(1) -= m_bbox.min(1);
// Get the cells of the end points.
- coord_t ix = p1.x / m_resolution;
- coord_t iy = p1.y / m_resolution;
- coord_t ixb = p2.x / m_resolution;
- coord_t iyb = p2.y / m_resolution;
+ coord_t ix = p1(0) / m_resolution;
+ coord_t iy = p1(1) / m_resolution;
+ coord_t ixb = p2(0) / m_resolution;
+ coord_t iyb = p2(1) / m_resolution;
assert(ix >= 0 && ix < m_cols);
assert(iy >= 0 && iy < m_rows);
assert(ixb >= 0 && ixb < m_cols);
@@ -154,13 +154,13 @@ void EdgeGrid::Grid::create_from_m_contours(coord_t resolution)
// Both ends fall into the same cell.
continue;
// Raster the centeral part of the line.
- coord_t dx = std::abs(p2.x - p1.x);
- coord_t dy = std::abs(p2.y - p1.y);
- if (p1.x < p2.x) {
- int64_t ex = int64_t((ix + 1)*m_resolution - p1.x) * int64_t(dy);
- if (p1.y < p2.y) {
+ coord_t dx = std::abs(p2(0) - p1(0));
+ coord_t dy = std::abs(p2(1) - p1(1));
+ if (p1(0) < p2(0)) {
+ int64_t ex = int64_t((ix + 1)*m_resolution - p1(0)) * int64_t(dy);
+ if (p1(1) < p2(1)) {
// x positive, y positive
- int64_t ey = int64_t((iy + 1)*m_resolution - p1.y) * int64_t(dx);
+ int64_t ey = int64_t((iy + 1)*m_resolution - p1(1)) * int64_t(dx);
do {
assert(ix <= ixb && iy <= iyb);
if (ex < ey) {
@@ -185,7 +185,7 @@ void EdgeGrid::Grid::create_from_m_contours(coord_t resolution)
}
else {
// x positive, y non positive
- int64_t ey = int64_t(p1.y - iy*m_resolution) * int64_t(dx);
+ int64_t ey = int64_t(p1(1) - iy*m_resolution) * int64_t(dx);
do {
assert(ix <= ixb && iy >= iyb);
if (ex <= ey) {
@@ -203,10 +203,10 @@ void EdgeGrid::Grid::create_from_m_contours(coord_t resolution)
}
}
else {
- int64_t ex = int64_t(p1.x - ix*m_resolution) * int64_t(dy);
- if (p1.y < p2.y) {
+ int64_t ex = int64_t(p1(0) - ix*m_resolution) * int64_t(dy);
+ if (p1(1) < p2(1)) {
// x non positive, y positive
- int64_t ey = int64_t((iy + 1)*m_resolution - p1.y) * int64_t(dx);
+ int64_t ey = int64_t((iy + 1)*m_resolution - p1(1)) * int64_t(dx);
do {
assert(ix >= ixb && iy <= iyb);
if (ex < ey) {
@@ -225,7 +225,7 @@ void EdgeGrid::Grid::create_from_m_contours(coord_t resolution)
}
else {
// x non positive, y non positive
- int64_t ey = int64_t(p1.y - iy*m_resolution) * int64_t(dx);
+ int64_t ey = int64_t(p1(1) - iy*m_resolution) * int64_t(dx);
do {
assert(ix >= ixb && iy >= iyb);
if (ex < ey) {
@@ -279,15 +279,15 @@ void EdgeGrid::Grid::create_from_m_contours(coord_t resolution)
// End points of the line segment.
Slic3r::Point p1(pts[j]);
Slic3r::Point p2 = pts[(j + 1 == pts.size()) ? 0 : j + 1];
- p1.x -= m_bbox.min.x;
- p1.y -= m_bbox.min.y;
- p2.x -= m_bbox.min.x;
- p2.y -= m_bbox.min.y;
+ p1(0) -= m_bbox.min(0);
+ p1(1) -= m_bbox.min(1);
+ p2(0) -= m_bbox.min(0);
+ p2(1) -= m_bbox.min(1);
// Get the cells of the end points.
- coord_t ix = p1.x / m_resolution;
- coord_t iy = p1.y / m_resolution;
- coord_t ixb = p2.x / m_resolution;
- coord_t iyb = p2.y / m_resolution;
+ coord_t ix = p1(0) / m_resolution;
+ coord_t iy = p1(1) / m_resolution;
+ coord_t ixb = p2(0) / m_resolution;
+ coord_t iyb = p2(1) / m_resolution;
assert(ix >= 0 && ix < m_cols);
assert(iy >= 0 && iy < m_rows);
assert(ixb >= 0 && ixb < m_cols);
@@ -298,13 +298,13 @@ void EdgeGrid::Grid::create_from_m_contours(coord_t resolution)
// Both ends fall into the same cell.
continue;
// Raster the centeral part of the line.
- coord_t dx = std::abs(p2.x - p1.x);
- coord_t dy = std::abs(p2.y - p1.y);
- if (p1.x < p2.x) {
- int64_t ex = int64_t((ix + 1)*m_resolution - p1.x) * int64_t(dy);
- if (p1.y < p2.y) {
+ coord_t dx = std::abs(p2(0) - p1(0));
+ coord_t dy = std::abs(p2(1) - p1(1));
+ if (p1(0) < p2(0)) {
+ int64_t ex = int64_t((ix + 1)*m_resolution - p1(0)) * int64_t(dy);
+ if (p1(1) < p2(1)) {
// x positive, y positive
- int64_t ey = int64_t((iy + 1)*m_resolution - p1.y) * int64_t(dx);
+ int64_t ey = int64_t((iy + 1)*m_resolution - p1(1)) * int64_t(dx);
do {
assert(ix <= ixb && iy <= iyb);
if (ex < ey) {
@@ -329,7 +329,7 @@ void EdgeGrid::Grid::create_from_m_contours(coord_t resolution)
}
else {
// x positive, y non positive
- int64_t ey = int64_t(p1.y - iy*m_resolution) * int64_t(dx);
+ int64_t ey = int64_t(p1(1) - iy*m_resolution) * int64_t(dx);
do {
assert(ix <= ixb && iy >= iyb);
if (ex <= ey) {
@@ -347,10 +347,10 @@ void EdgeGrid::Grid::create_from_m_contours(coord_t resolution)
}
}
else {
- int64_t ex = int64_t(p1.x - ix*m_resolution) * int64_t(dy);
- if (p1.y < p2.y) {
+ int64_t ex = int64_t(p1(0) - ix*m_resolution) * int64_t(dy);
+ if (p1(1) < p2(1)) {
// x non positive, y positive
- int64_t ey = int64_t((iy + 1)*m_resolution - p1.y) * int64_t(dx);
+ int64_t ey = int64_t((iy + 1)*m_resolution - p1(1)) * int64_t(dx);
do {
assert(ix >= ixb && iy <= iyb);
if (ex < ey) {
@@ -369,7 +369,7 @@ void EdgeGrid::Grid::create_from_m_contours(coord_t resolution)
}
else {
// x non positive, y non positive
- int64_t ey = int64_t(p1.y - iy*m_resolution) * int64_t(dx);
+ int64_t ey = int64_t(p1(1) - iy*m_resolution) * int64_t(dx);
do {
assert(ix >= ixb && iy >= iyb);
if (ex < ey) {
@@ -429,15 +429,15 @@ bool EdgeGrid::Grid::intersect(const MultiPoint &polyline, bool closed)
Point p1 = p1src;
Point p2 = p2src;
// Discretize the line segment p1, p2.
- p1.x -= m_bbox.min.x;
- p1.y -= m_bbox.min.y;
- p2.x -= m_bbox.min.x;
- p2.y -= m_bbox.min.y;
+ p1(0) -= m_bbox.min(0);
+ p1(1) -= m_bbox.min(1);
+ p2(0) -= m_bbox.min(0);
+ p2(1) -= m_bbox.min(1);
// Get the cells of the end points.
- coord_t ix = div_floor(p1.x, m_resolution);
- coord_t iy = div_floor(p1.y, m_resolution);
- coord_t ixb = div_floor(p2.x, m_resolution);
- coord_t iyb = div_floor(p2.y, m_resolution);
+ coord_t ix = div_floor(p1(0), m_resolution);
+ coord_t iy = div_floor(p1(1), m_resolution);
+ coord_t ixb = div_floor(p2(0), m_resolution);
+ coord_t iyb = div_floor(p2(1), m_resolution);
// assert(ix >= 0 && ix < m_cols);
// assert(iy >= 0 && iy < m_rows);
// assert(ixb >= 0 && ixb < m_cols);
@@ -449,12 +449,12 @@ bool EdgeGrid::Grid::intersect(const MultiPoint &polyline, bool closed)
// Both ends fall into the same cell.
continue;
// Raster the centeral part of the line.
- coord_t dx = std::abs(p2.x - p1.x);
- coord_t dy = std::abs(p2.y - p1.y);
- if (p1.x < p2.x) {
- int64_t ex = int64_t((ix + 1)*m_resolution - p1.x) * int64_t(dy);
- if (p1.y < p2.y) {
- int64_t ey = int64_t((iy + 1)*m_resolution - p1.y) * int64_t(dx);
+ coord_t dx = std::abs(p2(0) - p1(0));
+ coord_t dy = std::abs(p2(1) - p1(1));
+ if (p1(0) < p2(0)) {
+ int64_t ex = int64_t((ix + 1)*m_resolution - p1(0)) * int64_t(dy);
+ if (p1(1) < p2(1)) {
+ int64_t ey = int64_t((iy + 1)*m_resolution - p1(1)) * int64_t(dx);
do {
assert(ix <= ixb && iy <= iyb);
if (ex < ey) {
@@ -479,7 +479,7 @@ bool EdgeGrid::Grid::intersect(const MultiPoint &polyline, bool closed)
} while (ix != ixb || iy != iyb);
}
else {
- int64_t ey = int64_t(p1.y - iy*m_resolution) * int64_t(dx);
+ int64_t ey = int64_t(p1(1) - iy*m_resolution) * int64_t(dx);
do {
assert(ix <= ixb && iy >= iyb);
if (ex <= ey) {
@@ -498,9 +498,9 @@ bool EdgeGrid::Grid::intersect(const MultiPoint &polyline, bool closed)
}
}
else {
- int64_t ex = int64_t(p1.x - ix*m_resolution) * int64_t(dy);
- if (p1.y < p2.y) {
- int64_t ey = int64_t((iy + 1)*m_resolution - p1.y) * int64_t(dx);
+ int64_t ex = int64_t(p1(0) - ix*m_resolution) * int64_t(dy);
+ if (p1(1) < p2(1)) {
+ int64_t ey = int64_t((iy + 1)*m_resolution - p1(1)) * int64_t(dx);
do {
assert(ix >= ixb && iy <= iyb);
if (ex < ey) {
@@ -519,7 +519,7 @@ bool EdgeGrid::Grid::intersect(const MultiPoint &polyline, bool closed)
} while (ix != ixb || iy != iyb);
}
else {
- int64_t ey = int64_t(p1.y - iy*m_resolution) * int64_t(dx);
+ int64_t ey = int64_t(p1(1) - iy*m_resolution) * int64_t(dx);
do {
assert(ix >= ixb && iy >= iyb);
if (ex < ey) {
@@ -556,8 +556,8 @@ bool EdgeGrid::Grid::line_cell_intersect(const Point &p1a, const Point &p2a, con
{
BoundingBox bbox(p1a, p1a);
bbox.merge(p2a);
- int64_t va_x = p2a.x - p1a.x;
- int64_t va_y = p2a.y - p1a.y;
+ int64_t va_x = p2a(0) - p1a(0);
+ int64_t va_y = p2a(1) - p1a(1);
for (size_t i = cell.begin; i != cell.end; ++ i) {
const std::pair<size_t, size_t> &cell_data = m_cell_data[i];
// Contour indexed by the ith line of this cell.
@@ -576,21 +576,21 @@ bool EdgeGrid::Grid::line_cell_intersect(const Point &p1a, const Point &p2a, con
if (! bbox.overlap(bbox2))
continue;
// Now intersect the two line segments using exact arithmetics.
- int64_t w1_x = p1b.x - p1a.x;
- int64_t w1_y = p1b.y - p1a.y;
- int64_t w2_x = p2b.x - p1a.x;
- int64_t w2_y = p2b.y - p1a.y;
+ int64_t w1_x = p1b(0) - p1a(0);
+ int64_t w1_y = p1b(1) - p1a(1);
+ int64_t w2_x = p2b(0) - p1a(0);
+ int64_t w2_y = p2b(1) - p1a(1);
int64_t side1 = va_x * w1_y - va_y * w1_x;
int64_t side2 = va_x * w2_y - va_y * w2_x;
if (side1 == side2 && side1 != 0)
// The line segments don't intersect.
continue;
- w1_x = p1a.x - p1b.x;
- w1_y = p1a.y - p1b.y;
- w2_x = p2a.x - p1b.x;
- w2_y = p2a.y - p1b.y;
- int64_t vb_x = p2b.x - p1b.x;
- int64_t vb_y = p2b.y - p1b.y;
+ w1_x = p1a(0) - p1b(0);
+ w1_y = p1a(1) - p1b(1);
+ w2_x = p2a(0) - p1b(0);
+ w2_y = p2a(1) - p1b(1);
+ int64_t vb_x = p2b(0) - p1b(0);
+ int64_t vb_y = p2b(1) - p1b(1);
side1 = vb_x * w1_y - vb_y * w1_x;
side2 = vb_x * w2_y - vb_y * w2_x;
if (side1 == side2 && side1 != 0)
@@ -607,13 +607,13 @@ bool EdgeGrid::Grid::line_cell_intersect(const Point &p1a, const Point &p2a, con
bool EdgeGrid::Grid::inside(const Point &pt_src)
{
Point p = pt_src;
- p.x -= m_bbox.min.x;
- p.y -= m_bbox.min.y;
+ p(0) -= m_bbox.min(0);
+ p(1) -= m_bbox.min(1);
// Get the cell of the point.
- if (p.x < 0 || p.y < 0)
+ if (p(0) < 0 || p(1) < 0)
return false;
- coord_t ix = p.x / m_resolution;
- coord_t iy = p.y / m_resolution;
+ coord_t ix = p(0) / m_resolution;
+ coord_t iy = p(1) / m_resolution;
if (ix >= this->m_cols || iy >= this->m_rows)
return false;
@@ -634,21 +634,21 @@ bool EdgeGrid::Grid::inside(const Point &pt_src)
idx2 = 0;
const Point &p1 = contour[idx1];
const Point &p2 = contour[idx2];
- if (p1.y < p2.y) {
- if (p.y < p1.y || p.y > p2.y)
+ if (p1(1) < p2(1)) {
+ if (p(1) < p1(1) || p(1) > p2(1))
continue;
//FIXME finish this!
int64_t vx = 0;// pt_src
//FIXME finish this!
int64_t det = 0;
- } else if (p1.y != p2.y) {
- assert(p1.y > p2.y);
- if (p.y < p2.y || p.y > p1.y)
+ } else if (p1(1) != p2(1)) {
+ assert(p1(1) > p2(1));
+ if (p(1) < p2(1) || p(1) > p1(1))
continue;
} else {
- assert(p1.y == p2.y);
- if (p1.y == p.y) {
- if (p.x >= p1.x && p.x <= p2.x)
+ assert(p1(1) == p2(1));
+ if (p1(1) == p(1)) {
+ if (p(0) >= p1(0) && p(0) <= p2(0))
// On the segment.
return true;
// Before or after the segment.
@@ -767,9 +767,9 @@ void EdgeGrid::Grid::calculate_sdf()
const Slic3r::Point &p1 = pts[ipt];
const Slic3r::Point &p2 = pts[(ipt + 1 == pts.size()) ? 0 : ipt + 1];
// Segment vector
- const Slic3r::Point v_seg = p1.vector_to(p2);
+ const Slic3r::Point v_seg = p2 - p1;
// l2 of v_seg
- const int64_t l2_seg = int64_t(v_seg.x) * int64_t(v_seg.x) + int64_t(v_seg.y) * int64_t(v_seg.y);
+ const int64_t l2_seg = int64_t(v_seg(0)) * int64_t(v_seg(0)) + int64_t(v_seg(1)) * int64_t(v_seg(1));
// For each corner of this cell and its 1 ring neighbours:
for (int corner_y = -1; corner_y < 3; ++ corner_y) {
coord_t corner_r = r + corner_y;
@@ -780,28 +780,28 @@ void EdgeGrid::Grid::calculate_sdf()
if (corner_c < 0 || corner_c >= ncols)
continue;
float &d_min = m_signed_distance_field[corner_r * ncols + corner_c];
- Slic3r::Point pt(m_bbox.min.x + corner_c * m_resolution, m_bbox.min.y + corner_r * m_resolution);
- Slic3r::Point v_pt = p1.vector_to(pt);
+ Slic3r::Point pt(m_bbox.min(0) + corner_c * m_resolution, m_bbox.min(1) + corner_r * m_resolution);
+ Slic3r::Point v_pt = pt - p1;
// dot(p2-p1, pt-p1)
- int64_t t_pt = int64_t(v_seg.x) * int64_t(v_pt.x) + int64_t(v_seg.y) * int64_t(v_pt.y);
+ int64_t t_pt = int64_t(v_seg(0)) * int64_t(v_pt(0)) + int64_t(v_seg(1)) * int64_t(v_pt(1));
if (t_pt < 0) {
// Closest to p1.
- double dabs = sqrt(int64_t(v_pt.x) * int64_t(v_pt.x) + int64_t(v_pt.y) * int64_t(v_pt.y));
+ double dabs = sqrt(int64_t(v_pt(0)) * int64_t(v_pt(0)) + int64_t(v_pt(1)) * int64_t(v_pt(1)));
if (dabs < d_min) {
// Previous point.
const Slic3r::Point &p0 = pts[(ipt == 0) ? (pts.size() - 1) : ipt - 1];
- Slic3r::Point v_seg_prev = p0.vector_to(p1);
- int64_t t2_pt = int64_t(v_seg_prev.x) * int64_t(v_pt.x) + int64_t(v_seg_prev.y) * int64_t(v_pt.y);
+ Slic3r::Point v_seg_prev = p1 - p0;
+ int64_t t2_pt = int64_t(v_seg_prev(0)) * int64_t(v_pt(0)) + int64_t(v_seg_prev(1)) * int64_t(v_pt(1));
if (t2_pt > 0) {
// Inside the wedge between the previous and the next segment.
// Set the signum depending on whether the vertex is convex or reflex.
- int64_t det = int64_t(v_seg_prev.x) * int64_t(v_seg.y) - int64_t(v_seg_prev.y) * int64_t(v_seg.x);
+ int64_t det = int64_t(v_seg_prev(0)) * int64_t(v_seg(1)) - int64_t(v_seg_prev(1)) * int64_t(v_seg(0));
assert(det != 0);
d_min = dabs;
// Fill in an unsigned vector towards the zero iso surface.
float *l = &L[(corner_r * ncols + corner_c) << 1];
- l[0] = std::abs(v_pt.x);
- l[1] = std::abs(v_pt.y);
+ l[0] = std::abs(v_pt(0));
+ l[1] = std::abs(v_pt(1));
#ifdef _DEBUG
double dabs2 = sqrt(l[0]*l[0]+l[1]*l[1]);
assert(std::abs(dabs-dabs2) < 1e-4 * std::max(dabs, dabs2));
@@ -816,7 +816,7 @@ void EdgeGrid::Grid::calculate_sdf()
} else {
// Closest to the segment.
assert(t_pt >= 0 && t_pt <= l2_seg);
- int64_t d_seg = int64_t(v_seg.y) * int64_t(v_pt.x) - int64_t(v_seg.x) * int64_t(v_pt.y);
+ int64_t d_seg = int64_t(v_seg(1)) * int64_t(v_pt(0)) - int64_t(v_seg(0)) * int64_t(v_pt(1));
double d = double(d_seg) / sqrt(double(l2_seg));
double dabs = std::abs(d);
if (dabs < d_min) {
@@ -824,8 +824,8 @@ void EdgeGrid::Grid::calculate_sdf()
// Fill in an unsigned vector towards the zero iso surface.
float *l = &L[(corner_r * ncols + corner_c) << 1];
float linv = float(d_seg) / float(l2_seg);
- l[0] = std::abs(float(v_seg.y) * linv);
- l[1] = std::abs(float(v_seg.x) * linv);
+ l[0] = std::abs(float(v_seg(1)) * linv);
+ l[1] = std::abs(float(v_seg(0)) * linv);
#ifdef _DEBUG
double dabs2 = sqrt(l[0]*l[0]+l[1]*l[1]);
assert(std::abs(dabs-dabs2) <= 1e-4 * std::max(dabs, dabs2));
@@ -1059,8 +1059,8 @@ void EdgeGrid::Grid::calculate_sdf()
float EdgeGrid::Grid::signed_distance_bilinear(const Point &pt) const
{
- coord_t x = pt.x - m_bbox.min.x;
- coord_t y = pt.y - m_bbox.min.y;
+ coord_t x = pt(0) - m_bbox.min(0);
+ coord_t y = pt(1) - m_bbox.min(1);
coord_t w = m_resolution * m_cols;
coord_t h = m_resolution * m_rows;
bool clamped = false;
@@ -1124,39 +1124,39 @@ float EdgeGrid::Grid::signed_distance_bilinear(const Point &pt) const
bool EdgeGrid::Grid::signed_distance_edges(const Point &pt, coord_t search_radius, coordf_t &result_min_dist, bool *pon_segment) const {
BoundingBox bbox;
- bbox.min = bbox.max = Point(pt.x - m_bbox.min.x, pt.y - m_bbox.min.y);
+ bbox.min = bbox.max = Point(pt(0) - m_bbox.min(0), pt(1) - m_bbox.min(1));
bbox.defined = true;
// Upper boundary, round to grid and test validity.
- bbox.max.x += search_radius;
- bbox.max.y += search_radius;
- if (bbox.max.x < 0 || bbox.max.y < 0)
+ bbox.max(0) += search_radius;
+ bbox.max(1) += search_radius;
+ if (bbox.max(0) < 0 || bbox.max(1) < 0)
return false;
- bbox.max.x /= m_resolution;
- bbox.max.y /= m_resolution;
- if (bbox.max.x >= m_cols)
- bbox.max.x = m_cols - 1;
- if (bbox.max.y >= m_rows)
- bbox.max.y = m_rows - 1;
+ bbox.max(0) /= m_resolution;
+ bbox.max(1) /= m_resolution;
+ if (bbox.max(0) >= m_cols)
+ bbox.max(0) = m_cols - 1;
+ if (bbox.max(1) >= m_rows)
+ bbox.max(1) = m_rows - 1;
// Lower boundary, round to grid and test validity.
- bbox.min.x -= search_radius;
- bbox.min.y -= search_radius;
- if (bbox.min.x < 0)
- bbox.min.x = 0;
- if (bbox.min.y < 0)
- bbox.min.y = 0;
- bbox.min.x /= m_resolution;
- bbox.min.y /= m_resolution;
+ bbox.min(0) -= search_radius;
+ bbox.min(1) -= search_radius;
+ if (bbox.min(0) < 0)
+ bbox.min(0) = 0;
+ if (bbox.min(1) < 0)
+ bbox.min(1) = 0;
+ bbox.min(0) /= m_resolution;
+ bbox.min(1) /= m_resolution;
// Is the interval empty?
- if (bbox.min.x > bbox.max.x ||
- bbox.min.y > bbox.max.y)
+ if (bbox.min(0) > bbox.max(0) ||
+ bbox.min(1) > bbox.max(1))
return false;
// Traverse all cells in the bounding box.
float d_min = search_radius;
// Signum of the distance field at pt.
int sign_min = 0;
bool on_segment = false;
- for (int r = bbox.min.y; r <= bbox.max.y; ++ r) {
- for (int c = bbox.min.x; c <= bbox.max.x; ++ c) {
+ for (int r = bbox.min(1); r <= bbox.max(1); ++ r) {
+ for (int c = bbox.min(0); c <= bbox.max(0); ++ c) {
const Cell &cell = m_cells[r * m_cols + c];
for (size_t i = cell.begin; i < cell.end; ++ i) {
const Slic3r::Points &pts = *m_contours[m_cell_data[i].first];
@@ -1164,25 +1164,25 @@ bool EdgeGrid::Grid::signed_distance_edges(const Point &pt, coord_t search_radiu
// End points of the line segment.
const Slic3r::Point &p1 = pts[ipt];
const Slic3r::Point &p2 = pts[(ipt + 1 == pts.size()) ? 0 : ipt + 1];
- Slic3r::Point v_seg = p1.vector_to(p2);
- Slic3r::Point v_pt = p1.vector_to(pt);
+ Slic3r::Point v_seg = p2 - p1;
+ Slic3r::Point v_pt = pt - p1;
// dot(p2-p1, pt-p1)
- int64_t t_pt = int64_t(v_seg.x) * int64_t(v_pt.x) + int64_t(v_seg.y) * int64_t(v_pt.y);
+ int64_t t_pt = int64_t(v_seg(0)) * int64_t(v_pt(0)) + int64_t(v_seg(1)) * int64_t(v_pt(1));
// l2 of seg
- int64_t l2_seg = int64_t(v_seg.x) * int64_t(v_seg.x) + int64_t(v_seg.y) * int64_t(v_seg.y);
+ int64_t l2_seg = int64_t(v_seg(0)) * int64_t(v_seg(0)) + int64_t(v_seg(1)) * int64_t(v_seg(1));
if (t_pt < 0) {
// Closest to p1.
- double dabs = sqrt(int64_t(v_pt.x) * int64_t(v_pt.x) + int64_t(v_pt.y) * int64_t(v_pt.y));
+ double dabs = sqrt(int64_t(v_pt(0)) * int64_t(v_pt(0)) + int64_t(v_pt(1)) * int64_t(v_pt(1)));
if (dabs < d_min) {
// Previous point.
const Slic3r::Point &p0 = pts[(ipt == 0) ? (pts.size() - 1) : ipt - 1];
- Slic3r::Point v_seg_prev = p0.vector_to(p1);
- int64_t t2_pt = int64_t(v_seg_prev.x) * int64_t(v_pt.x) + int64_t(v_seg_prev.y) * int64_t(v_pt.y);
+ Slic3r::Point v_seg_prev = p1 - p0;
+ int64_t t2_pt = int64_t(v_seg_prev(0)) * int64_t(v_pt(0)) + int64_t(v_seg_prev(1)) * int64_t(v_pt(1));
if (t2_pt > 0) {
// Inside the wedge between the previous and the next segment.
d_min = dabs;
// Set the signum depending on whether the vertex is convex or reflex.
- int64_t det = int64_t(v_seg_prev.x) * int64_t(v_seg.y) - int64_t(v_seg_prev.y) * int64_t(v_seg.x);
+ int64_t det = int64_t(v_seg_prev(0)) * int64_t(v_seg(1)) - int64_t(v_seg_prev(1)) * int64_t(v_seg(0));
assert(det != 0);
sign_min = (det > 0) ? 1 : -1;
on_segment = false;
@@ -1195,7 +1195,7 @@ bool EdgeGrid::Grid::signed_distance_edges(const Point &pt, coord_t search_radiu
} else {
// Closest to the segment.
assert(t_pt >= 0 && t_pt <= l2_seg);
- int64_t d_seg = int64_t(v_seg.y) * int64_t(v_pt.x) - int64_t(v_seg.x) * int64_t(v_pt.y);
+ int64_t d_seg = int64_t(v_seg(1)) * int64_t(v_pt(0)) - int64_t(v_seg(0)) * int64_t(v_pt(1));
double d = double(d_seg) / sqrt(double(l2_seg));
double dabs = std::abs(d);
if (dabs < d_min) {
@@ -1307,7 +1307,7 @@ Polygons EdgeGrid::Grid::contours_simplified(coord_t offset) const
const Line &line_next = lines[it->second];
const Vector v1 = line_current.vector();
const Vector v2 = line_next.vector();
- int64_t cross = int64_t(v1.x) * int64_t(v2.y) - int64_t(v2.x) * int64_t(v1.y);
+ int64_t cross = int64_t(v1(0)) * int64_t(v2(1)) - int64_t(v2(0)) * int64_t(v1(1));
if (cross > 0) {
// This has to be a convex right angle. There is no better next line.
i_next = it->second;
@@ -1328,10 +1328,10 @@ Polygons EdgeGrid::Grid::contours_simplified(coord_t offset) const
Polygon &poly = out[i];
for (size_t j = 0; j < poly.points.size(); ++ j) {
Point &p = poly.points[j];
- p.x *= m_resolution;
- p.y *= m_resolution;
- p.x += m_bbox.min.x;
- p.y += m_bbox.min.y;
+ p(0) *= m_resolution;
+ p(1) *= m_resolution;
+ p(0) += m_bbox.min(0);
+ p(1) += m_bbox.min(1);
}
// Shrink the contour slightly, so if the same contour gets discretized and simplified again, one will get the same result.
// Remove collineaer points.
@@ -1341,11 +1341,11 @@ Polygons EdgeGrid::Grid::contours_simplified(coord_t offset) const
size_t j0 = (j == 0) ? poly.points.size() - 1 : j - 1;
size_t j2 = (j + 1 == poly.points.size()) ? 0 : j + 1;
Point v = poly.points[j2] - poly.points[j0];
- if (v.x != 0 && v.y != 0) {
+ if (v(0) != 0 && v(1) != 0) {
// This is a corner point. Copy it to the output contour.
Point p = poly.points[j];
- p.y += (v.x < 0) ? - offset : offset;
- p.x += (v.y > 0) ? - offset : offset;
+ p(1) += (v(0) < 0) ? - offset : offset;
+ p(0) += (v(1) > 0) ? - offset : offset;
pts.push_back(p);
}
}
@@ -1357,8 +1357,8 @@ Polygons EdgeGrid::Grid::contours_simplified(coord_t offset) const
#if 0
void EdgeGrid::save_png(const EdgeGrid::Grid &grid, const BoundingBox &bbox, coord_t resolution, const char *path)
{
- unsigned int w = (bbox.max.x - bbox.min.x + resolution - 1) / resolution;
- unsigned int h = (bbox.max.y - bbox.min.y + resolution - 1) / resolution;
+ unsigned int w = (bbox.max(0) - bbox.min(0) + resolution - 1) / resolution;
+ unsigned int h = (bbox.max(1) - bbox.min(1) + resolution - 1) / resolution;
wxImage img(w, h);
unsigned char *data = img.GetData();
memset(data, 0, w * h * 3);
@@ -1371,7 +1371,7 @@ void EdgeGrid::save_png(const EdgeGrid::Grid &grid, const BoundingBox &bbox, coo
for (coord_t r = 0; r < h; ++r) {
for (coord_t c = 0; c < w; ++ c) {
unsigned char *pxl = data + (((h - r - 1) * w) + c) * 3;
- Point pt(c * resolution + bbox.min.x, r * resolution + bbox.min.y);
+ Point pt(c * resolution + bbox.min(0), r * resolution + bbox.min(1));
coordf_t min_dist;
bool on_segment = true;
#if 0
@@ -1409,8 +1409,8 @@ void EdgeGrid::save_png(const EdgeGrid::Grid &grid, const BoundingBox &bbox, coo
pxl[2] = 0;
}
- float gridx = float(pt.x - grid.bbox().min.x) / float(grid.resolution());
- float gridy = float(pt.y - grid.bbox().min.y) / float(grid.resolution());
+ float gridx = float(pt(0) - grid.bbox().min(0)) / float(grid.resolution());
+ float gridy = float(pt(1) - grid.bbox().min(1)) / float(grid.resolution());
if (gridx >= -0.4f && gridy >= -0.4f && gridx <= grid.cols() + 0.4f && gridy <= grid.rows() + 0.4f) {
int ix = int(floor(gridx + 0.5f));
int iy = int(floor(gridy + 0.5f));
diff --git a/xs/src/libslic3r/ExPolygon.cpp b/xs/src/libslic3r/ExPolygon.cpp
index cd57fd7b0..4294fe543 100644
--- a/xs/src/libslic3r/ExPolygon.cpp
+++ b/xs/src/libslic3r/ExPolygon.cpp
@@ -34,54 +34,43 @@ ExPolygon::operator Polylines() const
return to_polylines(*this);
}
-void
-ExPolygon::scale(double factor)
+void ExPolygon::scale(double factor)
{
contour.scale(factor);
- for (Polygons::iterator it = holes.begin(); it != holes.end(); ++it) {
- (*it).scale(factor);
- }
+ for (Polygon &hole : holes)
+ hole.scale(factor);
}
-void
-ExPolygon::translate(double x, double y)
+void ExPolygon::translate(double x, double y)
{
contour.translate(x, y);
- for (Polygons::iterator it = holes.begin(); it != holes.end(); ++it) {
- (*it).translate(x, y);
- }
+ for (Polygon &hole : holes)
+ hole.translate(x, y);
}
-void
-ExPolygon::rotate(double angle)
+void ExPolygon::rotate(double angle)
{
contour.rotate(angle);
- for (Polygons::iterator it = holes.begin(); it != holes.end(); ++it) {
- (*it).rotate(angle);
- }
+ for (Polygon &hole : holes)
+ hole.rotate(angle);
}
-void
-ExPolygon::rotate(double angle, const Point &center)
+void ExPolygon::rotate(double angle, const Point &center)
{
contour.rotate(angle, center);
- for (Polygons::iterator it = holes.begin(); it != holes.end(); ++it) {
- (*it).rotate(angle, center);
- }
+ for (Polygon &hole : holes)
+ hole.rotate(angle, center);
}
-double
-ExPolygon::area() const
+double ExPolygon::area() const
{
double a = this->contour.area();
- for (Polygons::const_iterator it = this->holes.begin(); it != this->holes.end(); ++it) {
- a -= -(*it).area(); // holes have negative area
- }
+ for (const Polygon &hole : holes)
+ a -= - hole.area(); // holes have negative area
return a;
}
-bool
-ExPolygon::is_valid() const
+bool ExPolygon::is_valid() const
{
if (!this->contour.is_valid() || !this->contour.is_counter_clockwise()) return false;
for (Polygons::const_iterator it = this->holes.begin(); it != this->holes.end(); ++it) {
@@ -90,20 +79,17 @@ ExPolygon::is_valid() const
return true;
}
-bool
-ExPolygon::contains(const Line &line) const
+bool ExPolygon::contains(const Line &line) const
{
- return this->contains((Polyline)line);
+ return this->contains(Polyline(line.a, line.b));
}
-bool
-ExPolygon::contains(const Polyline &polyline) const
+bool ExPolygon::contains(const Polyline &polyline) const
{
return diff_pl((Polylines)polyline, *this).empty();
}
-bool
-ExPolygon::contains(const Polylines &polylines) const
+bool ExPolygon::contains(const Polylines &polylines) const
{
#if 0
BoundingBox bbox = get_extents(polylines);
@@ -120,8 +106,7 @@ ExPolygon::contains(const Polylines &polylines) const
return pl_out.empty();
}
-bool
-ExPolygon::contains(const Point &point) const
+bool ExPolygon::contains(const Point &point) const
{
if (!this->contour.contains(point)) return false;
for (Polygons::const_iterator it = this->holes.begin(); it != this->holes.end(); ++it) {
@@ -131,8 +116,7 @@ ExPolygon::contains(const Point &point) const
}
// inclusive version of contains() that also checks whether point is on boundaries
-bool
-ExPolygon::contains_b(const Point &point) const
+bool ExPolygon::contains_b(const Point &point) const
{
return this->contains(point) || this->has_boundary_point(point);
}
@@ -243,25 +227,24 @@ ExPolygon::medial_axis(double max_width, double min_width, ThickPolylines* polyl
Point new_front = polyline.points.front();
Point new_back = polyline.points.back();
if (polyline.endpoints.first && !this->has_boundary_point(new_front)) {
- Line line(polyline.points.front(), polyline.points[1]);
-
+ Vec2d p1 = polyline.points.front().cast<double>();
+ Vec2d p2 = polyline.points[1].cast<double>();
// prevent the line from touching on the other side, otherwise intersection() might return that solution
- if (polyline.points.size() == 2) line.b = line.midpoint();
-
- line.extend_start(max_width);
- (void)this->contour.intersection(line, &new_front);
+ if (polyline.points.size() == 2)
+ p2 = (p1 + p2) * 0.5;
+ // Extend the start of the segment.
+ p1 -= (p2 - p1).normalized() * max_width;
+ this->contour.intersection(Line(p1.cast<coord_t>(), p2.cast<coord_t>()), &new_front);
}
if (polyline.endpoints.second && !this->has_boundary_point(new_back)) {
- Line line(
- *(polyline.points.end() - 2),
- polyline.points.back()
- );
-
+ Vec2d p1 = (polyline.points.end() - 2)->cast<double>();
+ Vec2d p2 = polyline.points.back().cast<double>();
// prevent the line from touching on the other side, otherwise intersection() might return that solution
- if (polyline.points.size() == 2) line.a = line.midpoint();
- line.extend_end(max_width);
-
- (void)this->contour.intersection(line, &new_back);
+ if (polyline.points.size() == 2)
+ p1 = (p1 + p2) * 0.5;
+ // Extend the start of the segment.
+ p2 += (p2 - p1).normalized() * max_width;
+ this->contour.intersection(Line(p1.cast<coord_t>(), p2.cast<coord_t>()), &new_back);
}
polyline.points.front() = new_front;
polyline.points.back() = new_back;
@@ -294,14 +277,14 @@ ExPolygon::medial_axis(double max_width, double min_width, ThickPolylines* polyl
// find another polyline starting here
for (size_t j = i+1; j < pp.size(); ++j) {
ThickPolyline& other = pp[j];
- if (polyline.last_point().coincides_with(other.last_point())) {
+ if (polyline.last_point() == other.last_point()) {
other.reverse();
- } else if (polyline.first_point().coincides_with(other.last_point())) {
+ } else if (polyline.first_point() == other.last_point()) {
polyline.reverse();
other.reverse();
- } else if (polyline.first_point().coincides_with(other.first_point())) {
+ } else if (polyline.first_point() == other.first_point()) {
polyline.reverse();
- } else if (!polyline.last_point().coincides_with(other.first_point())) {
+ } else if (polyline.last_point() != other.first_point()) {
continue;
}
@@ -361,7 +344,7 @@ ExPolygon::get_trapezoids2(Polygons* polygons) const
std::vector<coord_t> xx;
xx.reserve(pp.size());
for (Points::const_iterator p = pp.begin(); p != pp.end(); ++p)
- xx.push_back(p->x);
+ xx.push_back(p->x());
std::sort(xx.begin(), xx.end());
// find trapezoids by looping from first to next-to-last coordinate
@@ -372,14 +355,14 @@ ExPolygon::get_trapezoids2(Polygons* polygons) const
// build rectangle
Polygon poly;
poly.points.resize(4);
- poly[0].x = *x;
- poly[0].y = bb.min.y;
- poly[1].x = next_x;
- poly[1].y = bb.min.y;
- poly[2].x = next_x;
- poly[2].y = bb.max.y;
- poly[3].x = *x;
- poly[3].y = bb.max.y;
+ poly[0](0) = *x;
+ poly[0](1) = bb.min(1);
+ poly[1](0) = next_x;
+ poly[1](1) = bb.min(1);
+ poly[2](0) = next_x;
+ poly[2](1) = bb.max(1);
+ poly[3](0) = *x;
+ poly[3](1) = bb.max(1);
// intersect with this expolygon
// append results to return value
@@ -425,10 +408,11 @@ ExPolygon::triangulate_pp(Polygons* polygons) const
TPPLPoly p;
p.Init(int(ex->contour.points.size()));
//printf(PRINTF_ZU "\n0\n", ex->contour.points.size());
- for (Points::const_iterator point = ex->contour.points.begin(); point != ex->contour.points.end(); ++point) {
- p[ point-ex->contour.points.begin() ].x = point->x;
- p[ point-ex->contour.points.begin() ].y = point->y;
- //printf("%ld %ld\n", point->x, point->y);
+ for (const Point &point : ex->contour.points) {
+ size_t i = &point - &ex->contour.points.front();
+ p[i].x = point(0);
+ p[i].y = point(1);
+ //printf("%ld %ld\n", point->x(), point->y());
}
p.SetHole(false);
input.push_back(p);
@@ -439,10 +423,11 @@ ExPolygon::triangulate_pp(Polygons* polygons) const
TPPLPoly p;
p.Init(hole->points.size());
//printf(PRINTF_ZU "\n1\n", hole->points.size());
- for (Points::const_iterator point = hole->points.begin(); point != hole->points.end(); ++point) {
- p[ point-hole->points.begin() ].x = point->x;
- p[ point-hole->points.begin() ].y = point->y;
- //printf("%ld %ld\n", point->x, point->y);
+ for (const Point &point : hole->points) {
+ size_t i = &point - &hole->points.front();
+ p[i].x = point(0);
+ p[i].y = point(1);
+ //printf("%ld %ld\n", point->x(), point->y());
}
p.SetHole(true);
input.push_back(p);
@@ -460,8 +445,8 @@ ExPolygon::triangulate_pp(Polygons* polygons) const
Polygon p;
p.points.resize(num_points);
for (long i = 0; i < num_points; ++i) {
- p.points[i].x = coord_t((*poly)[i].x);
- p.points[i].y = coord_t((*poly)[i].y);
+ p.points[i](0) = coord_t((*poly)[i].x);
+ p.points[i](1) = coord_t((*poly)[i].y);
}
polygons->push_back(p);
}
@@ -477,19 +462,17 @@ ExPolygon::triangulate_p2t(Polygons* polygons) const
// contour
std::vector<p2t::Point*> ContourPoints;
- for (Points::const_iterator point = ex->contour.points.begin(); point != ex->contour.points.end(); ++point) {
+ for (const Point &pt : ex->contour.points)
// We should delete each p2t::Point object
- ContourPoints.push_back(new p2t::Point(point->x, point->y));
- }
+ ContourPoints.push_back(new p2t::Point(pt(0), pt(1)));
p2t::CDT cdt(ContourPoints);
// holes
for (Polygons::const_iterator hole = ex->holes.begin(); hole != ex->holes.end(); ++hole) {
std::vector<p2t::Point*> points;
- for (Points::const_iterator point = hole->points.begin(); point != hole->points.end(); ++point) {
+ for (const Point &pt : hole->points)
// will be destructed in SweepContext::~SweepContext
- points.push_back(new p2t::Point(point->x, point->y));
- }
+ points.push_back(new p2t::Point(pt(0), pt(1)));
cdt.AddHole(points);
}
@@ -506,9 +489,8 @@ ExPolygon::triangulate_p2t(Polygons* polygons) const
polygons->push_back(p);
}
- for(std::vector<p2t::Point*>::iterator it = ContourPoints.begin(); it != ContourPoints.end(); ++it) {
- delete *it;
- }
+ for (p2t::Point *ptr : ContourPoints)
+ delete ptr;
}
}
@@ -523,17 +505,6 @@ ExPolygon::lines() const
return lines;
}
-std::string
-ExPolygon::dump_perl() const
-{
- std::ostringstream ret;
- ret << "[" << this->contour.dump_perl();
- for (Polygons::const_iterator h = this->holes.begin(); h != this->holes.end(); ++h)
- ret << "," << h->dump_perl();
- ret << "]";
- return ret.str();
-}
-
BoundingBox get_extents(const ExPolygon &expolygon)
{
return get_extents(expolygon.contour);
diff --git a/xs/src/libslic3r/ExPolygon.hpp b/xs/src/libslic3r/ExPolygon.hpp
index f4782ba55..4833ee49e 100644
--- a/xs/src/libslic3r/ExPolygon.hpp
+++ b/xs/src/libslic3r/ExPolygon.hpp
@@ -63,7 +63,6 @@ public:
void triangulate_pp(Polygons* polygons) const;
void triangulate_p2t(Polygons* polygons) const;
Lines lines() const;
- std::string dump_perl() const;
};
// Count a nuber of polygons stored inside the vector of expolygons.
diff --git a/xs/src/libslic3r/ExtrusionEntity.cpp b/xs/src/libslic3r/ExtrusionEntity.cpp
index c6f67b169..92f0d3669 100644
--- a/xs/src/libslic3r/ExtrusionEntity.cpp
+++ b/xs/src/libslic3r/ExtrusionEntity.cpp
@@ -220,7 +220,7 @@ void ExtrusionLoop::split_at(const Point &point, bool prefer_non_overhang)
double min_non_overhang = std::numeric_limits<double>::max();
for (ExtrusionPaths::const_iterator path = this->paths.begin(); path != this->paths.end(); ++path) {
Point p_tmp = point.projection_onto(path->polyline);
- double dist = point.distance_to(p_tmp);
+ double dist = (p_tmp - point).cast<double>().norm();
if (dist < min) {
p = p_tmp;
min = dist;
diff --git a/xs/src/libslic3r/ExtrusionEntity.hpp b/xs/src/libslic3r/ExtrusionEntity.hpp
index 15363e8ed..90675c04a 100644
--- a/xs/src/libslic3r/ExtrusionEntity.hpp
+++ b/xs/src/libslic3r/ExtrusionEntity.hpp
@@ -149,7 +149,7 @@ public:
// Minimum volumetric velocity of this extrusion entity. Used by the constant nozzle pressure algorithm.
double min_mm3_per_mm() const { return this->mm3_per_mm; }
Polyline as_polyline() const { return this->polyline; }
- virtual double total_volume() const { return mm3_per_mm * unscale(length()); }
+ virtual double total_volume() const { return mm3_per_mm * unscale<double>(length()); }
private:
void _inflate_collection(const Polylines &polylines, ExtrusionEntityCollection* collection) const;
diff --git a/xs/src/libslic3r/ExtrusionEntityCollection.hpp b/xs/src/libslic3r/ExtrusionEntityCollection.hpp
index 382455fe3..3b34145f8 100644
--- a/xs/src/libslic3r/ExtrusionEntityCollection.hpp
+++ b/xs/src/libslic3r/ExtrusionEntityCollection.hpp
@@ -50,10 +50,15 @@ public:
src.clear();
}
}
- void append(const ExtrusionPaths &paths) {
+ void append(const ExtrusionPaths &paths) {
this->entities.reserve(this->entities.size() + paths.size());
- for (ExtrusionPaths::const_iterator path = paths.begin(); path != paths.end(); ++path)
- this->entities.push_back(path->clone());
+ for (const ExtrusionPath &path : paths)
+ this->entities.emplace_back(path.clone());
+ }
+ void append(ExtrusionPaths &&paths) {
+ this->entities.reserve(this->entities.size() + paths.size());
+ for (ExtrusionPath &path : paths)
+ this->entities.emplace_back(new ExtrusionPath(std::move(path)));
}
void replace(size_t i, const ExtrusionEntity &entity);
void remove(size_t i);
diff --git a/xs/src/libslic3r/ExtrusionSimulator.cpp b/xs/src/libslic3r/ExtrusionSimulator.cpp
index daecbc0d1..fcb2fe825 100644
--- a/xs/src/libslic3r/ExtrusionSimulator.cpp
+++ b/xs/src/libslic3r/ExtrusionSimulator.cpp
@@ -893,24 +893,24 @@ ExtrusionSimulator::~ExtrusionSimulator()
void ExtrusionSimulator::set_image_size(const Point &image_size)
{
// printf("ExtrusionSimulator::set_image_size()\n");
- if (this->image_size.x == image_size.x &&
- this->image_size.y == image_size.y)
+ if (this->image_size.x() == image_size.x() &&
+ this->image_size.y() == image_size.y())
return;
// printf("Setting image size: %d, %d\n", image_size.x, image_size.y);
this->image_size = image_size;
// Allocate the image data in an RGBA format.
// printf("Allocating image data, size %d\n", image_size.x * image_size.y * 4);
- pimpl->image_data.assign(image_size.x * image_size.y * 4, 0);
+ pimpl->image_data.assign(image_size.x() * image_size.y() * 4, 0);
// printf("Allocating image data, allocated\n");
//FIXME fill the image with red vertical lines.
- for (size_t r = 0; r < image_size.y; ++ r) {
- for (size_t c = 0; c < image_size.x; c += 2) {
+ for (size_t r = 0; r < image_size.y(); ++ r) {
+ for (size_t c = 0; c < image_size.x(); c += 2) {
// Color red
- pimpl->image_data[r * image_size.x * 4 + c * 4] = 255;
+ pimpl->image_data[r * image_size.x() * 4 + c * 4] = 255;
// Opacity full
- pimpl->image_data[r * image_size.x * 4 + c * 4 + 3] = 255;
+ pimpl->image_data[r * image_size.x() * 4 + c * 4 + 3] = 255;
}
}
// printf("Allocating image data, set\n");
@@ -922,8 +922,8 @@ void ExtrusionSimulator::set_viewport(const BoundingBox &viewport)
if (this->viewport != viewport) {
this->viewport = viewport;
Point sz = viewport.size();
- pimpl->accumulator.resize(boost::extents[sz.y][sz.x]);
- pimpl->bitmap.resize(boost::extents[sz.y*pimpl->bitmap_oversampled][sz.x*pimpl->bitmap_oversampled]);
+ pimpl->accumulator.resize(boost::extents[sz.y()][sz.x()]);
+ pimpl->bitmap.resize(boost::extents[sz.y()*pimpl->bitmap_oversampled][sz.x()*pimpl->bitmap_oversampled]);
// printf("Accumulator size: %d, %d\n", sz.y, sz.x);
}
}
@@ -943,8 +943,8 @@ void ExtrusionSimulator::reset_accumulator()
// printf("ExtrusionSimulator::reset_accumulator()\n");
Point sz = viewport.size();
// printf("Reset accumulator, Accumulator size: %d, %d\n", sz.y, sz.x);
- memset(&pimpl->accumulator[0][0], 0, sizeof(float) * sz.x * sz.y);
- memset(&pimpl->bitmap[0][0], 0, sz.x * sz.y * pimpl->bitmap_oversampled * pimpl->bitmap_oversampled);
+ memset(&pimpl->accumulator[0][0], 0, sizeof(float) * sz.x() * sz.y());
+ memset(&pimpl->bitmap[0][0], 0, sz.x() * sz.y() * pimpl->bitmap_oversampled * pimpl->bitmap_oversampled);
pimpl->extrusion_points.clear();
// printf("Reset accumulator, done.\n");
}
@@ -955,17 +955,17 @@ void ExtrusionSimulator::extrude_to_accumulator(const ExtrusionPath &path, const
// Convert the path to V2f points, shift and scale them to the viewport.
std::vector<V2f> polyline;
polyline.reserve(path.polyline.points.size());
- float scalex = float(viewport.size().x) / float(bbox.size().x);
- float scaley = float(viewport.size().y) / float(bbox.size().y);
+ float scalex = float(viewport.size().x()) / float(bbox.size().x());
+ float scaley = float(viewport.size().y()) / float(bbox.size().y());
float w = scale_(path.width) * scalex;
float h = scale_(path.height) * scalex;
w = scale_(path.mm3_per_mm / path.height) * scalex;
// printf("scalex: %f, scaley: %f\n", scalex, scaley);
- // printf("bbox: %d,%d %d,%d\n", bbox.min.x, bbox.min.y, bbox.max.x, bbox.max.y);
+ // printf("bbox: %d,%d %d,%d\n", bbox.min.x(), bbox.min.y, bbox.max.x(), bbox.max.y);
for (Points::const_iterator it = path.polyline.points.begin(); it != path.polyline.points.end(); ++ it) {
- // printf("point %d,%d\n", it->x+shift.x, it->y+shift.y);
+ // printf("point %d,%d\n", it->x+shift.x(), it->y+shift.y);
ExtrusionPoint ept;
- ept.center = V2f(float(it->x+shift.x-bbox.min.x) * scalex, float(it->y+shift.y-bbox.min.y) * scaley);
+ ept.center = V2f(float((*it)(0)+shift.x()-bbox.min.x()) * scalex, float((*it)(1)+shift.y()-bbox.min.y()) * scaley);
ept.radius = w/2.f;
ept.height = 0.5f;
polyline.push_back(ept.center);
@@ -989,9 +989,9 @@ void ExtrusionSimulator::evaluate_accumulator(ExtrusionSimulationType simulation
if (simulationType > ExtrusionSimulationDontSpread) {
// Average the cells of a bitmap into a lower resolution floating point mask.
- A2f mask(boost::extents[sz.y][sz.x]);
- for (int r = 0; r < sz.y; ++r) {
- for (int c = 0; c < sz.x; ++c) {
+ A2f mask(boost::extents[sz.y()][sz.x()]);
+ for (int r = 0; r < sz.y(); ++r) {
+ for (int c = 0; c < sz.x(); ++c) {
float p = 0;
for (int j = 0; j < pimpl->bitmap_oversampled; ++ j) {
for (int i = 0; i < pimpl->bitmap_oversampled; ++ i) {
@@ -1009,9 +1009,9 @@ void ExtrusionSimulator::evaluate_accumulator(ExtrusionSimulationType simulation
}
// Color map the accumulator.
- for (int r = 0; r < sz.y; ++r) {
- unsigned char *ptr = &pimpl->image_data[(image_size.x * (viewport.min.y + r) + viewport.min.x) * 4];
- for (int c = 0; c < sz.x; ++c) {
+ for (int r = 0; r < sz.y(); ++r) {
+ unsigned char *ptr = &pimpl->image_data[(image_size.x() * (viewport.min.y() + r) + viewport.min.x()) * 4];
+ for (int c = 0; c < sz.x(); ++c) {
#if 1
float p = pimpl->accumulator[r][c];
#else
diff --git a/xs/src/libslic3r/Fill/Fill3DHoneycomb.cpp b/xs/src/libslic3r/Fill/Fill3DHoneycomb.cpp
index aa9774784..6a37e4369 100644
--- a/xs/src/libslic3r/Fill/Fill3DHoneycomb.cpp
+++ b/xs/src/libslic3r/Fill/Fill3DHoneycomb.cpp
@@ -54,9 +54,9 @@ static std::vector<coordf_t> perpendPoints(const coordf_t offset, const size_t b
// components that are outside these limits are set to the limits.
static inline void trim(Pointfs &pts, coordf_t minX, coordf_t minY, coordf_t maxX, coordf_t maxY)
{
- for (Pointfs::iterator it = pts.begin(); it != pts.end(); ++ it) {
- it->x = clamp(minX, maxX, it->x);
- it->y = clamp(minY, maxY, it->y);
+ for (Vec2d &pt : pts) {
+ pt(0) = clamp(minX, maxX, pt(0));
+ pt(1) = clamp(minY, maxY, pt(1));
}
}
@@ -66,7 +66,7 @@ static inline Pointfs zip(const std::vector<coordf_t> &x, const std::vector<coor
Pointfs out;
out.reserve(x.size());
for (size_t i = 0; i < x.size(); ++ i)
- out.push_back(Pointf(x[i], y[i]));
+ out.push_back(Vec2d(x[i], y[i]));
return out;
}
@@ -128,7 +128,7 @@ static Polylines makeGrid(coord_t z, coord_t gridSize, size_t gridWidth, size_t
result.push_back(Polyline());
Polyline &polyline = result.back();
for (Pointfs::const_iterator it = it_polylines->begin(); it != it_polylines->end(); ++ it)
- polyline.points.push_back(Point(coord_t(it->x * scaleFactor), coord_t(it->y * scaleFactor)));
+ polyline.points.push_back(Point(coord_t((*it)(0) * scaleFactor), coord_t((*it)(1) * scaleFactor)));
}
return result;
}
@@ -153,13 +153,13 @@ void Fill3DHoneycomb::_fill_surface_single(
Polylines polylines = makeGrid(
scale_(this->z),
distance,
- ceil(bb.size().x / distance) + 1,
- ceil(bb.size().y / distance) + 1,
+ ceil(bb.size()(0) / distance) + 1,
+ ceil(bb.size()(1) / distance) + 1,
((this->layer_id/thickness_layers) % 2) + 1);
// move pattern in place
for (Polylines::iterator it = polylines.begin(); it != polylines.end(); ++ it)
- it->translate(bb.min.x, bb.min.y);
+ it->translate(bb.min(0), bb.min(1));
// clip pattern to boundaries
polylines = intersection_pl(polylines, (Polygons)expolygon);
@@ -187,7 +187,7 @@ void Fill3DHoneycomb::_fill_surface_single(
const Point &last_point = pts_end.back();
// TODO: we should also check that both points are on a fill_boundary to avoid
// connecting paths on the boundaries of internal regions
- if (first_point.distance_to(last_point) <= 1.5 * distance &&
+ if ((last_point - first_point).cast<double>().norm() <= 1.5 * distance &&
expolygon_off.contains(Line(last_point, first_point))) {
// Append the polyline.
pts_end.insert(pts_end.end(), it_polyline->points.begin(), it_polyline->points.end());
diff --git a/xs/src/libslic3r/Fill/FillBase.hpp b/xs/src/libslic3r/Fill/FillBase.hpp
index 62d18e518..b67d14339 100644
--- a/xs/src/libslic3r/Fill/FillBase.hpp
+++ b/xs/src/libslic3r/Fill/FillBase.hpp
@@ -121,11 +121,11 @@ public:
return aligned;
}
static Point _align_to_grid(Point coord, Point spacing)
- { return Point(_align_to_grid(coord.x, spacing.x), _align_to_grid(coord.y, spacing.y)); }
+ { return Point(_align_to_grid(coord(0), spacing(0)), _align_to_grid(coord(1), spacing(1))); }
static coord_t _align_to_grid(coord_t coord, coord_t spacing, coord_t base)
{ return base + _align_to_grid(coord - base, spacing); }
static Point _align_to_grid(Point coord, Point spacing, Point base)
- { return Point(_align_to_grid(coord.x, spacing.x, base.x), _align_to_grid(coord.y, spacing.y, base.y)); }
+ { return Point(_align_to_grid(coord(0), spacing(0), base(0)), _align_to_grid(coord(1), spacing(1), base(1))); }
};
} // namespace Slic3r
diff --git a/xs/src/libslic3r/Fill/FillConcentric.cpp b/xs/src/libslic3r/Fill/FillConcentric.cpp
index b21ad2799..8a3a7ea89 100644
--- a/xs/src/libslic3r/Fill/FillConcentric.cpp
+++ b/xs/src/libslic3r/Fill/FillConcentric.cpp
@@ -20,8 +20,8 @@ void FillConcentric::_fill_surface_single(
coord_t distance = coord_t(min_spacing / params.density);
if (params.density > 0.9999f && !params.dont_adjust) {
- distance = this->_adjust_solid_spacing(bounding_box.size().x, distance);
- this->spacing = unscale(distance);
+ distance = this->_adjust_solid_spacing(bounding_box.size()(0), distance);
+ this->spacing = unscale<double>(distance);
}
Polygons loops = (Polygons)expolygon;
diff --git a/xs/src/libslic3r/Fill/FillGyroid.cpp b/xs/src/libslic3r/Fill/FillGyroid.cpp
index 89d5d231e..d6bf03ce6 100644
--- a/xs/src/libslic3r/Fill/FillGyroid.cpp
+++ b/xs/src/libslic3r/Fill/FillGyroid.cpp
@@ -30,39 +30,39 @@ static inline double f(double x, double z_sin, double z_cos, bool vertical, bool
}
static inline Polyline make_wave(
- const std::vector<Pointf>& one_period, double width, double height, double offset, double scaleFactor,
+ const std::vector<Vec2d>& one_period, double width, double height, double offset, double scaleFactor,
double z_cos, double z_sin, bool vertical)
{
- std::vector<Pointf> points = one_period;
- double period = points.back().x;
+ std::vector<Vec2d> points = one_period;
+ double period = points.back()(0);
points.pop_back();
int n = points.size();
do {
- points.emplace_back(Pointf(points[points.size()-n].x + period, points[points.size()-n].y));
- } while (points.back().x < width);
- points.back().x = width;
+ points.emplace_back(Vec2d(points[points.size()-n](0) + period, points[points.size()-n](1)));
+ } while (points.back()(0) < width);
+ points.back()(0) = width;
// and construct the final polyline to return:
Polyline polyline;
for (auto& point : points) {
- point.y += offset;
- point.y = clamp(0., height, double(point.y));
+ point(1) += offset;
+ point(1) = clamp(0., height, double(point(1)));
if (vertical)
- std::swap(point.x, point.y);
- polyline.points.emplace_back(convert_to<Point>(point * scaleFactor));
+ std::swap(point(0), point(1));
+ polyline.points.emplace_back((point * scaleFactor).cast<coord_t>());
}
return polyline;
}
-static std::vector<Pointf> make_one_period(double width, double scaleFactor, double z_cos, double z_sin, bool vertical, bool flip)
+static std::vector<Vec2d> make_one_period(double width, double scaleFactor, double z_cos, double z_sin, bool vertical, bool flip)
{
- std::vector<Pointf> points;
+ std::vector<Vec2d> points;
double dx = M_PI_4; // very coarse spacing to begin with
double limit = std::min(2*M_PI, width);
for (double x = 0.; x < limit + EPSILON; x += dx) { // so the last point is there too
x = std::min(x, limit);
- points.emplace_back(Pointf(x,f(x, z_sin,z_cos, vertical, flip)));
+ points.emplace_back(Vec2d(x,f(x, z_sin,z_cos, vertical, flip)));
}
// now we will check all internal points and in case some are too far from the line connecting its neighbours,
@@ -71,17 +71,19 @@ static std::vector<Pointf> make_one_period(double width, double scaleFactor, dou
for (unsigned int i=1;i<points.size()-1;++i) {
auto& lp = points[i-1]; // left point
auto& tp = points[i]; // this point
+ Vec2d lrv = tp - lp;
auto& rp = points[i+1]; // right point
// calculate distance of the point to the line:
- double dist_mm = unscale(scaleFactor * std::abs( (rp.y - lp.y)*tp.x + (lp.x - rp.x)*tp.y + (rp.x*lp.y - rp.y*lp.x) ) / std::hypot((rp.y - lp.y),(lp.x - rp.x)));
-
+ double dist_mm = unscale<double>(scaleFactor) * std::abs(cross2(rp, lp) - cross2(rp - lp, tp)) / lrv.norm();
if (dist_mm > tolerance) { // if the difference from straight line is more than this
- double x = 0.5f * (points[i-1].x + points[i].x);
- points.emplace_back(Pointf(x, f(x, z_sin, z_cos, vertical, flip)));
- x = 0.5f * (points[i+1].x + points[i].x);
- points.emplace_back(Pointf(x, f(x, z_sin, z_cos, vertical, flip)));
- std::sort(points.begin(), points.end()); // we added the points to the end, but need them all in order
- --i; // decrement i so we also check the first newly added point
+ double x = 0.5f * (points[i-1](0) + points[i](0));
+ points.emplace_back(Vec2d(x, f(x, z_sin, z_cos, vertical, flip)));
+ x = 0.5f * (points[i+1](0) + points[i](0));
+ points.emplace_back(Vec2d(x, f(x, z_sin, z_cos, vertical, flip)));
+ // we added the points to the end, but need them all in order
+ std::sort(points.begin(), points.end(), [](const Vec2d &lhs, const Vec2d &rhs){ return lhs < rhs; });
+ // decrement i so we also check the first newly added point
+ --i;
}
}
return points;
@@ -107,7 +109,7 @@ static Polylines make_gyroid_waves(double gridZ, double density_adjusted, double
std::swap(width,height);
}
- std::vector<Pointf> one_period = make_one_period(width, scaleFactor, z_cos, z_sin, vertical, flip); // creates one period of the waves, so it doesn't have to be recalculated all the time
+ std::vector<Vec2d> one_period = make_one_period(width, scaleFactor, z_cos, z_sin, vertical, flip); // creates one period of the waves, so it doesn't have to be recalculated all the time
Polylines result;
for (double y0 = lower_bound; y0 < upper_bound+EPSILON; y0 += 2*M_PI) // creates odd polylines
@@ -143,12 +145,12 @@ void FillGyroid::_fill_surface_single(
scale_(this->z),
density_adjusted,
this->spacing,
- ceil(bb.size().x / distance) + 1.,
- ceil(bb.size().y / distance) + 1.);
+ ceil(bb.size()(0) / distance) + 1.,
+ ceil(bb.size()(1) / distance) + 1.);
// move pattern in place
for (Polyline &polyline : polylines)
- polyline.translate(bb.min.x, bb.min.y);
+ polyline.translate(bb.min(0), bb.min(1));
// clip pattern to boundaries
polylines = intersection_pl(polylines, (Polygons)expolygon);
@@ -177,7 +179,7 @@ void FillGyroid::_fill_surface_single(
// TODO: we should also check that both points are on a fill_boundary to avoid
// connecting paths on the boundaries of internal regions
// TODO: avoid crossing current infill path
- if (first_point.distance_to(last_point) <= 5 * distance &&
+ if ((last_point - first_point).cast<double>().norm() <= 5 * distance &&
expolygon_off.contains(Line(last_point, first_point))) {
// Append the polyline.
pts_end.insert(pts_end.end(), polyline.points.begin(), polyline.points.end());
diff --git a/xs/src/libslic3r/Fill/FillHoneycomb.cpp b/xs/src/libslic3r/Fill/FillHoneycomb.cpp
index aa0e0f6b0..6f26167a2 100644
--- a/xs/src/libslic3r/Fill/FillHoneycomb.cpp
+++ b/xs/src/libslic3r/Fill/FillHoneycomb.cpp
@@ -50,13 +50,13 @@ void FillHoneycomb::_fill_surface_single(
bounding_box.merge(_align_to_grid(bounding_box.min, Point(m.hex_width, m.pattern_height)));
}
- coord_t x = bounding_box.min.x;
- while (x <= bounding_box.max.x) {
+ coord_t x = bounding_box.min(0);
+ while (x <= bounding_box.max(0)) {
Polygon p;
coord_t ax[2] = { x + m.x_offset, x + m.distance - m.x_offset };
for (size_t i = 0; i < 2; ++ i) {
std::reverse(p.points.begin(), p.points.end()); // turn first half upside down
- for (coord_t y = bounding_box.min.y; y <= bounding_box.max.y; y += m.y_short + m.hex_side + m.y_short + m.hex_side) {
+ for (coord_t y = bounding_box.min(1); y <= bounding_box.max(1); y += m.y_short + m.hex_side + m.y_short + m.hex_side) {
p.points.push_back(Point(ax[1], y + m.y_offset));
p.points.push_back(Point(ax[0], y + m.y_short - m.y_offset));
p.points.push_back(Point(ax[0], y + m.y_short + m.hex_side + m.y_offset));
@@ -101,7 +101,7 @@ void FillHoneycomb::_fill_surface_single(
for (Polylines::iterator it_path = chained.begin(); it_path != chained.end(); ++ it_path) {
if (! paths.empty()) {
// distance between first point of this path and last point of last path
- double distance = paths.back().last_point().distance_to(it_path->first_point());
+ double distance = (it_path->first_point() - paths.back().last_point()).cast<double>().norm();
if (distance <= m.hex_width) {
paths.back().points.insert(paths.back().points.end(), it_path->points.begin(), it_path->points.end());
continue;
diff --git a/xs/src/libslic3r/Fill/FillPlanePath.cpp b/xs/src/libslic3r/Fill/FillPlanePath.cpp
index f71ef95a1..615cc6efe 100644
--- a/xs/src/libslic3r/Fill/FillPlanePath.cpp
+++ b/xs/src/libslic3r/Fill/FillPlanePath.cpp
@@ -24,14 +24,14 @@ void FillPlanePath::_fill_surface_single(
Point shift = this->_centered() ?
bounding_box.center() :
bounding_box.min;
- expolygon.translate(-shift.x, -shift.y);
- bounding_box.translate(-shift.x, -shift.y);
+ expolygon.translate(-shift(0), -shift(1));
+ bounding_box.translate(-shift(0), -shift(1));
Pointfs pts = _generate(
- coord_t(ceil(coordf_t(bounding_box.min.x) / distance_between_lines)),
- coord_t(ceil(coordf_t(bounding_box.min.y) / distance_between_lines)),
- coord_t(ceil(coordf_t(bounding_box.max.x) / distance_between_lines)),
- coord_t(ceil(coordf_t(bounding_box.max.y) / distance_between_lines)));
+ coord_t(ceil(coordf_t(bounding_box.min(0)) / distance_between_lines)),
+ coord_t(ceil(coordf_t(bounding_box.min(1)) / distance_between_lines)),
+ coord_t(ceil(coordf_t(bounding_box.max(0)) / distance_between_lines)),
+ coord_t(ceil(coordf_t(bounding_box.max(1)) / distance_between_lines)));
Polylines polylines;
if (pts.size() >= 2) {
@@ -41,8 +41,8 @@ void FillPlanePath::_fill_surface_single(
polyline.points.reserve(pts.size());
for (Pointfs::iterator it = pts.begin(); it != pts.end(); ++ it)
polyline.points.push_back(Point(
- coord_t(floor(it->x * distance_between_lines + 0.5)),
- coord_t(floor(it->y * distance_between_lines + 0.5))));
+ coord_t(floor((*it)(0) * distance_between_lines + 0.5)),
+ coord_t(floor((*it)(1) * distance_between_lines + 0.5))));
// intersection(polylines_src, offset((Polygons)expolygon, scale_(0.02)), &polylines);
polylines = intersection_pl(polylines, to_polygons(expolygon));
@@ -62,7 +62,7 @@ void FillPlanePath::_fill_surface_single(
// paths must be repositioned and rotated back
for (Polylines::iterator it = polylines.begin(); it != polylines.end(); ++ it) {
- it->translate(shift.x, shift.y);
+ it->translate(shift(0), shift(1));
it->rotate(direction.first);
}
}
@@ -86,12 +86,12 @@ Pointfs FillArchimedeanChords::_generate(coord_t min_x, coord_t min_y, coord_t m
coordf_t r = 1;
Pointfs out;
//FIXME Vojtech: If used as a solid infill, there is a gap left at the center.
- out.push_back(Pointf(0, 0));
- out.push_back(Pointf(1, 0));
+ out.push_back(Vec2d(0, 0));
+ out.push_back(Vec2d(1, 0));
while (r < rmax) {
theta += 1. / r;
r = a + b * theta;
- out.push_back(Pointf(r * cos(theta), r * sin(theta)));
+ out.push_back(Vec2d(r * cos(theta), r * sin(theta)));
}
return out;
}
@@ -162,7 +162,7 @@ Pointfs FillHilbertCurve::_generate(coord_t min_x, coord_t min_y, coord_t max_x,
line.reserve(sz2);
for (size_t i = 0; i < sz2; ++ i) {
Point p = hilbert_n_to_xy(i);
- line.push_back(Pointf(p.x + min_x, p.y + min_y));
+ line.push_back(Vec2d(p(0) + min_x, p(1) + min_y));
}
return line;
}
@@ -175,27 +175,27 @@ Pointfs FillOctagramSpiral::_generate(coord_t min_x, coord_t min_y, coord_t max_
coordf_t r = 0;
coordf_t r_inc = sqrt(2.);
Pointfs out;
- out.push_back(Pointf(0, 0));
+ out.push_back(Vec2d(0, 0));
while (r < rmax) {
r += r_inc;
coordf_t rx = r / sqrt(2.);
coordf_t r2 = r + rx;
- out.push_back(Pointf( r, 0.));
- out.push_back(Pointf( r2, rx));
- out.push_back(Pointf( rx, rx));
- out.push_back(Pointf( rx, r2));
- out.push_back(Pointf(0., r));
- out.push_back(Pointf(-rx, r2));
- out.push_back(Pointf(-rx, rx));
- out.push_back(Pointf(-r2, rx));
- out.push_back(Pointf(-r, 0.));
- out.push_back(Pointf(-r2, -rx));
- out.push_back(Pointf(-rx, -rx));
- out.push_back(Pointf(-rx, -r2));
- out.push_back(Pointf(0., -r));
- out.push_back(Pointf( rx, -r2));
- out.push_back(Pointf( rx, -rx));
- out.push_back(Pointf( r2+r_inc, -rx));
+ out.push_back(Vec2d( r, 0.));
+ out.push_back(Vec2d( r2, rx));
+ out.push_back(Vec2d( rx, rx));
+ out.push_back(Vec2d( rx, r2));
+ out.push_back(Vec2d(0., r));
+ out.push_back(Vec2d(-rx, r2));
+ out.push_back(Vec2d(-rx, rx));
+ out.push_back(Vec2d(-r2, rx));
+ out.push_back(Vec2d(-r, 0.));
+ out.push_back(Vec2d(-r2, -rx));
+ out.push_back(Vec2d(-rx, -rx));
+ out.push_back(Vec2d(-rx, -r2));
+ out.push_back(Vec2d(0., -r));
+ out.push_back(Vec2d( rx, -r2));
+ out.push_back(Vec2d( rx, -rx));
+ out.push_back(Vec2d( r2+r_inc, -rx));
}
return out;
}
diff --git a/xs/src/libslic3r/Fill/FillRectilinear.cpp b/xs/src/libslic3r/Fill/FillRectilinear.cpp
index 5ba30ba51..205eb1b66 100644
--- a/xs/src/libslic3r/Fill/FillRectilinear.cpp
+++ b/xs/src/libslic3r/Fill/FillRectilinear.cpp
@@ -26,8 +26,8 @@ void FillRectilinear::_fill_surface_single(
// define flow spacing according to requested density
if (params.density > 0.9999f && !params.dont_adjust) {
- this->_line_spacing = this->_adjust_solid_spacing(bounding_box.size().x, this->_line_spacing);
- this->spacing = unscale(this->_line_spacing);
+ this->_line_spacing = this->_adjust_solid_spacing(bounding_box.size()(0), this->_line_spacing);
+ this->spacing = unscale<double>(this->_line_spacing);
} else {
// extend bounding box so that our pattern will be aligned with other layers
// Transform the reference point to the rotated coordinate system.
@@ -38,14 +38,14 @@ void FillRectilinear::_fill_surface_single(
}
// generate the basic pattern
- coord_t x_max = bounding_box.max.x + SCALED_EPSILON;
+ coord_t x_max = bounding_box.max(0) + SCALED_EPSILON;
Lines lines;
- for (coord_t x = bounding_box.min.x; x <= x_max; x += this->_line_spacing)
- lines.push_back(this->_line(lines.size(), x, bounding_box.min.y, bounding_box.max.y));
+ for (coord_t x = bounding_box.min(0); x <= x_max; x += this->_line_spacing)
+ lines.push_back(this->_line(lines.size(), x, bounding_box.min(1), bounding_box.max(1)));
if (this->_horizontal_lines()) {
- coord_t y_max = bounding_box.max.y + SCALED_EPSILON;
- for (coord_t y = bounding_box.min.y; y <= y_max; y += this->_line_spacing)
- lines.push_back(Line(Point(bounding_box.min.x, y), Point(bounding_box.max.x, y)));
+ coord_t y_max = bounding_box.max(1) + SCALED_EPSILON;
+ for (coord_t y = bounding_box.min(1); y <= y_max; y += this->_line_spacing)
+ lines.push_back(Line(Point(bounding_box.min(0), y), Point(bounding_box.max(0), y)));
}
// clip paths against a slightly larger expolygon, so that the first and last paths
@@ -72,10 +72,10 @@ void FillRectilinear::_fill_surface_single(
for (Polylines::iterator it_polyline = polylines.begin(); it_polyline != polylines.end(); ++ it_polyline) {
Point *first_point = &it_polyline->points.front();
Point *last_point = &it_polyline->points.back();
- if (first_point->y > last_point->y)
+ if (first_point->y() > last_point->y())
std::swap(first_point, last_point);
- first_point->y -= extra;
- last_point->y += extra;
+ first_point->y() -= extra;
+ last_point->y() += extra;
}
size_t n_polylines_out_old = polylines_out.size();
@@ -103,10 +103,10 @@ void FillRectilinear::_fill_surface_single(
const Point &first_point = it_polyline->points.front();
const Point &last_point = pts_end.back();
// Distance in X, Y.
- const Vector distance = first_point.vector_to(last_point);
+ const Vector distance = last_point - first_point;
// TODO: we should also check that both points are on a fill_boundary to avoid
// connecting paths on the boundaries of internal regions
- if (this->_can_connect(std::abs(distance.x), std::abs(distance.y)) &&
+ if (this->_can_connect(std::abs(distance(0)), std::abs(distance(1))) &&
expolygon_off.contains(Line(last_point, first_point))) {
// Append the polyline.
pts_end.insert(pts_end.end(), it_polyline->points.begin(), it_polyline->points.end());
@@ -122,7 +122,7 @@ void FillRectilinear::_fill_surface_single(
// paths must be rotated back
for (Polylines::iterator it = polylines_out.begin() + n_polylines_out_old; it != polylines_out.end(); ++ it) {
// No need to translate, the absolute position is irrelevant.
- // it->translate(- direction.second.x, - direction.second.y);
+ // it->translate(- direction.second(0), - direction.second(1));
it->rotate(direction.first);
}
}
diff --git a/xs/src/libslic3r/Fill/FillRectilinear2.cpp b/xs/src/libslic3r/Fill/FillRectilinear2.cpp
index ddd785101..65440d0ef 100644
--- a/xs/src/libslic3r/Fill/FillRectilinear2.cpp
+++ b/xs/src/libslic3r/Fill/FillRectilinear2.cpp
@@ -42,12 +42,12 @@ static inline coordf_t segment_length(const Polygon &poly, size_t seg1, const Po
Point px = (i == 0) ? p1 : p2;
Point pa = poly.points[((seg == 0) ? poly.points.size() : seg) - 1];
Point pb = poly.points[seg];
- if (pa.x > pb.x)
- std::swap(pa.x, pb.x);
- if (pa.y > pb.y)
- std::swap(pa.y, pb.y);
- assert(px.x >= pa.x && px.x <= pb.x);
- assert(px.y >= pa.y && px.y <= pb.y);
+ if (pa(0) > pb(0))
+ std::swap(pa(0), pb(0));
+ if (pa(1) > pb(1))
+ std::swap(pa(1), pb(1));
+ assert(px(0) >= pa(0) && px(0) <= pb(0));
+ assert(px(1) >= pa(1) && px(1) <= pb(1));
}
#endif /* SLIC3R_DEBUG */
const Point *pPrev = &p1;
@@ -55,14 +55,14 @@ static inline coordf_t segment_length(const Polygon &poly, size_t seg1, const Po
coordf_t len = 0;
if (seg1 <= seg2) {
for (size_t i = seg1; i < seg2; ++ i, pPrev = pThis)
- len += pPrev->distance_to(*(pThis = &poly.points[i]));
+ len += (*pPrev - *(pThis = &poly.points[i])).cast<double>().norm();
} else {
for (size_t i = seg1; i < poly.points.size(); ++ i, pPrev = pThis)
- len += pPrev->distance_to(*(pThis = &poly.points[i]));
+ len += (*pPrev - *(pThis = &poly.points[i])).cast<double>().norm();
for (size_t i = 0; i < seg2; ++ i, pPrev = pThis)
- len += pPrev->distance_to(*(pThis = &poly.points[i]));
+ len += (*pPrev - *(pThis = &poly.points[i])).cast<double>().norm();
}
- len += pPrev->distance_to(p2);
+ len += (*pPrev - p2).cast<double>().norm();
return len;
}
@@ -791,15 +791,15 @@ bool FillRectilinear2::fill_surface_by_lines(const Surface *surface, const FillP
// define flow spacing according to requested density
if (params.full_infill() && !params.dont_adjust) {
- line_spacing = this->_adjust_solid_spacing(bounding_box.size().x, line_spacing);
- this->spacing = unscale(line_spacing);
+ line_spacing = this->_adjust_solid_spacing(bounding_box.size()(0), line_spacing);
+ this->spacing = unscale<double>(line_spacing);
} else {
// extend bounding box so that our pattern will be aligned with other layers
// Transform the reference point to the rotated coordinate system.
Point refpt = rotate_vector.second.rotated(- rotate_vector.first);
// _align_to_grid will not work correctly with positive pattern_shift.
coord_t pattern_shift_scaled = coord_t(scale_(pattern_shift)) % line_spacing;
- refpt.x -= (pattern_shift_scaled >= 0) ? pattern_shift_scaled : (line_spacing + pattern_shift_scaled);
+ refpt(0) -= (pattern_shift_scaled >= 0) ? pattern_shift_scaled : (line_spacing + pattern_shift_scaled);
bounding_box.merge(_align_to_grid(
bounding_box.min,
Point(line_spacing, line_spacing),
@@ -808,8 +808,8 @@ bool FillRectilinear2::fill_surface_by_lines(const Surface *surface, const FillP
// Intersect a set of euqally spaced vertical lines wiht expolygon.
// n_vlines = ceil(bbox_width / line_spacing)
- size_t n_vlines = (bounding_box.max.x - bounding_box.min.x + line_spacing - 1) / line_spacing;
- coord_t x0 = bounding_box.min.x;
+ size_t n_vlines = (bounding_box.max(0) - bounding_box.min(0) + line_spacing - 1) / line_spacing;
+ coord_t x0 = bounding_box.min(0);
if (params.full_infill())
x0 += (line_spacing + SCALED_EPSILON) / 2;
@@ -842,8 +842,8 @@ bool FillRectilinear2::fill_surface_by_lines(const Surface *surface, const FillP
const Point &p1 = contour[iPrev];
const Point &p2 = contour[iSegment];
// Which of the equally spaced vertical lines is intersected by this segment?
- coord_t l = p1.x;
- coord_t r = p2.x;
+ coord_t l = p1(0);
+ coord_t r = p2(0);
if (l > r)
std::swap(l, r);
// il, ir are the left / right indices of vertical lines intersecting a segment
@@ -869,33 +869,33 @@ bool FillRectilinear2::fill_surface_by_lines(const Surface *surface, const FillP
assert(l <= this_x);
assert(r >= this_x);
// Calculate the intersection position in y axis. x is known.
- if (p1.x == this_x) {
- if (p2.x == this_x) {
+ if (p1(0) == this_x) {
+ if (p2(0) == this_x) {
// Ignore strictly vertical segments.
continue;
}
- is.pos_p = p1.y;
+ is.pos_p = p1(1);
is.pos_q = 1;
- } else if (p2.x == this_x) {
- is.pos_p = p2.y;
+ } else if (p2(0) == this_x) {
+ is.pos_p = p2(1);
is.pos_q = 1;
} else {
// First calculate the intersection parameter 't' as a rational number with non negative denominator.
- if (p2.x > p1.x) {
- is.pos_p = this_x - p1.x;
- is.pos_q = p2.x - p1.x;
+ if (p2(0) > p1(0)) {
+ is.pos_p = this_x - p1(0);
+ is.pos_q = p2(0) - p1(0);
} else {
- is.pos_p = p1.x - this_x;
- is.pos_q = p1.x - p2.x;
+ is.pos_p = p1(0) - this_x;
+ is.pos_q = p1(0) - p2(0);
}
assert(is.pos_p >= 0 && is.pos_p <= is.pos_q);
// Make an intersection point from the 't'.
- is.pos_p *= int64_t(p2.y - p1.y);
- is.pos_p += p1.y * int64_t(is.pos_q);
+ is.pos_p *= int64_t(p2(1) - p1(1));
+ is.pos_p += p1(1) * int64_t(is.pos_q);
}
// +-1 to take rounding into account.
- assert(is.pos() + 1 >= std::min(p1.y, p2.y));
- assert(is.pos() <= std::max(p1.y, p2.y) + 1);
+ assert(is.pos() + 1 >= std::min(p1(1), p2(1)));
+ assert(is.pos() <= std::max(p1(1), p2(1)) + 1);
segs[i].intersections.push_back(is);
}
}
@@ -919,7 +919,7 @@ bool FillRectilinear2::fill_surface_by_lines(const Surface *surface, const FillP
const Points &contour = poly_with_offset.contour(iContour).points;
size_t iSegment = sil.intersections[i].iSegment;
size_t iPrev = ((iSegment == 0) ? contour.size() : iSegment) - 1;
- coord_t dir = contour[iSegment].x - contour[iPrev].x;
+ coord_t dir = contour[iSegment](0) - contour[iPrev](0);
bool low = dir > 0;
sil.intersections[i].type = poly_with_offset.is_contour_outer(iContour) ?
(low ? SegmentIntersection::OUTER_LOW : SegmentIntersection::OUTER_HIGH) :
@@ -1066,7 +1066,7 @@ bool FillRectilinear2::fill_surface_by_lines(const Surface *surface, const FillP
intrsctn.consumed_vertical_up :
seg.intersections[i-1].consumed_vertical_up;
if (! consumed) {
- coordf_t dist2 = sqr(coordf_t(pointLast.x - seg.pos)) + sqr(coordf_t(pointLast.y - intrsctn.pos()));
+ coordf_t dist2 = sqr(coordf_t(pointLast(0) - seg.pos)) + sqr(coordf_t(pointLast(1) - intrsctn.pos()));
if (dist2 < dist2min) {
dist2min = dist2;
i_vline = i_vline2;
@@ -1356,8 +1356,8 @@ bool FillRectilinear2::fill_surface_by_lines(const Surface *surface, const FillP
// Handle nearly zero length edges.
if (polyline_current->points.size() <= 1 ||
(polyline_current->points.size() == 2 &&
- std::abs(polyline_current->points.front().x - polyline_current->points.back().x) < SCALED_EPSILON &&
- std::abs(polyline_current->points.front().y - polyline_current->points.back().y) < SCALED_EPSILON))
+ std::abs(polyline_current->points.front()(0) - polyline_current->points.back()(0)) < SCALED_EPSILON &&
+ std::abs(polyline_current->points.front()(1) - polyline_current->points.back()(1)) < SCALED_EPSILON))
polylines_out.pop_back();
intrsctn = NULL;
i_intersection = -1;
@@ -1383,7 +1383,7 @@ bool FillRectilinear2::fill_surface_by_lines(const Surface *surface, const FillP
// paths must be rotated back
for (Polylines::iterator it = polylines_out.begin() + n_polylines_out_initial; it != polylines_out.end(); ++ it) {
// No need to translate, the absolute position is irrelevant.
- // it->translate(- rotate_vector.second.x, - rotate_vector.second.y);
+ // it->translate(- rotate_vector.second(0), - rotate_vector.second(1));
assert(! it->has_duplicate_points());
it->rotate(rotate_vector.first);
//FIXME rather simplify the paths to avoid very short edges?
diff --git a/xs/src/libslic3r/Fill/FillRectilinear3.cpp b/xs/src/libslic3r/Fill/FillRectilinear3.cpp
index cccea3030..8fc129eac 100644
--- a/xs/src/libslic3r/Fill/FillRectilinear3.cpp
+++ b/xs/src/libslic3r/Fill/FillRectilinear3.cpp
@@ -217,30 +217,30 @@ Point SegmentIntersection::pos() const
const Point &seg_start = poly.points[(this->iSegment == 0) ? poly.points.size() - 1 : this->iSegment - 1];
const Point &seg_end = poly.points[this->iSegment];
// Point, vector of the segment.
- const Pointf p1 = convert_to<Pointf>(seg_start);
- const Pointf v1 = convert_to<Pointf>(seg_end - seg_start);
+ const Vec2d p1(seg_start.cast<coordf_t>());
+ const Vec2d v1((seg_end - seg_start).cast<coordf_t>());
// Point, vector of this hatching line.
- const Pointf p2 = convert_to<Pointf>(line->pos);
- const Pointf v2 = convert_to<Pointf>(line->dir);
+ const Vec2d p2(line->pos.cast<coordf_t>());
+ const Vec2d v2(line->dir.cast<coordf_t>());
// Intersect the two rays.
- double denom = v1.x * v2.y - v2.x * v1.y;
+ double denom = v1(0) * v2(1) - v2(0) * v1(1);
Point out;
if (denom == 0.) {
// Lines are collinear. As the pos() method is not supposed to be called on collinear vectors,
// the source vectors are not quite collinear. Return the center of the contour segment.
out = seg_start + seg_end;
- out.x >>= 1;
- out.y >>= 1;
+ out(0) >>= 1;
+ out(1) >>= 1;
} else {
// Find the intersection point.
- double t = (v2.x * (p1.y - p2.y) - v2.y * (p1.x - p2.x)) / denom;
+ double t = (v2(0) * (p1(1) - p2(1)) - v2(1) * (p1(0) - p2(0))) / denom;
if (t < 0.)
out = seg_start;
else if (t > 1.)
out = seg_end;
else {
- out.x = coord_t(floor(p1.x + t * v1.x + 0.5));
- out.y = coord_t(floor(p1.y + t * v1.y + 0.5));
+ out(0) = coord_t(floor(p1(0) + t * v1(0) + 0.5));
+ out(1) = coord_t(floor(p1(1) + t * v1(1) + 0.5));
}
}
return out;
@@ -276,13 +276,13 @@ int SegmentIntersection::ordering_along_line(const SegmentIntersection &other) c
// other.iSegment succeeds this->iSegment
assert(seg_end_a == seg_start_b);
// Avoid calling the 128bit x 128bit multiplication below if this->line intersects the common point.
- if (cross(this->line->dir, seg_end_b - this->line->pos) == 0)
+ if (cross2(Vec2i64(this->line->dir.cast<int64_t>()), (seg_end_b - this->line->pos).cast<int64_t>()) == 0)
return 0;
} else if ((other.iSegment + 1) % poly_a.points.size() == this->iSegment) {
// this->iSegment succeeds other.iSegment
assert(seg_start_a == seg_end_b);
// Avoid calling the 128bit x 128bit multiplication below if this->line intersects the common point.
- if (cross(this->line->dir, seg_start_a - this->line->pos) == 0)
+ if (cross2(Vec2i64(this->line->dir.cast<int64_t>()), (seg_start_a - this->line->pos).cast<int64_t>()) == 0)
return 0;
} else {
// General case.
@@ -290,35 +290,35 @@ int SegmentIntersection::ordering_along_line(const SegmentIntersection &other) c
}
// First test, whether both points of one segment are completely in one half-plane of the other line.
- const Point vec_b = seg_end_b - seg_start_b;
- int side_start = signum(cross(vec_b, seg_start_a - seg_start_b));
- int side_end = signum(cross(vec_b, seg_end_a - seg_start_b));
+ const Vec2i64 vec_b = (seg_end_b - seg_start_b).cast<int64_t>();
+ int side_start = signum(cross2(vec_b, (seg_start_a - seg_start_b).cast<int64_t>()));
+ int side_end = signum(cross2(vec_b, (seg_end_a - seg_start_b).cast<int64_t>()));
int side = side_start * side_end;
if (side > 0)
// This segment is completely inside one half-plane of the other line, therefore the ordering is trivial.
- return signum(cross(vec_b, this->line->dir)) * side_start;
+ return signum(cross2(vec_b, this->line->dir.cast<int64_t>())) * side_start;
- const Point vec_a = seg_end_a - seg_start_a;
- int side_start2 = signum(cross(vec_a, seg_start_b - seg_start_a));
- int side_end2 = signum(cross(vec_a, seg_end_b - seg_start_a));
+ const Vec2i64 vec_a = (seg_end_a - seg_start_a).cast<int64_t>();
+ int side_start2 = signum(cross2(vec_a, (seg_start_b - seg_start_a).cast<int64_t>()));
+ int side_end2 = signum(cross2(vec_a, (seg_end_b - seg_start_a).cast<int64_t>()));
int side2 = side_start2 * side_end2;
//if (side == 0 && side2 == 0)
// The segments share one of their end points.
if (side2 > 0)
// This segment is completely inside one half-plane of the other line, therefore the ordering is trivial.
- return signum(cross(this->line->dir, vec_a)) * side_start2;
+ return signum(cross2(this->line->dir.cast<int64_t>(), vec_a)) * side_start2;
// The two segments intersect and they are not sucessive segments of the same contour.
// Ordering of the points depends on the position of the segment intersection (left / right from this->line),
// therefore a simple test over the input segment end points is not sufficient.
// Find the parameters of intersection of the two segmetns with this->line.
- int64_t denom1 = cross(this->line->dir, vec_a);
- int64_t denom2 = cross(this->line->dir, vec_b);
- Point vx_a = seg_start_a - this->line->pos;
- Point vx_b = seg_start_b - this->line->pos;
- int64_t t1_times_denom1 = int64_t(vx_a.x) * int64_t(vec_a.y) - int64_t(vx_a.y) * int64_t(vec_a.x);
- int64_t t2_times_denom2 = int64_t(vx_b.x) * int64_t(vec_b.y) - int64_t(vx_b.y) * int64_t(vec_b.x);
+ int64_t denom1 = cross2(this->line->dir.cast<int64_t>(), vec_a);
+ int64_t denom2 = cross2(this->line->dir.cast<int64_t>(), vec_b);
+ Vec2i64 vx_a = (seg_start_a - this->line->pos).cast<int64_t>();
+ Vec2i64 vx_b = (seg_start_b - this->line->pos).cast<int64_t>();
+ int64_t t1_times_denom1 = vx_a(0) * vec_a(1) - vx_a(1) * vec_a(0);
+ int64_t t2_times_denom2 = vx_b(0) * vec_b(1) - vx_b(1) * vec_b(0);
assert(denom1 != 0);
assert(denom2 != 0);
return Int128::compare_rationals_filtered(t1_times_denom1, denom1, t2_times_denom2, denom2);
@@ -330,7 +330,7 @@ bool SegmentIntersection::operator<(const SegmentIntersection &other) const
#ifdef _DEBUG
Point p1 = this->pos();
Point p2 = other.pos();
- int64_t d = dot(this->line->dir, p2 - p1);
+ int64_t d = this->line->dir.cast<int64_t>().dot((p2 - p1).cast<int64_t>());
#endif /* _DEBUG */
int ordering = this->ordering_along_line(other);
#ifdef _DEBUG
@@ -389,16 +389,16 @@ static bool prepare_infill_hatching_segments(
// Define the flow spacing according to requested density.
if (params.full_infill() && ! params.dont_adjust) {
// Full infill, adjust the line spacing to fit an integer number of lines.
- out.line_spacing = Fill::_adjust_solid_spacing(bounding_box.size().x, line_spacing);
+ out.line_spacing = Fill::_adjust_solid_spacing(bounding_box.size()(0), line_spacing);
// Report back the adjusted line spacing.
- fill_dir_params.spacing = float(unscale(line_spacing));
+ fill_dir_params.spacing = unscale<double>(line_spacing);
} else {
// Extend bounding box so that our pattern will be aligned with the other layers.
// Transform the reference point to the rotated coordinate system.
Point refpt = rotate_vector.second.rotated(- out.angle);
// _align_to_grid will not work correctly with positive pattern_shift.
coord_t pattern_shift_scaled = coord_t(scale_(fill_dir_params.pattern_shift)) % line_spacing;
- refpt.x -= (pattern_shift_scaled >= 0) ? pattern_shift_scaled : (line_spacing + pattern_shift_scaled);
+ refpt(0) -= (pattern_shift_scaled >= 0) ? pattern_shift_scaled : (line_spacing + pattern_shift_scaled);
bounding_box.merge(Fill::_align_to_grid(
bounding_box.min,
Point(line_spacing, line_spacing),
@@ -407,13 +407,13 @@ static bool prepare_infill_hatching_segments(
// Intersect a set of euqally spaced vertical lines wiht expolygon.
// n_vlines = ceil(bbox_width / line_spacing)
- size_t n_vlines = (bounding_box.max.x - bounding_box.min.x + line_spacing - 1) / line_spacing;
- coord_t x0 = bounding_box.min.x;
+ size_t n_vlines = (bounding_box.max(0) - bounding_box.min(0) + line_spacing - 1) / line_spacing;
+ coord_t x0 = bounding_box.min(0);
if (params.full_infill())
x0 += coord_t((line_spacing + SCALED_EPSILON) / 2);
out.line_spacing = line_spacing;
- out.start_point = Point(x0, bounding_box.min.y);
+ out.start_point = Point(x0, bounding_box.min(1));
out.start_point.rotate(out.angle);
#ifdef SLIC3R_DEBUG
@@ -436,10 +436,10 @@ static bool prepare_infill_hatching_segments(
for (size_t i = 0; i < n_vlines; ++ i) {
auto &seg = out.segs[i];
seg.idx = i;
- // seg.x = x0 + coord_t(i) * line_spacing;
+ // seg(0) = x0 + coord_t(i) * line_spacing;
coord_t x = x0 + coord_t(i) * line_spacing;
- seg.pos.x = coord_t(floor(cos_a * x - sin_a * bounding_box.min.y + 0.5));
- seg.pos.y = coord_t(floor(cos_a * bounding_box.min.y + sin_a * x + 0.5));
+ seg.pos(0) = coord_t(floor(cos_a * x - sin_a * bounding_box.min(1) + 0.5));
+ seg.pos(1) = coord_t(floor(cos_a * bounding_box.min(1) + sin_a * x + 0.5));
seg.dir = out.direction;
}
@@ -454,7 +454,7 @@ static bool prepare_infill_hatching_segments(
const Point *pr = &contour[iSegment];
// Orient the segment to the direction vector.
const Point v = *pr - *pl;
- int orientation = Int128::sign_determinant_2x2_filtered(v.x, v.y, out.direction.x, out.direction.y);
+ int orientation = Int128::sign_determinant_2x2_filtered(v(0), v(1), out.direction(0), out.direction(1));
if (orientation == 0)
// Ignore strictly vertical segments.
continue;
@@ -462,8 +462,8 @@ static bool prepare_infill_hatching_segments(
// Always orient the input segment consistently towards the hatching direction.
std::swap(pl, pr);
// Which of the equally spaced vertical lines is intersected by this segment?
- coord_t l = (coord_t)floor(cos_a * pl->x + sin_a * pl->y - SCALED_EPSILON);
- coord_t r = (coord_t)ceil (cos_a * pr->x + sin_a * pr->y + SCALED_EPSILON);
+ coord_t l = (coord_t)floor(cos_a * (*pl)(0) + sin_a * (*pl)(1) - SCALED_EPSILON);
+ coord_t r = (coord_t)ceil (cos_a * (*pr)(0) + sin_a * (*pr)(1) + SCALED_EPSILON);
assert(l < r - SCALED_EPSILON);
// il, ir are the left / right indices of vertical lines intersecting a segment
int il = std::max<int>(0, (l - x0 + line_spacing) / line_spacing);
@@ -479,9 +479,9 @@ static bool prepare_infill_hatching_segments(
// 2) all lines from il to ir intersect <pl, pr>.
assert(il >= 0 && ir < int(out.segs.size()));
for (int i = il; i <= ir; ++ i) {
- // assert(out.segs[i].x == i * line_spacing + x0);
- // assert(l <= out.segs[i].x);
- // assert(r >= out.segs[i].x);
+ // assert(out.segs[i](0) == i * line_spacing + x0);
+ // assert(l <= out.segs[i](0));
+ // assert(r >= out.segs[i](0));
SegmentIntersection is;
is.line = &out.segs[i];
is.expoly_with_offset = &poly_with_offset;
@@ -491,10 +491,10 @@ static bool prepare_infill_hatching_segments(
// +-1 to take rounding into account.
assert(int128::orient(out.segs[i].pos, out.segs[i].pos + out.direction, *pl) >= 0);
assert(int128::orient(out.segs[i].pos, out.segs[i].pos + out.direction, *pr) <= 0);
- assert(is.pos().x + 1 >= std::min(pl->x, pr->x));
- assert(is.pos().y + 1 >= std::min(pl->y, pr->y));
- assert(is.pos().x <= std::max(pl->x, pr->x) + 1);
- assert(is.pos().y <= std::max(pl->y, pr->y) + 1);
+ assert(is.pos()(0) + 1 >= std::min((*pl)(0), (*pr)(0)));
+ assert(is.pos()(1) + 1 >= std::min((*pl)(1), (*pr)(1)));
+ assert(is.pos()(0) <= std::max((*pl)(0), (*pr)(0)) + 1);
+ assert(is.pos()(1) <= std::max((*pl)(1), (*pr)(1)) + 1);
out.segs[i].intersections.push_back(is);
}
}
@@ -510,7 +510,7 @@ static bool prepare_infill_hatching_segments(
for (size_t i = 1; i < sil.intersections.size(); ++ i) {
Point p1 = sil.intersections[i - 1].pos();
Point p2 = sil.intersections[i].pos();
- int64_t d = dot(sil.dir, p2 - p1);
+ int64_t d = sil.dir.cast<int64_t>().dot((p2 - p1).cast<int64_t>());
assert(d >= - int64_t(SCALED_EPSILON));
}
#endif /* _DEBUG */
@@ -659,12 +659,12 @@ static inline coordf_t segment_length(const Polygon &poly, size_t seg1, const Po
Point px = (i == 0) ? p1 : p2;
Point pa = poly.points[((seg == 0) ? poly.points.size() : seg) - 1];
Point pb = poly.points[seg];
- if (pa.x > pb.x)
- std::swap(pa.x, pb.x);
- if (pa.y > pb.y)
- std::swap(pa.y, pb.y);
- assert(px.x >= pa.x && px.x <= pb.x);
- assert(px.y >= pa.y && px.y <= pb.y);
+ if (pa(0) > pb(0))
+ std::swap(pa(0), pb(0));
+ if (pa(1) > pb(1))
+ std::swap(pa(1), pb(1));
+ assert(px(0) >= pa(0) && px(0) <= pb(0));
+ assert(px(1) >= pa(1) && px(1) <= pb(1));
}
#endif /* SLIC3R_DEBUG */
const Point *pPrev = &p1;
@@ -672,14 +672,14 @@ static inline coordf_t segment_length(const Polygon &poly, size_t seg1, const Po
coordf_t len = 0;
if (seg1 <= seg2) {
for (size_t i = seg1; i < seg2; ++ i, pPrev = pThis)
- len += pPrev->distance_to(*(pThis = &poly.points[i]));
+ len += (*pPrev - *(pThis = &poly.points[i])).cast<double>().norm();
} else {
for (size_t i = seg1; i < poly.points.size(); ++ i, pPrev = pThis)
- len += pPrev->distance_to(*(pThis = &poly.points[i]));
+ len += (*pPrev - *(pThis = &poly.points[i])).cast<double>().norm();
for (size_t i = 0; i < seg2; ++ i, pPrev = pThis)
- len += pPrev->distance_to(*(pThis = &poly.points[i]));
+ len += (*pPrev - *(pThis = &poly.points[i])).cast<double>().norm();
}
- len += pPrev->distance_to(p2);
+ len += (*pPrev - p2).cast<double>().norm();
return len;
}
@@ -1191,7 +1191,7 @@ static bool fill_hatching_segments_legacy(
intrsctn.consumed_vertical_up :
seg.intersections[i-1].consumed_vertical_up;
if (! consumed) {
- coordf_t dist2 = pointLast.distance_to(intrsctn.pos());
+ coordf_t dist2 = (intrsctn.pos() - pointLast).cast<double>().norm();
if (dist2 < dist2min) {
dist2min = dist2;
i_vline = i_vline2;
@@ -1481,8 +1481,8 @@ static bool fill_hatching_segments_legacy(
// Handle nearly zero length edges.
if (polyline_current->points.size() <= 1 ||
(polyline_current->points.size() == 2 &&
- std::abs(polyline_current->points.front().x - polyline_current->points.back().x) < SCALED_EPSILON &&
- std::abs(polyline_current->points.front().y - polyline_current->points.back().y) < SCALED_EPSILON))
+ std::abs(polyline_current->points.front()(0) - polyline_current->points.back()(0)) < SCALED_EPSILON &&
+ std::abs(polyline_current->points.front()(1) - polyline_current->points.back()(1)) < SCALED_EPSILON))
polylines_out.pop_back();
intrsctn = NULL;
i_intersection = -1;
@@ -1510,7 +1510,7 @@ static bool fill_hatching_segments_legacy(
// paths must be rotated back
for (Polylines::iterator it = polylines_out.begin() + n_polylines_out_initial; it != polylines_out.end(); ++ it) {
// No need to translate, the absolute position is irrelevant.
- // it->translate(- rotate_vector.second.x, - rotate_vector.second.y);
+ // it->translate(- rotate_vector.second(0), - rotate_vector.second(1));
assert(! it->has_duplicate_points());
//it->rotate(rotate_vector.first);
//FIXME rather simplify the paths to avoid very short edges?
diff --git a/xs/src/libslic3r/Format/3mf.cpp b/xs/src/libslic3r/Format/3mf.cpp
index 5de1d26c5..d05460408 100644
--- a/xs/src/libslic3r/Format/3mf.cpp
+++ b/xs/src/libslic3r/Format/3mf.cpp
@@ -1352,8 +1352,8 @@ namespace Slic3r {
double angle_z = (rotation.axis() == Eigen::Vector3d::UnitZ()) ? rotation.angle() : -rotation.angle();
#endif
- instance.offset.x = offset_x;
- instance.offset.y = offset_y;
+ instance.offset(0) = offset_x;
+ instance.offset(1) = offset_y;
instance.scaling_factor = sx;
instance.rotation = angle_z;
}
@@ -1485,7 +1485,7 @@ namespace Slic3r {
stl_facet& facet = stl.facet_start[i];
for (unsigned int v = 0; v < 3; ++v)
{
- ::memcpy((void*)&facet.vertex[v].x, (const void*)&geometry.vertices[geometry.triangles[src_start_id + ii + v] * 3], 3 * sizeof(float));
+ ::memcpy(facet.vertex[v].data(), (const void*)&geometry.vertices[geometry.triangles[src_start_id + ii + v] * 3], 3 * sizeof(float));
}
}
@@ -1802,7 +1802,7 @@ namespace Slic3r {
}
Eigen::Affine3f transform;
- transform = Eigen::Translation3f((float)instance->offset.x, (float)instance->offset.y, 0.0f) * Eigen::AngleAxisf((float)instance->rotation, Eigen::Vector3f::UnitZ()) * Eigen::Scaling((float)instance->scaling_factor);
+ transform = Eigen::Translation3f((float)instance->offset(0), (float)instance->offset(1), 0.0f) * Eigen::AngleAxisf((float)instance->rotation, Eigen::Vector3f::UnitZ()) * Eigen::Scaling((float)instance->scaling_factor);
build_items.emplace_back(instance_id, transform.matrix());
stream << " </" << OBJECT_TAG << ">\n";
@@ -1845,9 +1845,9 @@ namespace Slic3r {
for (int i = 0; i < stl.stats.shared_vertices; ++i)
{
stream << " <" << VERTEX_TAG << " ";
- stream << "x=\"" << stl.v_shared[i].x << "\" ";
- stream << "y=\"" << stl.v_shared[i].y << "\" ";
- stream << "z=\"" << stl.v_shared[i].z << "\" />\n";
+ stream << "x=\"" << stl.v_shared[i](0) << "\" ";
+ stream << "y=\"" << stl.v_shared[i](1) << "\" ";
+ stream << "z=\"" << stl.v_shared[i](2) << "\" />\n";
}
}
diff --git a/xs/src/libslic3r/Format/AMF.cpp b/xs/src/libslic3r/Format/AMF.cpp
index 886bbae97..81617ad72 100644
--- a/xs/src/libslic3r/Format/AMF.cpp
+++ b/xs/src/libslic3r/Format/AMF.cpp
@@ -402,7 +402,7 @@ void AMFParserContext::endElement(const char * /* name */)
for (size_t i = 0; i < m_volume_facets.size();) {
stl_facet &facet = stl.facet_start[i/3];
for (unsigned int v = 0; v < 3; ++ v)
- memcpy(&facet.vertex[v].x, &m_object_vertices[m_volume_facets[i ++] * 3], 3 * sizeof(float));
+ memcpy(facet.vertex[v].data(), &m_object_vertices[m_volume_facets[i ++] * 3], 3 * sizeof(float));
}
stl_get_size(&stl);
m_volume->mesh.repair();
@@ -498,8 +498,8 @@ void AMFParserContext::endDocument()
for (const Instance &instance : object.second.instances)
if (instance.deltax_set && instance.deltay_set) {
ModelInstance *mi = m_model.objects[object.second.idx]->add_instance();
- mi->offset.x = instance.deltax;
- mi->offset.y = instance.deltay;
+ mi->offset(0) = instance.deltax;
+ mi->offset(1) = instance.deltay;
mi->rotation = instance.rz_set ? instance.rz : 0.f;
mi->scaling_factor = instance.scale_set ? instance.scale : 1.f;
}
@@ -761,9 +761,9 @@ bool store_amf(const char *path, Model *model, Print* print, bool export_print_c
for (size_t i = 0; i < stl.stats.shared_vertices; ++ i) {
stream << " <vertex>\n";
stream << " <coordinates>\n";
- stream << " <x>" << stl.v_shared[i].x << "</x>\n";
- stream << " <y>" << stl.v_shared[i].y << "</y>\n";
- stream << " <z>" << stl.v_shared[i].z << "</z>\n";
+ stream << " <x>" << stl.v_shared[i](0) << "</x>\n";
+ stream << " <y>" << stl.v_shared[i](1) << "</y>\n";
+ stream << " <z>" << stl.v_shared[i](2) << "</z>\n";
stream << " </coordinates>\n";
stream << " </vertex>\n";
}
@@ -804,8 +804,8 @@ bool store_amf(const char *path, Model *model, Print* print, bool export_print_c
" <scale>%lf</scale>\n"
" </instance>\n",
object_id,
- instance->offset.x,
- instance->offset.y,
+ instance->offset(0),
+ instance->offset(1),
instance->rotation,
instance->scaling_factor);
//FIXME missing instance->scaling_factor
diff --git a/xs/src/libslic3r/Format/OBJ.cpp b/xs/src/libslic3r/Format/OBJ.cpp
index ea6b5604c..ee5756083 100644
--- a/xs/src/libslic3r/Format/OBJ.cpp
+++ b/xs/src/libslic3r/Format/OBJ.cpp
@@ -57,14 +57,14 @@ bool load_obj(const char *path, Model *model, const char *object_name_in)
continue;
stl_facet &facet = stl.facet_start[i_face ++];
size_t num_normals = 0;
- stl_normal normal = { 0.f };
+ stl_normal normal(stl_normal::Zero());
for (unsigned int v = 0; v < 3; ++ v) {
const ObjParser::ObjVertex &vertex = data.vertices[i++];
- memcpy(&facet.vertex[v].x, &data.coordinates[vertex.coordIdx*4], 3 * sizeof(float));
+ memcpy(facet.vertex[v].data(), &data.coordinates[vertex.coordIdx*4], 3 * sizeof(float));
if (vertex.normalIdx != -1) {
- normal.x += data.normals[vertex.normalIdx*3];
- normal.y += data.normals[vertex.normalIdx*3+1];
- normal.z += data.normals[vertex.normalIdx*3+2];
+ normal(0) += data.normals[vertex.normalIdx*3];
+ normal(1) += data.normals[vertex.normalIdx*3+1];
+ normal(2) += data.normals[vertex.normalIdx*3+2];
++ num_normals;
}
}
@@ -74,33 +74,27 @@ bool load_obj(const char *path, Model *model, const char *object_name_in)
facet2.vertex[0] = facet.vertex[0];
facet2.vertex[1] = facet.vertex[2];
const ObjParser::ObjVertex &vertex = data.vertices[i++];
- memcpy(&facet2.vertex[2].x, &data.coordinates[vertex.coordIdx * 4], 3 * sizeof(float));
+ memcpy(facet2.vertex[2].data(), &data.coordinates[vertex.coordIdx * 4], 3 * sizeof(float));
if (vertex.normalIdx != -1) {
- normal.x += data.normals[vertex.normalIdx*3];
- normal.y += data.normals[vertex.normalIdx*3+1];
- normal.z += data.normals[vertex.normalIdx*3+2];
+ normal(0) += data.normals[vertex.normalIdx*3];
+ normal(1) += data.normals[vertex.normalIdx*3+1];
+ normal(2) += data.normals[vertex.normalIdx*3+2];
++ num_normals;
}
if (num_normals == 4) {
// Normalize an average normal of a quad.
- float len = sqrt(facet.normal.x*facet.normal.x + facet.normal.y*facet.normal.y + facet.normal.z*facet.normal.z);
+ float len = facet.normal.norm();
if (len > EPSILON) {
- normal.x /= len;
- normal.y /= len;
- normal.z /= len;
+ normal /= len;
facet.normal = normal;
facet2.normal = normal;
}
}
} else if (num_normals == 3) {
// Normalize an average normal of a triangle.
- float len = sqrt(facet.normal.x*facet.normal.x + facet.normal.y*facet.normal.y + facet.normal.z*facet.normal.z);
- if (len > EPSILON) {
- normal.x /= len;
- normal.y /= len;
- normal.z /= len;
- facet.normal = normal;
- }
+ float len = facet.normal.norm();
+ if (len > EPSILON)
+ facet.normal = normal / len;
}
}
stl_get_size(&stl);
diff --git a/xs/src/libslic3r/Format/PRUS.cpp b/xs/src/libslic3r/Format/PRUS.cpp
index 1809eaead..3cf3fc075 100644
--- a/xs/src/libslic3r/Format/PRUS.cpp
+++ b/xs/src/libslic3r/Format/PRUS.cpp
@@ -166,7 +166,7 @@ bool load_prus(const char *path, Model *model)
float trafo[3][4] = { 0 };
double instance_rotation = 0.;
double instance_scaling_factor = 1.f;
- Pointf instance_offset(0., 0.);
+ Vec2d instance_offset(0., 0.);
bool trafo_set = false;
unsigned int group_id = (unsigned int)-1;
unsigned int extruder_id = (unsigned int)-1;
@@ -207,8 +207,8 @@ bool load_prus(const char *path, Model *model)
for (size_t c = 0; c < 3; ++ c)
trafo[r][c] += mat_trafo(r, c);
}
- instance_offset.x = position[0] - zero[0];
- instance_offset.y = position[1] - zero[1];
+ instance_offset(0) = position[0] - zero[0];
+ instance_offset(1) = position[1] - zero[1];
trafo[2][3] = position[2] / instance_scaling_factor;
trafo_set = true;
}
@@ -260,8 +260,8 @@ bool load_prus(const char *path, Model *model)
mesh.repair();
// Transform the model.
stl_transform(&stl, &trafo[0][0]);
- if (std::abs(stl.stats.min.z) < EPSILON)
- stl.stats.min.z = 0.;
+ if (std::abs(stl.stats.min(2)) < EPSILON)
+ stl.stats.min(2) = 0.;
// Add a mesh to a model.
if (mesh.facets_count() > 0)
mesh_valid = true;
@@ -309,11 +309,11 @@ bool load_prus(const char *path, Model *model)
assert(res_normal == 3);
int res_outer_loop = line_reader.next_line_scanf(" outer loop");
assert(res_outer_loop == 0);
- int res_vertex1 = line_reader.next_line_scanf(" vertex %f %f %f", &facet.vertex[0].x, &facet.vertex[0].y, &facet.vertex[0].z);
+ int res_vertex1 = line_reader.next_line_scanf(" vertex %f %f %f", &facet.vertex[0](0), &facet.vertex[0](1), &facet.vertex[0](2));
assert(res_vertex1 == 3);
- int res_vertex2 = line_reader.next_line_scanf(" vertex %f %f %f", &facet.vertex[1].x, &facet.vertex[1].y, &facet.vertex[1].z);
+ int res_vertex2 = line_reader.next_line_scanf(" vertex %f %f %f", &facet.vertex[1](0), &facet.vertex[1](1), &facet.vertex[1](2));
assert(res_vertex2 == 3);
- int res_vertex3 = line_reader.next_line_scanf(" vertex %f %f %f", &facet.vertex[2].x, &facet.vertex[2].y, &facet.vertex[2].z);
+ int res_vertex3 = line_reader.next_line_scanf(" vertex %f %f %f", &facet.vertex[2](0), &facet.vertex[2](1), &facet.vertex[2](2));
assert(res_vertex3 == 3);
int res_endloop = line_reader.next_line_scanf(" endloop");
assert(res_endloop == 0);
@@ -324,9 +324,9 @@ bool load_prus(const char *path, Model *model)
break;
}
// The facet normal has been parsed as a single string as to workaround for not a numbers in the normal definition.
- if (sscanf(normal_buf[0], "%f", &facet.normal.x) != 1 ||
- sscanf(normal_buf[1], "%f", &facet.normal.y) != 1 ||
- sscanf(normal_buf[2], "%f", &facet.normal.z) != 1) {
+ if (sscanf(normal_buf[0], "%f", &facet.normal(0)) != 1 ||
+ sscanf(normal_buf[1], "%f", &facet.normal(1)) != 1 ||
+ sscanf(normal_buf[2], "%f", &facet.normal(2)) != 1) {
// Normal was mangled. Maybe denormals or "not a number" were stored?
// Just reset the normal and silently ignore it.
memset(&facet.normal, 0, sizeof(facet.normal));
diff --git a/xs/src/libslic3r/GCode.cpp b/xs/src/libslic3r/GCode.cpp
index b34ba5441..fa18ddf3f 100644
--- a/xs/src/libslic3r/GCode.cpp
+++ b/xs/src/libslic3r/GCode.cpp
@@ -49,11 +49,11 @@ Polyline AvoidCrossingPerimeters::travel_to(const GCode &gcodegen, const Point &
// If use_external, then perform the path planning in the world coordinate system (correcting for the gcodegen offset).
// Otherwise perform the path planning in the coordinate system of the active object.
bool use_external = this->use_external_mp || this->use_external_mp_once;
- Point scaled_origin = use_external ? Point::new_scale(gcodegen.origin().x, gcodegen.origin().y) : Point(0, 0);
+ Point scaled_origin = use_external ? Point::new_scale(gcodegen.origin()(0), gcodegen.origin()(1)) : Point(0, 0);
Polyline result = (use_external ? m_external_mp.get() : m_layer_mp.get())->
shortest_path(gcodegen.last_pos() + scaled_origin, point + scaled_origin);
if (use_external)
- result.translate(scaled_origin.negative());
+ result.translate(- scaled_origin);
return result;
}
@@ -64,8 +64,8 @@ std::string OozePrevention::pre_toolchange(GCode &gcodegen)
// move to the nearest standby point
if (!this->standby_points.empty()) {
// get current position in print coordinates
- Pointf3 writer_pos = gcodegen.writer().get_position();
- Point pos = Point::new_scale(writer_pos.x, writer_pos.y);
+ Vec3d writer_pos = gcodegen.writer().get_position();
+ Point pos = Point::new_scale(writer_pos(0), writer_pos(1));
// find standby point
Point standby_point;
@@ -74,7 +74,7 @@ std::string OozePrevention::pre_toolchange(GCode &gcodegen)
/* We don't call gcodegen.travel_to() because we don't need retraction (it was already
triggered by the caller) nor avoid_crossing_perimeters and also because the coordinates
of the destination point must not be transformed by origin nor current extruder offset. */
- gcode += gcodegen.writer().travel_to_xy(Pointf::new_unscale(standby_point),
+ gcode += gcodegen.writer().travel_to_xy(unscale(standby_point),
"move to standby position");
}
@@ -160,7 +160,7 @@ Wipe::wipe(GCode &gcodegen, bool toolchange)
static inline Point wipe_tower_point_to_object_point(GCode &gcodegen, const WipeTower::xy &wipe_tower_pt)
{
- return Point(scale_(wipe_tower_pt.x - gcodegen.origin().x), scale_(wipe_tower_pt.y - gcodegen.origin().y));
+ return Point(scale_(wipe_tower_pt.x - gcodegen.origin()(0)), scale_(wipe_tower_pt.y - gcodegen.origin()(1)));
}
std::string WipeTowerIntegration::append_tcr(GCode &gcodegen, const WipeTower::ToolChangeResult &tcr, int new_extruder_id) const
@@ -207,7 +207,7 @@ std::string WipeTowerIntegration::append_tcr(GCode &gcodegen, const WipeTower::T
check_add_eol(gcode);
}
// A phony move to the end position at the wipe tower.
- gcodegen.writer().travel_to_xy(Pointf(end_pos.x, end_pos.y));
+ gcodegen.writer().travel_to_xy(Vec2d(end_pos.x, end_pos.y));
gcodegen.set_last_pos(wipe_tower_point_to_object_point(gcodegen, end_pos));
// Prepare a future wipe.
@@ -293,7 +293,7 @@ std::string WipeTowerIntegration::prime(GCode &gcodegen)
gcodegen.writer().toolchange(current_extruder_id);
gcodegen.placeholder_parser().set("current_extruder", current_extruder_id);
// A phony move to the end position at the wipe tower.
- gcodegen.writer().travel_to_xy(Pointf(m_priming.end_pos.x, m_priming.end_pos.y));
+ gcodegen.writer().travel_to_xy(Vec2d(m_priming.end_pos.x, m_priming.end_pos.y));
gcodegen.set_last_pos(wipe_tower_point_to_object_point(gcodegen, m_priming.end_pos));
// Prepare a future wipe.
gcodegen.m_wipe.path.points.clear();
@@ -325,7 +325,7 @@ std::string WipeTowerIntegration::tool_change(GCode &gcodegen, int extruder_id,
std::string WipeTowerIntegration::finalize(GCode &gcodegen)
{
std::string gcode;
- if (std::abs(gcodegen.writer().get_position().z - m_final_purge.print_z) > EPSILON)
+ if (std::abs(gcodegen.writer().get_position()(2) - m_final_purge.print_z) > EPSILON)
gcode += gcodegen.change_layer(m_final_purge.print_z);
gcode += append_tcr(gcodegen, m_final_purge, -1);
return gcode;
@@ -767,7 +767,7 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
for (const ExPolygon &expoly : layer->slices.expolygons)
for (const Point &copy : object->_shifted_copies) {
islands.emplace_back(expoly.contour);
- islands.back().translate(copy);
+ islands.back().translate(- copy);
}
//FIXME Mege the islands in parallel.
m_avoid_crossing_perimeters.init_external_mp(union_ex(islands));
@@ -783,9 +783,9 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
Polygon outer_skirt = Slic3r::Geometry::convex_hull(skirt_points);
Polygons skirts;
for (unsigned int extruder_id : print.extruders()) {
- const Pointf &extruder_offset = print.config.extruder_offset.get_at(extruder_id);
+ const Vec2d &extruder_offset = print.config.extruder_offset.get_at(extruder_id);
Polygon s(outer_skirt);
- s.translate(-scale_(extruder_offset.x), -scale_(extruder_offset.y));
+ s.translate(Point::new_scale(- extruder_offset(0), - extruder_offset(1)));
skirts.emplace_back(std::move(s));
}
m_ooze_prevention.enable = true;
@@ -814,7 +814,7 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
// Print objects from the smallest to the tallest to avoid collisions
// when moving onto next object starting point.
std::vector<PrintObject*> objects(printable_objects);
- std::sort(objects.begin(), objects.end(), [](const PrintObject* po1, const PrintObject* po2) { return po1->size.z < po2->size.z; });
+ std::sort(objects.begin(), objects.end(), [](const PrintObject* po1, const PrintObject* po2) { return po1->size(2) < po2->size(2); });
size_t finished_objects = 0;
for (size_t object_id = initial_print_object_id; object_id < objects.size(); ++ object_id) {
const PrintObject &object = *objects[object_id];
@@ -831,7 +831,7 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
final_extruder_id = tool_ordering.last_extruder();
assert(final_extruder_id != (unsigned int)-1);
}
- this->set_origin(unscale(copy.x), unscale(copy.y));
+ this->set_origin(unscale(copy));
if (finished_objects > 0) {
// Move to the origin position for the copy we're going to print.
// This happens before Z goes down to layer 0 again, so that no collision happens hopefully.
@@ -940,7 +940,7 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
{
DynamicConfig config;
config.set_key_value("layer_num", new ConfigOptionInt(m_layer_index));
- config.set_key_value("layer_z", new ConfigOptionFloat(m_writer.get_position().z - m_config.z_offset.value));
+ config.set_key_value("layer_z", new ConfigOptionFloat(m_writer.get_position()(2) - m_config.z_offset.value));
if (print.config.single_extruder_multi_material) {
// Process the end_filament_gcode for the active filament only.
_writeln(file, this->placeholder_parser_process("end_filament_gcode", print.config.end_filament_gcode.get_at(m_writer.extruder()->id()), m_writer.extruder()->id(), &config));
@@ -1396,8 +1396,8 @@ void GCode::process_layer(
layer_surface_bboxes.push_back(get_extents(expoly.contour));
auto point_inside_surface = [&layer, &layer_surface_bboxes](const size_t i, const Point &point) {
const BoundingBox &bbox = layer_surface_bboxes[i];
- return point.x >= bbox.min.x && point.x < bbox.max.x &&
- point.y >= bbox.min.y && point.y < bbox.max.y &&
+ return point(0) >= bbox.min(0) && point(0) < bbox.max(0) &&
+ point(1) >= bbox.min(1) && point(1) < bbox.max(1) &&
layer.slices.expolygons[i].contour.contains(point);
};
@@ -1547,7 +1547,7 @@ void GCode::process_layer(
if (m_last_obj_copy != this_object_copy)
m_avoid_crossing_perimeters.use_external_mp_once = true;
m_last_obj_copy = this_object_copy;
- this->set_origin(unscale(copy.x), unscale(copy.y));
+ this->set_origin(unscale(copy));
if (object_by_extruder.support != nullptr && !print_wipe_extrusions) {
m_layer = layers[layer_id].support_layer;
gcode += this->extrude_support(
@@ -1632,14 +1632,14 @@ void GCode::set_extruders(const std::vector<unsigned int> &extruder_ids)
}
}
-void GCode::set_origin(const Pointf &pointf)
+void GCode::set_origin(const Vec2d &pointf)
{
// if origin increases (goes towards right), last_pos decreases because it goes towards left
const Point translate(
- scale_(m_origin.x - pointf.x),
- scale_(m_origin.y - pointf.y)
+ scale_(m_origin(0) - pointf(0)),
+ scale_(m_origin(1) - pointf(1))
);
- m_last_pos.translate(translate);
+ m_last_pos += translate;
m_wipe.path.translate(translate);
m_origin = pointf;
}
@@ -1770,13 +1770,13 @@ static Points::iterator project_point_to_polygon_and_insert(Polygon &polygon, co
j = 0;
const Point &p1 = polygon.points[i];
const Point &p2 = polygon.points[j];
- const Slic3r::Point v_seg = p1.vector_to(p2);
- const Slic3r::Point v_pt = p1.vector_to(pt);
- const int64_t l2_seg = int64_t(v_seg.x) * int64_t(v_seg.x) + int64_t(v_seg.y) * int64_t(v_seg.y);
- int64_t t_pt = int64_t(v_seg.x) * int64_t(v_pt.x) + int64_t(v_seg.y) * int64_t(v_pt.y);
+ const Slic3r::Point v_seg = p2 - p1;
+ const Slic3r::Point v_pt = pt - p1;
+ const int64_t l2_seg = int64_t(v_seg(0)) * int64_t(v_seg(0)) + int64_t(v_seg(1)) * int64_t(v_seg(1));
+ int64_t t_pt = int64_t(v_seg(0)) * int64_t(v_pt(0)) + int64_t(v_seg(1)) * int64_t(v_pt(1));
if (t_pt < 0) {
// Closest to p1.
- double dabs = sqrt(int64_t(v_pt.x) * int64_t(v_pt.x) + int64_t(v_pt.y) * int64_t(v_pt.y));
+ double dabs = sqrt(int64_t(v_pt(0)) * int64_t(v_pt(0)) + int64_t(v_pt(1)) * int64_t(v_pt(1)));
if (dabs < d_min) {
d_min = dabs;
i_min = i;
@@ -1789,7 +1789,7 @@ static Points::iterator project_point_to_polygon_and_insert(Polygon &polygon, co
} else {
// Closest to the segment.
assert(t_pt >= 0 && t_pt <= l2_seg);
- int64_t d_seg = int64_t(v_seg.y) * int64_t(v_pt.x) - int64_t(v_seg.x) * int64_t(v_pt.y);
+ int64_t d_seg = int64_t(v_seg(1)) * int64_t(v_pt(0)) - int64_t(v_seg(0)) * int64_t(v_pt(1));
double d = double(d_seg) / sqrt(double(l2_seg));
double dabs = std::abs(d);
if (dabs < d_min) {
@@ -1798,15 +1798,15 @@ static Points::iterator project_point_to_polygon_and_insert(Polygon &polygon, co
// Evaluate the foot point.
pt_min = p1;
double linv = double(d_seg) / double(l2_seg);
- pt_min.x = pt.x - coord_t(floor(double(v_seg.y) * linv + 0.5));
- pt_min.y = pt.y + coord_t(floor(double(v_seg.x) * linv + 0.5));
+ pt_min(0) = pt(0) - coord_t(floor(double(v_seg(1)) * linv + 0.5));
+ pt_min(1) = pt(1) + coord_t(floor(double(v_seg(0)) * linv + 0.5));
assert(Line(p1, p2).distance_to(pt_min) < scale_(1e-5));
}
}
}
assert(i_min != size_t(-1));
- if (pt_min.distance_to(polygon.points[i_min]) > eps) {
+ if ((pt_min - polygon.points[i_min]).cast<double>().norm() > eps) {
// Insert a new point on the segment i_min, i_min+1.
return polygon.points.insert(polygon.points.begin() + (i_min + 1), pt_min);
}
@@ -1818,8 +1818,8 @@ std::vector<float> polygon_parameter_by_length(const Polygon &polygon)
// Parametrize the polygon by its length.
std::vector<float> lengths(polygon.points.size()+1, 0.);
for (size_t i = 1; i < polygon.points.size(); ++ i)
- lengths[i] = lengths[i-1] + float(polygon.points[i].distance_to(polygon.points[i-1]));
- lengths.back() = lengths[lengths.size()-2] + float(polygon.points.front().distance_to(polygon.points.back()));
+ lengths[i] = lengths[i-1] + (polygon.points[i] - polygon.points[i-1]).cast<float>().norm();
+ lengths.back() = lengths[lengths.size()-2] + (polygon.points.front() - polygon.points.back()).cast<float>().norm();
return lengths;
}
@@ -1867,10 +1867,10 @@ std::vector<float> polygon_angles_at_vertices(const Polygon &polygon, const std:
const Point &p0 = polygon.points[idx_prev];
const Point &p1 = polygon.points[idx_curr];
const Point &p2 = polygon.points[idx_next];
- const Point v1 = p0.vector_to(p1);
- const Point v2 = p1.vector_to(p2);
- int64_t dot = int64_t(v1.x)*int64_t(v2.x) + int64_t(v1.y)*int64_t(v2.y);
- int64_t cross = int64_t(v1.x)*int64_t(v2.y) - int64_t(v1.y)*int64_t(v2.x);
+ const Point v1 = p1 - p0;
+ const Point v2 = p2 - p1;
+ int64_t dot = int64_t(v1(0))*int64_t(v2(0)) + int64_t(v1(1))*int64_t(v2(1));
+ int64_t cross = int64_t(v1(0))*int64_t(v2(1)) - int64_t(v1(1))*int64_t(v2(0));
float angle = float(atan2(double(cross), double(dot)));
angles[idx_curr] = angle;
}
@@ -1894,10 +1894,10 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou
{
static int iRun = 0;
BoundingBox bbox = (*lower_layer_edge_grid)->bbox();
- bbox.min.x -= scale_(5.f);
- bbox.min.y -= scale_(5.f);
- bbox.max.x += scale_(5.f);
- bbox.max.y += scale_(5.f);
+ bbox.min(0) -= scale_(5.f);
+ bbox.min(1) -= scale_(5.f);
+ bbox.max(0) += scale_(5.f);
+ bbox.max(1) += scale_(5.f);
EdgeGrid::save_png(*(*lower_layer_edge_grid), bbox, scale_(0.1f), debug_out_path("GCode_extrude_loop_edge_grid-%d.png", iRun++));
}
#endif
@@ -1933,7 +1933,7 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou
break;
case spRear:
last_pos = m_layer->object()->bounding_box().center();
- last_pos.y += coord_t(3. * m_layer->object()->bounding_box().radius());
+ last_pos(1) += coord_t(3. * m_layer->object()->bounding_box().radius());
last_pos_weight = 5.f;
break;
}
@@ -2066,7 +2066,7 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou
//FIXME Better parametrize the loop by its length.
Polygon polygon = loop.polygon();
Point centroid = polygon.centroid();
- last_pos = Point(polygon.bounding_box().max.x, centroid.y);
+ last_pos = Point(polygon.bounding_box().max(0), centroid(1));
last_pos.rotate(fmod((float)rand()/16.0, 2.0*PI), centroid);
}
// Find the closest point, avoid overhangs.
@@ -2123,19 +2123,17 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou
// create the destination point along the first segment and rotate it
// we make sure we don't exceed the segment length because we don't know
// the rotation of the second segment so we might cross the object boundary
- Line first_segment(
- paths.front().polyline.points[0],
- paths.front().polyline.points[1]
- );
- double distance = std::min<double>(
- scale_(EXTRUDER_CONFIG(nozzle_diameter)),
- first_segment.length()
- );
- Point point = first_segment.point_at(distance);
- point.rotate(angle, first_segment.a);
-
+ Vec2d p1 = paths.front().polyline.points.front().cast<double>();
+ Vec2d p2 = paths.front().polyline.points[1].cast<double>();
+ Vec2d v = p2 - p1;
+ double nd = scale_(EXTRUDER_CONFIG(nozzle_diameter));
+ double l2 = v.squaredNorm();
+ // Shift by no more than a nozzle diameter.
+ //FIXME Hiding the seams will not work nicely for very densely discretized contours!
+ Point pt = ((nd * nd >= l2) ? p2 : (p1 + v * (nd / sqrt(l2)))).cast<coord_t>();
+ pt.rotate(angle, paths.front().polyline.points.front());
// generate the travel move
- gcode += m_writer.travel_to_xy(this->point_to_gcode(point), "move inwards before travel");
+ gcode += m_writer.travel_to_xy(this->point_to_gcode(pt), "move inwards before travel");
}
return gcode;
@@ -2305,7 +2303,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
std::string gcode;
// go to first point of extrusion path
- if (!m_last_pos_defined || !m_last_pos.coincides_with(path.first_point())) {
+ if (!m_last_pos_defined || m_last_pos != path.first_point()) {
gcode += this->travel_to(
path.first_point(),
path.role(),
@@ -2620,24 +2618,21 @@ std::string GCode::set_extruder(unsigned int extruder_id)
}
// convert a model-space scaled point into G-code coordinates
-Pointf GCode::point_to_gcode(const Point &point) const
+Vec2d GCode::point_to_gcode(const Point &point) const
{
- Pointf extruder_offset = EXTRUDER_CONFIG(extruder_offset);
- return Pointf(
- unscale(point.x) + m_origin.x - extruder_offset.x,
- unscale(point.y) + m_origin.y - extruder_offset.y);
+ Vec2d extruder_offset = EXTRUDER_CONFIG(extruder_offset);
+ return unscale(point) + m_origin - extruder_offset;
}
// convert a model-space scaled point into G-code coordinates
-Point GCode::gcode_to_point(const Pointf &point) const
+Point GCode::gcode_to_point(const Vec2d &point) const
{
- Pointf extruder_offset = EXTRUDER_CONFIG(extruder_offset);
+ Vec2d extruder_offset = EXTRUDER_CONFIG(extruder_offset);
return Point(
- scale_(point.x - m_origin.x + extruder_offset.x),
- scale_(point.y - m_origin.y + extruder_offset.y));
+ scale_(point(0) - m_origin(0) + extruder_offset(0)),
+ scale_(point(1) - m_origin(1) + extruder_offset(1)));
}
-
// Goes through by_region std::vector and returns reference to a subvector of entities, that are to be printed
// during infill/perimeter wiping, or normally (depends on wiping_entities parameter)
// Returns a reference to member to avoid copying.
diff --git a/xs/src/libslic3r/GCode.hpp b/xs/src/libslic3r/GCode.hpp
index 4953c39fe..dc8a32135 100644
--- a/xs/src/libslic3r/GCode.hpp
+++ b/xs/src/libslic3r/GCode.hpp
@@ -125,6 +125,7 @@ private:
class GCode {
public:
GCode() :
+ m_origin(Vec2d::Zero()),
m_enable_loop_clipping(true),
m_enable_cooling_markers(false),
m_enable_extrusion_role_markers(false),
@@ -152,12 +153,12 @@ public:
void do_export(Print *print, const char *path, GCodePreviewData *preview_data = nullptr);
// Exported for the helper classes (OozePrevention, Wipe) and for the Perl binding for unit tests.
- const Pointf& origin() const { return m_origin; }
- void set_origin(const Pointf &pointf);
- void set_origin(const coordf_t x, const coordf_t y) { this->set_origin(Pointf(x, y)); }
+ const Vec2d& origin() const { return m_origin; }
+ void set_origin(const Vec2d &pointf);
+ void set_origin(const coordf_t x, const coordf_t y) { this->set_origin(Vec2d(x, y)); }
const Point& last_pos() const { return m_last_pos; }
- Pointf point_to_gcode(const Point &point) const;
- Point gcode_to_point(const Pointf &point) const;
+ Vec2d point_to_gcode(const Point &point) const;
+ Point gcode_to_point(const Vec2d &point) const;
const FullPrintConfig &config() const { return m_config; }
const Layer* layer() const { return m_layer; }
GCodeWriter& writer() { return m_writer; }
@@ -258,7 +259,7 @@ protected:
/* Origin of print coordinates expressed in unscaled G-code coordinates.
This affects the input arguments supplied to the extrude*() and travel_to()
methods. */
- Pointf m_origin;
+ Vec2d m_origin;
FullPrintConfig m_config;
GCodeWriter m_writer;
PlaceholderParser m_placeholder_parser;
diff --git a/xs/src/libslic3r/GCode/Analyzer.cpp b/xs/src/libslic3r/GCode/Analyzer.cpp
index b7ecee5a4..51d5b1a06 100644
--- a/xs/src/libslic3r/GCode/Analyzer.cpp
+++ b/xs/src/libslic3r/GCode/Analyzer.cpp
@@ -14,7 +14,7 @@ static const float MMMIN_TO_MMSEC = 1.0f / 60.0f;
static const float INCHES_TO_MM = 25.4f;
static const float DEFAULT_FEEDRATE = 0.0f;
static const unsigned int DEFAULT_EXTRUDER_ID = 0;
-static const Slic3r::Pointf3 DEFAULT_START_POSITION = Slic3r::Pointf3(0.0f, 0.0f, 0.0f);
+static const Slic3r::Vec3d DEFAULT_START_POSITION = Slic3r::Vec3d(0.0f, 0.0f, 0.0f);
static const float DEFAULT_START_EXTRUSION = 0.0f;
namespace Slic3r {
@@ -71,7 +71,7 @@ bool GCodeAnalyzer::Metadata::operator != (const GCodeAnalyzer::Metadata& other)
return false;
}
-GCodeAnalyzer::GCodeMove::GCodeMove(GCodeMove::EType type, ExtrusionRole extrusion_role, unsigned int extruder_id, double mm3_per_mm, float width, float height, float feedrate, const Pointf3& start_position, const Pointf3& end_position, float delta_extruder)
+GCodeAnalyzer::GCodeMove::GCodeMove(GCodeMove::EType type, ExtrusionRole extrusion_role, unsigned int extruder_id, double mm3_per_mm, float width, float height, float feedrate, const Vec3d& start_position, const Vec3d& end_position, float delta_extruder)
: type(type)
, data(extrusion_role, extruder_id, mm3_per_mm, width, height, feedrate)
, start_position(start_position)
@@ -80,7 +80,7 @@ GCodeAnalyzer::GCodeMove::GCodeMove(GCodeMove::EType type, ExtrusionRole extrusi
{
}
-GCodeAnalyzer::GCodeMove::GCodeMove(GCodeMove::EType type, const GCodeAnalyzer::Metadata& data, const Pointf3& start_position, const Pointf3& end_position, float delta_extruder)
+GCodeAnalyzer::GCodeMove::GCodeMove(GCodeMove::EType type, const GCodeAnalyzer::Metadata& data, const Vec3d& start_position, const Vec3d& end_position, float delta_extruder)
: type(type)
, data(data)
, start_position(start_position)
@@ -587,12 +587,12 @@ void GCodeAnalyzer::_reset_axes_position()
::memset((void*)m_state.position, 0, Num_Axis * sizeof(float));
}
-void GCodeAnalyzer::_set_start_position(const Pointf3& position)
+void GCodeAnalyzer::_set_start_position(const Vec3d& position)
{
m_state.start_position = position;
}
-const Pointf3& GCodeAnalyzer::_get_start_position() const
+const Vec3d& GCodeAnalyzer::_get_start_position() const
{
return m_state.start_position;
}
@@ -612,9 +612,9 @@ float GCodeAnalyzer::_get_delta_extrusion() const
return _get_axis_position(E) - m_state.start_extrusion;
}
-Pointf3 GCodeAnalyzer::_get_end_position() const
+Vec3d GCodeAnalyzer::_get_end_position() const
{
- return Pointf3(m_state.position[X], m_state.position[Y], m_state.position[Z]);
+ return Vec3d(m_state.position[X], m_state.position[Y], m_state.position[Z]);
}
void GCodeAnalyzer::_store_move(GCodeAnalyzer::GCodeMove::EType type)
@@ -673,7 +673,7 @@ void GCodeAnalyzer::_calc_gcode_preview_extrusion_layers(GCodePreviewData& previ
Metadata data;
float z = FLT_MAX;
Polyline polyline;
- Pointf3 position(FLT_MAX, FLT_MAX, FLT_MAX);
+ Vec3d position(FLT_MAX, FLT_MAX, FLT_MAX);
float volumetric_rate = FLT_MAX;
GCodePreviewData::Range height_range;
GCodePreviewData::Range width_range;
@@ -683,7 +683,7 @@ void GCodeAnalyzer::_calc_gcode_preview_extrusion_layers(GCodePreviewData& previ
// constructs the polylines while traversing the moves
for (const GCodeMove& move : extrude_moves->second)
{
- if ((data != move.data) || (z != move.start_position.z) || (position != move.start_position) || (volumetric_rate != move.data.feedrate * (float)move.data.mm3_per_mm))
+ if ((data != move.data) || (z != move.start_position.z()) || (position != move.start_position) || (volumetric_rate != move.data.feedrate * (float)move.data.mm3_per_mm))
{
// store current polyline
polyline.remove_duplicate_points();
@@ -693,12 +693,12 @@ void GCodeAnalyzer::_calc_gcode_preview_extrusion_layers(GCodePreviewData& previ
polyline = Polyline();
// add both vertices of the move
- polyline.append(Point(scale_(move.start_position.x), scale_(move.start_position.y)));
- polyline.append(Point(scale_(move.end_position.x), scale_(move.end_position.y)));
+ polyline.append(Point(scale_(move.start_position.x()), scale_(move.start_position.y())));
+ polyline.append(Point(scale_(move.end_position.x()), scale_(move.end_position.y())));
// update current values
data = move.data;
- z = move.start_position.z;
+ z = move.start_position.z();
volumetric_rate = move.data.feedrate * (float)move.data.mm3_per_mm;
height_range.update_from(move.data.height);
width_range.update_from(move.data.width);
@@ -707,7 +707,7 @@ void GCodeAnalyzer::_calc_gcode_preview_extrusion_layers(GCodePreviewData& previ
}
else
// append end vertex of the move to current polyline
- polyline.append(Point(scale_(move.end_position.x), scale_(move.end_position.y)));
+ polyline.append(Point(scale_(move.end_position.x()), scale_(move.end_position.y())));
// update current values
position = move.end_position;
@@ -742,7 +742,7 @@ void GCodeAnalyzer::_calc_gcode_preview_travel(GCodePreviewData& preview_data)
return;
Polyline3 polyline;
- Pointf3 position(FLT_MAX, FLT_MAX, FLT_MAX);
+ Vec3d position(FLT_MAX, FLT_MAX, FLT_MAX);
GCodePreviewData::Travel::EType type = GCodePreviewData::Travel::Num_Types;
GCodePreviewData::Travel::Polyline::EDirection direction = GCodePreviewData::Travel::Polyline::Num_Directions;
float feedrate = FLT_MAX;
@@ -756,7 +756,7 @@ void GCodeAnalyzer::_calc_gcode_preview_travel(GCodePreviewData& preview_data)
for (const GCodeMove& move : travel_moves->second)
{
GCodePreviewData::Travel::EType move_type = (move.delta_extruder < 0.0f) ? GCodePreviewData::Travel::Retract : ((move.delta_extruder > 0.0f) ? GCodePreviewData::Travel::Extrude : GCodePreviewData::Travel::Move);
- GCodePreviewData::Travel::Polyline::EDirection move_direction = ((move.start_position.x != move.end_position.x) || (move.start_position.y != move.end_position.y)) ? GCodePreviewData::Travel::Polyline::Generic : GCodePreviewData::Travel::Polyline::Vertical;
+ GCodePreviewData::Travel::Polyline::EDirection move_direction = ((move.start_position.x() != move.end_position.x()) || (move.start_position.y() != move.end_position.y())) ? GCodePreviewData::Travel::Polyline::Generic : GCodePreviewData::Travel::Polyline::Vertical;
if ((type != move_type) || (direction != move_direction) || (feedrate != move.data.feedrate) || (position != move.start_position) || (extruder_id != move.data.extruder_id))
{
@@ -768,12 +768,12 @@ void GCodeAnalyzer::_calc_gcode_preview_travel(GCodePreviewData& preview_data)
polyline = Polyline3();
// add both vertices of the move
- polyline.append(Point3(scale_(move.start_position.x), scale_(move.start_position.y), scale_(move.start_position.z)));
- polyline.append(Point3(scale_(move.end_position.x), scale_(move.end_position.y), scale_(move.end_position.z)));
+ polyline.append(Vec3crd(scale_(move.start_position.x()), scale_(move.start_position.y()), scale_(move.start_position.z())));
+ polyline.append(Vec3crd(scale_(move.end_position.x()), scale_(move.end_position.y()), scale_(move.end_position.z())));
}
else
// append end vertex of the move to current polyline
- polyline.append(Point3(scale_(move.end_position.x), scale_(move.end_position.y), scale_(move.end_position.z)));
+ polyline.append(Vec3crd(scale_(move.end_position.x()), scale_(move.end_position.y()), scale_(move.end_position.z())));
// update current values
position = move.end_position;
@@ -804,7 +804,7 @@ void GCodeAnalyzer::_calc_gcode_preview_retractions(GCodePreviewData& preview_da
for (const GCodeMove& move : retraction_moves->second)
{
// store position
- Point3 position(scale_(move.start_position.x), scale_(move.start_position.y), scale_(move.start_position.z));
+ Vec3crd position(scale_(move.start_position.x()), scale_(move.start_position.y()), scale_(move.start_position.z()));
preview_data.retraction.positions.emplace_back(position, move.data.width, move.data.height);
}
}
@@ -818,7 +818,7 @@ void GCodeAnalyzer::_calc_gcode_preview_unretractions(GCodePreviewData& preview_
for (const GCodeMove& move : unretraction_moves->second)
{
// store position
- Point3 position(scale_(move.start_position.x), scale_(move.start_position.y), scale_(move.start_position.z));
+ Vec3crd position(scale_(move.start_position.x()), scale_(move.start_position.y()), scale_(move.start_position.z()));
preview_data.unretraction.positions.emplace_back(position, move.data.width, move.data.height);
}
}
diff --git a/xs/src/libslic3r/GCode/Analyzer.hpp b/xs/src/libslic3r/GCode/Analyzer.hpp
index 03dbab338..27a49b869 100644
--- a/xs/src/libslic3r/GCode/Analyzer.hpp
+++ b/xs/src/libslic3r/GCode/Analyzer.hpp
@@ -75,12 +75,12 @@ public:
EType type;
Metadata data;
- Pointf3 start_position;
- Pointf3 end_position;
+ Vec3d start_position;
+ Vec3d end_position;
float delta_extruder;
- GCodeMove(EType type, ExtrusionRole extrusion_role, unsigned int extruder_id, double mm3_per_mm, float width, float height, float feedrate, const Pointf3& start_position, const Pointf3& end_position, float delta_extruder);
- GCodeMove(EType type, const Metadata& data, const Pointf3& start_position, const Pointf3& end_position, float delta_extruder);
+ GCodeMove(EType type, ExtrusionRole extrusion_role, unsigned int extruder_id, double mm3_per_mm, float width, float height, float feedrate, const Vec3d& start_position, const Vec3d& end_position, float delta_extruder);
+ GCodeMove(EType type, const Metadata& data, const Vec3d& start_position, const Vec3d& end_position, float delta_extruder);
};
typedef std::vector<GCodeMove> GCodeMovesList;
@@ -93,7 +93,7 @@ private:
EPositioningType global_positioning_type;
EPositioningType e_local_positioning_type;
Metadata data;
- Pointf3 start_position;
+ Vec3d start_position = Vec3d::Zero();
float start_extrusion;
float position[Num_Axis];
};
@@ -206,15 +206,15 @@ private:
// Sets axes position to zero
void _reset_axes_position();
- void _set_start_position(const Pointf3& position);
- const Pointf3& _get_start_position() const;
+ void _set_start_position(const Vec3d& position);
+ const Vec3d& _get_start_position() const;
void _set_start_extrusion(float extrusion);
float _get_start_extrusion() const;
float _get_delta_extrusion() const;
// Returns current xyz position (from m_state.position[])
- Pointf3 _get_end_position() const;
+ Vec3d _get_end_position() const;
// Adds a new move with the given data
void _store_move(GCodeMove::EType type);
diff --git a/xs/src/libslic3r/GCode/CoolingBuffer.cpp b/xs/src/libslic3r/GCode/CoolingBuffer.cpp
index a15247693..40ccc7b09 100644
--- a/xs/src/libslic3r/GCode/CoolingBuffer.cpp
+++ b/xs/src/libslic3r/GCode/CoolingBuffer.cpp
@@ -23,10 +23,10 @@ CoolingBuffer::CoolingBuffer(GCode &gcodegen) : m_gcodegen(gcodegen), m_current_
void CoolingBuffer::reset()
{
m_current_pos.assign(5, 0.f);
- Pointf3 pos = m_gcodegen.writer().get_position();
- m_current_pos[0] = float(pos.x);
- m_current_pos[1] = float(pos.y);
- m_current_pos[2] = float(pos.z);
+ Vec3d pos = m_gcodegen.writer().get_position();
+ m_current_pos[0] = float(pos(0));
+ m_current_pos[1] = float(pos(1));
+ m_current_pos[2] = float(pos(2));
m_current_pos[4] = float(m_gcodegen.config().travel_speed.value);
}
diff --git a/xs/src/libslic3r/GCode/PreviewData.cpp b/xs/src/libslic3r/GCode/PreviewData.cpp
index 3833bca06..9cf9716e0 100644
--- a/xs/src/libslic3r/GCode/PreviewData.cpp
+++ b/xs/src/libslic3r/GCode/PreviewData.cpp
@@ -226,7 +226,7 @@ void GCodePreviewData::Travel::set_default()
const GCodePreviewData::Color GCodePreviewData::Retraction::Default_Color = GCodePreviewData::Color(1.0f, 1.0f, 1.0f, 1.0f);
-GCodePreviewData::Retraction::Position::Position(const Point3& position, float width, float height)
+GCodePreviewData::Retraction::Position::Position(const Vec3crd& position, float width, float height)
: position(position)
, width(width)
, height(height)
diff --git a/xs/src/libslic3r/GCode/PreviewData.hpp b/xs/src/libslic3r/GCode/PreviewData.hpp
index ea8ca6d58..ab74993f5 100644
--- a/xs/src/libslic3r/GCode/PreviewData.hpp
+++ b/xs/src/libslic3r/GCode/PreviewData.hpp
@@ -151,11 +151,11 @@ public:
struct Position
{
- Point3 position;
+ Vec3crd position;
float width;
float height;
- Position(const Point3& position, float width, float height);
+ Position(const Vec3crd& position, float width, float height);
};
typedef std::vector<Position> PositionsList;
diff --git a/xs/src/libslic3r/GCode/PrintExtents.cpp b/xs/src/libslic3r/GCode/PrintExtents.cpp
index 37b79f343..2ed607769 100644
--- a/xs/src/libslic3r/GCode/PrintExtents.cpp
+++ b/xs/src/libslic3r/GCode/PrintExtents.cpp
@@ -19,10 +19,10 @@ static inline BoundingBox extrusion_polyline_extents(const Polyline &polyline, c
if (! polyline.points.empty())
bbox.merge(polyline.points.front());
for (const Point &pt : polyline.points) {
- bbox.min.x = std::min(bbox.min.x, pt.x - radius);
- bbox.min.y = std::min(bbox.min.y, pt.y - radius);
- bbox.max.x = std::max(bbox.max.x, pt.x + radius);
- bbox.max.y = std::max(bbox.max.y, pt.y + radius);
+ bbox.min(0) = std::min(bbox.min(0), pt(0) - radius);
+ bbox.min(1) = std::min(bbox.min(1), pt(1) - radius);
+ bbox.max(0) = std::max(bbox.max(0), pt(0) + radius);
+ bbox.max(1) = std::max(bbox.max(1), pt(1) + radius);
}
return bbox;
}
@@ -32,8 +32,8 @@ static inline BoundingBoxf extrusionentity_extents(const ExtrusionPath &extrusio
BoundingBox bbox = extrusion_polyline_extents(extrusion_path.polyline, scale_(0.5 * extrusion_path.width));
BoundingBoxf bboxf;
if (! empty(bbox)) {
- bboxf.min = Pointf::new_unscale(bbox.min);
- bboxf.max = Pointf::new_unscale(bbox.max);
+ bboxf.min = unscale(bbox.min);
+ bboxf.max = unscale(bbox.max);
bboxf.defined = true;
}
return bboxf;
@@ -46,8 +46,8 @@ static inline BoundingBoxf extrusionentity_extents(const ExtrusionLoop &extrusio
bbox.merge(extrusion_polyline_extents(extrusion_path.polyline, scale_(0.5 * extrusion_path.width)));
BoundingBoxf bboxf;
if (! empty(bbox)) {
- bboxf.min = Pointf::new_unscale(bbox.min);
- bboxf.max = Pointf::new_unscale(bbox.max);
+ bboxf.min = unscale(bbox.min);
+ bboxf.max = unscale(bbox.max);
bboxf.defined = true;
}
return bboxf;
@@ -60,8 +60,8 @@ static inline BoundingBoxf extrusionentity_extents(const ExtrusionMultiPath &ext
bbox.merge(extrusion_polyline_extents(extrusion_path.polyline, scale_(0.5 * extrusion_path.width)));
BoundingBoxf bboxf;
if (! empty(bbox)) {
- bboxf.min = Pointf::new_unscale(bbox.min);
- bboxf.max = Pointf::new_unscale(bbox.max);
+ bboxf.min = unscale(bbox.min);
+ bboxf.max = unscale(bbox.max);
bboxf.defined = true;
}
return bboxf;
@@ -123,7 +123,7 @@ BoundingBoxf get_print_object_extrusions_extents(const PrintObject &print_object
bbox_this.merge(extrusionentity_extents(extrusion_entity));
for (const Point &offset : print_object._shifted_copies) {
BoundingBoxf bbox_translated(bbox_this);
- bbox_translated.translate(Pointf::new_unscale(offset));
+ bbox_translated.translate(unscale(offset));
bbox.merge(bbox_translated);
}
}
@@ -136,8 +136,9 @@ BoundingBoxf get_wipe_tower_extrusions_extents(const Print &print, const coordf_
{
// Wipe tower extrusions are saved as if the tower was at the origin with no rotation
// We need to get position and angle of the wipe tower to transform them to actual position.
- Pointf wipe_tower_pos(print.config.wipe_tower_x.value, print.config.wipe_tower_y.value);
- float wipe_tower_angle = print.config.wipe_tower_rotation_angle.value;
+ Transform2d trafo =
+ Eigen::Translation2d(print.config.wipe_tower_x.value, print.config.wipe_tower_y.value) *
+ Eigen::Rotation2Dd(print.config.wipe_tower_rotation_angle.value);
BoundingBoxf bbox;
for (const std::vector<WipeTower::ToolChangeResult> &tool_changes : print.m_wipe_tower_tool_changes) {
@@ -147,19 +148,11 @@ BoundingBoxf get_wipe_tower_extrusions_extents(const Print &print, const coordf_
for (size_t i = 1; i < tcr.extrusions.size(); ++ i) {
const WipeTower::Extrusion &e = tcr.extrusions[i];
if (e.width > 0) {
- Pointf p1((&e - 1)->pos.x, (&e - 1)->pos.y);
- Pointf p2(e.pos.x, e.pos.y);
- p1.rotate(wipe_tower_angle);
- p1.translate(wipe_tower_pos);
- p2.rotate(wipe_tower_angle);
- p2.translate(wipe_tower_pos);
-
- bbox.merge(p1);
- coordf_t radius = 0.5 * e.width;
- bbox.min.x = std::min(bbox.min.x, std::min(p1.x, p2.x) - radius);
- bbox.min.y = std::min(bbox.min.y, std::min(p1.y, p2.y) - radius);
- bbox.max.x = std::max(bbox.max.x, std::max(p1.x, p2.x) + radius);
- bbox.max.y = std::max(bbox.max.y, std::max(p1.y, p2.y) + radius);
+ Vec2d delta = 0.5 * Vec2d(e.width, e.width);
+ Vec2d p1 = trafo * Vec2d((&e - 1)->pos.x, (&e - 1)->pos.y);
+ Vec2d p2 = trafo * Vec2d(e.pos.x, e.pos.y);
+ bbox.merge(p1.cwiseMin(p2) - delta);
+ bbox.merge(p1.cwiseMax(p2) + delta);
}
}
}
@@ -176,14 +169,14 @@ BoundingBoxf get_wipe_tower_priming_extrusions_extents(const Print &print)
for (size_t i = 1; i < tcr.extrusions.size(); ++ i) {
const WipeTower::Extrusion &e = tcr.extrusions[i];
if (e.width > 0) {
- Pointf p1((&e - 1)->pos.x, (&e - 1)->pos.y);
- Pointf p2(e.pos.x, e.pos.y);
+ Vec2d p1((&e - 1)->pos.x, (&e - 1)->pos.y);
+ Vec2d p2(e.pos.x, e.pos.y);
bbox.merge(p1);
coordf_t radius = 0.5 * e.width;
- bbox.min.x = std::min(bbox.min.x, std::min(p1.x, p2.x) - radius);
- bbox.min.y = std::min(bbox.min.y, std::min(p1.y, p2.y) - radius);
- bbox.max.x = std::max(bbox.max.x, std::max(p1.x, p2.x) + radius);
- bbox.max.y = std::max(bbox.max.y, std::max(p1.y, p2.y) + radius);
+ bbox.min(0) = std::min(bbox.min(0), std::min(p1(0), p2(0)) - radius);
+ bbox.min(1) = std::min(bbox.min(1), std::min(p1(1), p2(1)) - radius);
+ bbox.max(0) = std::max(bbox.max(0), std::max(p1(0), p2(0)) + radius);
+ bbox.max(1) = std::max(bbox.max(1), std::max(p1(1), p2(1)) + radius);
}
}
}
diff --git a/xs/src/libslic3r/GCode/WipeTower.hpp b/xs/src/libslic3r/GCode/WipeTower.hpp
index 9bf350328..c35a0feb3 100644
--- a/xs/src/libslic3r/GCode/WipeTower.hpp
+++ b/xs/src/libslic3r/GCode/WipeTower.hpp
@@ -30,10 +30,9 @@ public:
xy out(0,0);
float temp_x = x - width / 2.f;
float temp_y = y - depth / 2.f;
- angle *= M_PI/180.;
+ angle *= float(M_PI/180.);
out.x += temp_x * cos(angle) - temp_y * sin(angle) + width / 2.f;
out.y += temp_x * sin(angle) + temp_y * cos(angle) + depth / 2.f;
-
return out;
}
diff --git a/xs/src/libslic3r/GCodeWriter.cpp b/xs/src/libslic3r/GCodeWriter.cpp
index 34e6b7ec3..6ef17f4f4 100644
--- a/xs/src/libslic3r/GCodeWriter.cpp
+++ b/xs/src/libslic3r/GCodeWriter.cpp
@@ -276,30 +276,30 @@ std::string GCodeWriter::set_speed(double F, const std::string &comment, const s
return gcode.str();
}
-std::string GCodeWriter::travel_to_xy(const Pointf &point, const std::string &comment)
+std::string GCodeWriter::travel_to_xy(const Vec2d &point, const std::string &comment)
{
- m_pos.x = point.x;
- m_pos.y = point.y;
+ m_pos(0) = point(0);
+ m_pos(1) = point(1);
std::ostringstream gcode;
- gcode << "G1 X" << XYZF_NUM(point.x)
- << " Y" << XYZF_NUM(point.y)
+ gcode << "G1 X" << XYZF_NUM(point(0))
+ << " Y" << XYZF_NUM(point(1))
<< " F" << XYZF_NUM(this->config.travel_speed.value * 60.0);
COMMENT(comment);
gcode << "\n";
return gcode.str();
}
-std::string GCodeWriter::travel_to_xyz(const Pointf3 &point, const std::string &comment)
+std::string GCodeWriter::travel_to_xyz(const Vec3d &point, const std::string &comment)
{
/* If target Z is lower than current Z but higher than nominal Z we
don't perform the Z move but we only move in the XY plane and
adjust the nominal Z by reducing the lift amount that will be
used for unlift. */
- 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);
+ if (!this->will_move_z(point(2))) {
+ double nominal_z = m_pos(2) - m_lifted;
+ m_lifted = m_lifted - (point(2) - nominal_z);
+ return this->travel_to_xy(to_2d(point));
}
/* In all the other cases, we perform an actual XYZ move and cancel
@@ -308,9 +308,9 @@ std::string GCodeWriter::travel_to_xyz(const Pointf3 &point, const std::string &
m_pos = point;
std::ostringstream gcode;
- gcode << "G1 X" << XYZF_NUM(point.x)
- << " Y" << XYZF_NUM(point.y)
- << " Z" << XYZF_NUM(point.z)
+ gcode << "G1 X" << XYZF_NUM(point(0))
+ << " Y" << XYZF_NUM(point(1))
+ << " Z" << XYZF_NUM(point(2))
<< " F" << XYZF_NUM(this->config.travel_speed.value * 60.0);
COMMENT(comment);
gcode << "\n";
@@ -323,7 +323,7 @@ std::string GCodeWriter::travel_to_z(double z, const std::string &comment)
we don't perform the move but we only adjust the nominal Z by
reducing the lift amount that will be used for unlift. */
if (!this->will_move_z(z)) {
- double nominal_z = m_pos.z - m_lifted;
+ double nominal_z = m_pos(2) - m_lifted;
m_lifted = m_lifted - (z - nominal_z);
return "";
}
@@ -336,7 +336,7 @@ std::string GCodeWriter::travel_to_z(double z, const std::string &comment)
std::string GCodeWriter::_travel_to_z(double z, const std::string &comment)
{
- m_pos.z = z;
+ m_pos(2) = z;
std::ostringstream gcode;
gcode << "G1 Z" << XYZF_NUM(z)
@@ -351,38 +351,38 @@ bool GCodeWriter::will_move_z(double z) const
/* If target Z is lower than current Z but higher than nominal Z
we don't perform an actual Z move. */
if (m_lifted > 0) {
- double nominal_z = m_pos.z - m_lifted;
- if (z >= nominal_z && z <= m_pos.z)
+ double nominal_z = m_pos(2) - m_lifted;
+ if (z >= nominal_z && z <= m_pos(2))
return false;
}
return true;
}
-std::string GCodeWriter::extrude_to_xy(const Pointf &point, double dE, const std::string &comment)
+std::string GCodeWriter::extrude_to_xy(const Vec2d &point, double dE, const std::string &comment)
{
- m_pos.x = point.x;
- m_pos.y = point.y;
+ m_pos(0) = point(0);
+ m_pos(1) = point(1);
m_extruder->extrude(dE);
std::ostringstream gcode;
- gcode << "G1 X" << XYZF_NUM(point.x)
- << " Y" << XYZF_NUM(point.y)
+ gcode << "G1 X" << XYZF_NUM(point(0))
+ << " Y" << XYZF_NUM(point(1))
<< " " << m_extrusion_axis << E_NUM(m_extruder->E());
COMMENT(comment);
gcode << "\n";
return gcode.str();
}
-std::string GCodeWriter::extrude_to_xyz(const Pointf3 &point, double dE, const std::string &comment)
+std::string GCodeWriter::extrude_to_xyz(const Vec3d &point, double dE, const std::string &comment)
{
m_pos = point;
m_lifted = 0;
m_extruder->extrude(dE);
std::ostringstream gcode;
- gcode << "G1 X" << XYZF_NUM(point.x)
- << " Y" << XYZF_NUM(point.y)
- << " Z" << XYZF_NUM(point.z)
+ gcode << "G1 X" << XYZF_NUM(point(0))
+ << " Y" << XYZF_NUM(point(1))
+ << " Z" << XYZF_NUM(point(2))
<< " " << m_extrusion_axis << E_NUM(m_extruder->E());
COMMENT(comment);
gcode << "\n";
@@ -486,12 +486,12 @@ std::string GCodeWriter::lift()
{
double above = this->config.retract_lift_above.get_at(m_extruder->id());
double below = this->config.retract_lift_below.get_at(m_extruder->id());
- if (m_pos.z >= above && (below == 0 || m_pos.z <= below))
+ if (m_pos(2) >= above && (below == 0 || m_pos(2) <= below))
target_lift = this->config.retract_lift.get_at(m_extruder->id());
}
if (m_lifted == 0 && target_lift > 0) {
m_lifted = target_lift;
- return this->_travel_to_z(m_pos.z + target_lift, "lift Z");
+ return this->_travel_to_z(m_pos(2) + target_lift, "lift Z");
}
return "";
}
@@ -500,7 +500,7 @@ std::string GCodeWriter::unlift()
{
std::string gcode;
if (m_lifted > 0) {
- gcode += this->_travel_to_z(m_pos.z - m_lifted, "restore layer Z");
+ gcode += this->_travel_to_z(m_pos(2) - m_lifted, "restore layer Z");
m_lifted = 0;
}
return gcode;
diff --git a/xs/src/libslic3r/GCodeWriter.hpp b/xs/src/libslic3r/GCodeWriter.hpp
index f706b8768..664b0e3a1 100644
--- a/xs/src/libslic3r/GCodeWriter.hpp
+++ b/xs/src/libslic3r/GCodeWriter.hpp
@@ -55,18 +55,18 @@ public:
std::string toolchange_prefix() const;
std::string toolchange(unsigned int extruder_id);
std::string set_speed(double F, const std::string &comment = std::string(), const std::string &cooling_marker = std::string()) const;
- std::string travel_to_xy(const Pointf &point, const std::string &comment = std::string());
- std::string travel_to_xyz(const Pointf3 &point, const std::string &comment = std::string());
+ std::string travel_to_xy(const Vec2d &point, const std::string &comment = std::string());
+ std::string travel_to_xyz(const Vec3d &point, const std::string &comment = std::string());
std::string travel_to_z(double z, const std::string &comment = std::string());
bool will_move_z(double z) const;
- std::string extrude_to_xy(const Pointf &point, double dE, const std::string &comment = std::string());
- std::string extrude_to_xyz(const Pointf3 &point, double dE, const std::string &comment = std::string());
+ std::string extrude_to_xy(const Vec2d &point, double dE, const std::string &comment = std::string());
+ std::string extrude_to_xyz(const Vec3d &point, double dE, const std::string &comment = std::string());
std::string retract(bool before_wipe = false);
std::string retract_for_toolchange(bool before_wipe = false);
std::string unretract();
std::string lift();
std::string unlift();
- Pointf3 get_position() const { return m_pos; }
+ Vec3d get_position() const { return m_pos; }
private:
std::vector<Extruder> m_extruders;
@@ -81,7 +81,7 @@ private:
unsigned int m_last_bed_temperature;
bool m_last_bed_temperature_reached;
double m_lifted;
- Pointf3 m_pos;
+ Vec3d m_pos = Vec3d::Zero();
std::string _travel_to_z(double z, const std::string &comment);
std::string _retract(double length, double restart_extra, const std::string &comment);
diff --git a/xs/src/libslic3r/Geometry.cpp b/xs/src/libslic3r/Geometry.cpp
index aaf0352c9..b0ded2d04 100644
--- a/xs/src/libslic3r/Geometry.cpp
+++ b/xs/src/libslic3r/Geometry.cpp
@@ -195,26 +195,29 @@ using namespace boost::polygon; // provides also high() and low()
namespace Slic3r { namespace Geometry {
-struct SortPoints {
- template <class T>
- bool operator()(const T& a, const T& b) const {
- return (b.x > a.x) || (a.x == b.x && b.y > a.y);
- }
-};
+static bool sort_points(const Point& a, const Point& b)
+{
+ return (a(0) < b(0)) || (a(0) == b(0) && a(1) < b(1));
+}
+
+static bool sort_pointfs(const Vec3d& a, const Vec3d& b)
+{
+ return (a(0) < b(0)) || (a(0) == b(0) && a(1) < b(1));
+}
// This implementation is based on Andrew's monotone chain 2D convex hull algorithm
-template<class T>
-static T raw_convex_hull(T& points)
+Polygon
+convex_hull(Points points)
{
assert(points.size() >= 3);
// sort input points
- std::sort(points.begin(), points.end(), SortPoints());
-
+ std::sort(points.begin(), points.end(), sort_points);
+
int n = points.size(), k = 0;
- T hull;
+ Polygon hull;
if (n >= 3) {
- hull.resize(2*n);
+ hull.points.resize(2 * n);
// Build lower hull
for (int i = 0; i < n; i++) {
@@ -228,10 +231,10 @@ static T raw_convex_hull(T& points)
hull[k++] = points[i];
}
- hull.resize(k);
-
- assert( hull.front().coincides_with(hull.back()) );
- hull.pop_back();
+ hull.points.resize(k);
+
+ assert(hull.points.front() == hull.points.back());
+ hull.points.pop_back();
}
return hull;
@@ -240,14 +243,59 @@ static T raw_convex_hull(T& points)
Pointf3s
convex_hull(Pointf3s points)
{
- return raw_convex_hull(points);
-}
+ assert(points.size() >= 3);
+ // sort input points
+ std::sort(points.begin(), points.end(), sort_pointfs);
+
+ int n = points.size(), k = 0;
+ Pointf3s hull;
+
+ if (n >= 3)
+ {
+ hull.resize(2 * n);
+
+ // Build lower hull
+ for (int i = 0; i < n; ++i)
+ {
+ Point p = Point::new_scale(points[i](0), points[i](1));
+ while (k >= 2)
+ {
+ Point k1 = Point::new_scale(hull[k - 1](0), hull[k - 1](1));
+ Point k2 = Point::new_scale(hull[k - 2](0), hull[k - 2](1));
+
+ if (p.ccw(k2, k1) <= 0)
+ --k;
+ else
+ break;
+ }
+
+ hull[k++] = points[i];
+ }
+
+ // Build upper hull
+ for (int i = n - 2, t = k + 1; i >= 0; --i)
+ {
+ Point p = Point::new_scale(points[i](0), points[i](1));
+ while (k >= t)
+ {
+ Point k1 = Point::new_scale(hull[k - 1](0), hull[k - 1](1));
+ Point k2 = Point::new_scale(hull[k - 2](0), hull[k - 2](1));
+
+ if (p.ccw(k2, k1) <= 0)
+ --k;
+ else
+ break;
+ }
+
+ hull[k++] = points[i];
+ }
+
+ hull.resize(k);
+
+ assert(hull.front() == hull.back());
+ hull.pop_back();
+ }
-Polygon
-convex_hull(Points points)
-{
- Polygon hull;
- hull.points = raw_convex_hull(points);
return hull;
}
@@ -360,54 +408,54 @@ linint(double value, double oldmin, double oldmax, double newmin, double newmax)
// If the points have the same weight, sort them lexicographically by their positions.
struct ArrangeItem {
ArrangeItem() {}
- Pointf pos;
+ Vec2d pos;
coordf_t weight;
bool operator<(const ArrangeItem &other) const {
return weight < other.weight ||
- ((weight == other.weight) && (pos.y < other.pos.y || (pos.y == other.pos.y && pos.x < other.pos.x)));
+ ((weight == other.weight) && (pos(1) < other.pos(1) || (pos(1) == other.pos(1) && pos(0) < other.pos(0))));
}
};
-Pointfs arrange(size_t num_parts, const Pointf &part_size, coordf_t gap, const BoundingBoxf* bed_bounding_box)
+Pointfs arrange(size_t num_parts, const Vec2d &part_size, coordf_t gap, const BoundingBoxf* bed_bounding_box)
{
// Use actual part size (the largest) plus separation distance (half on each side) in spacing algorithm.
- const Pointf cell_size(part_size.x + gap, part_size.y + gap);
+ const Vec2d cell_size(part_size(0) + gap, part_size(1) + gap);
const BoundingBoxf bed_bbox = (bed_bounding_box != NULL && bed_bounding_box->defined) ?
*bed_bounding_box :
// Bogus bed size, large enough not to trigger the unsufficient bed size error.
BoundingBoxf(
- Pointf(0, 0),
- Pointf(cell_size.x * num_parts, cell_size.y * num_parts));
+ Vec2d(0, 0),
+ Vec2d(cell_size(0) * num_parts, cell_size(1) * num_parts));
// This is how many cells we have available into which to put parts.
- size_t cellw = size_t(floor((bed_bbox.size().x + gap) / cell_size.x));
- size_t cellh = size_t(floor((bed_bbox.size().y + gap) / cell_size.y));
+ size_t cellw = size_t(floor((bed_bbox.size()(0) + gap) / cell_size(0)));
+ size_t cellh = size_t(floor((bed_bbox.size()(1) + gap) / cell_size(1)));
if (num_parts > cellw * cellh)
CONFESS(PRINTF_ZU " parts won't fit in your print area!\n", num_parts);
// Get a bounding box of cellw x cellh cells, centered at the center of the bed.
- Pointf cells_size(cellw * cell_size.x - gap, cellh * cell_size.y - gap);
- Pointf cells_offset(bed_bbox.center() - 0.5 * cells_size);
+ Vec2d cells_size(cellw * cell_size(0) - gap, cellh * cell_size(1) - gap);
+ Vec2d cells_offset(bed_bbox.center() - 0.5 * cells_size);
BoundingBoxf cells_bb(cells_offset, cells_size + cells_offset);
// List of cells, sorted by distance from center.
std::vector<ArrangeItem> cellsorder(cellw * cellh, ArrangeItem());
for (size_t j = 0; j < cellh; ++ j) {
// Center of the jth row on the bed.
- coordf_t cy = linint(j + 0.5, 0., double(cellh), cells_bb.min.y, cells_bb.max.y);
+ coordf_t cy = linint(j + 0.5, 0., double(cellh), cells_bb.min(1), cells_bb.max(1));
// Offset from the bed center.
- coordf_t yd = cells_bb.center().y - cy;
+ coordf_t yd = cells_bb.center()(1) - cy;
for (size_t i = 0; i < cellw; ++ i) {
// Center of the ith column on the bed.
- coordf_t cx = linint(i + 0.5, 0., double(cellw), cells_bb.min.x, cells_bb.max.x);
+ coordf_t cx = linint(i + 0.5, 0., double(cellw), cells_bb.min(0), cells_bb.max(0));
// Offset from the bed center.
- coordf_t xd = cells_bb.center().x - cx;
+ coordf_t xd = cells_bb.center()(0) - cx;
// Cell with a distance from the bed center.
ArrangeItem &ci = cellsorder[j * cellw + i];
// Cell center
- ci.pos.x = cx;
- ci.pos.y = cy;
+ ci.pos(0) = cx;
+ ci.pos(1) = cy;
// Square distance of the cell center to the bed center.
ci.weight = xd * xd + yd * yd;
}
@@ -420,61 +468,61 @@ Pointfs arrange(size_t num_parts, const Pointf &part_size, coordf_t gap, const B
Pointfs positions;
positions.reserve(num_parts);
for (std::vector<ArrangeItem>::const_iterator it = cellsorder.begin(); it != cellsorder.end(); ++ it)
- positions.push_back(Pointf(it->pos.x - 0.5 * part_size.x, it->pos.y - 0.5 * part_size.y));
+ positions.push_back(Vec2d(it->pos(0) - 0.5 * part_size(0), it->pos(1) - 0.5 * part_size(1)));
return positions;
}
#else
class ArrangeItem {
- public:
- Pointf pos;
+public:
+ Vec2d pos = Vec2d::Zero();
size_t index_x, index_y;
coordf_t dist;
};
class ArrangeItemIndex {
- public:
+public:
coordf_t index;
ArrangeItem item;
ArrangeItemIndex(coordf_t _index, ArrangeItem _item) : index(_index), item(_item) {};
};
bool
-arrange(size_t total_parts, const Pointf &part_size, coordf_t dist, const BoundingBoxf* bb, Pointfs &positions)
+arrange(size_t total_parts, const Vec2d &part_size, coordf_t dist, const BoundingBoxf* bb, Pointfs &positions)
{
positions.clear();
- Pointf part = part_size;
+ Vec2d part = part_size;
// use actual part size (the largest) plus separation distance (half on each side) in spacing algorithm
- part.x += dist;
- part.y += dist;
+ part(0) += dist;
+ part(1) += dist;
- Pointf area;
+ Vec2d area(Vec2d::Zero());
if (bb != NULL && bb->defined) {
area = bb->size();
} else {
// bogus area size, large enough not to trigger the error below
- area.x = part.x * total_parts;
- area.y = part.y * total_parts;
+ area(0) = part(0) * total_parts;
+ area(1) = part(1) * total_parts;
}
// this is how many cells we have available into which to put parts
- size_t cellw = floor((area.x + dist) / part.x);
- size_t cellh = floor((area.y + dist) / part.y);
+ size_t cellw = floor((area(0) + dist) / part(0));
+ size_t cellh = floor((area(1) + dist) / part(1));
if (total_parts > (cellw * cellh))
return false;
// total space used by cells
- Pointf cells(cellw * part.x, cellh * part.y);
+ Vec2d cells(cellw * part(0), cellh * part(1));
// bounding box of total space used by cells
BoundingBoxf cells_bb;
- cells_bb.merge(Pointf(0,0)); // min
+ cells_bb.merge(Vec2d(0,0)); // min
cells_bb.merge(cells); // max
// center bounding box to area
cells_bb.translate(
- (area.x - cells.x) / 2,
- (area.y - cells.y) / 2
+ (area(0) - cells(0)) / 2,
+ (area(1) - cells(1)) / 2
);
// list of cells, sorted by distance from center
@@ -483,15 +531,15 @@ arrange(size_t total_parts, const Pointf &part_size, coordf_t dist, const Boundi
// work out distance for all cells, sort into list
for (size_t i = 0; i <= cellw-1; ++i) {
for (size_t j = 0; j <= cellh-1; ++j) {
- coordf_t cx = linint(i + 0.5, 0, cellw, cells_bb.min.x, cells_bb.max.x);
- coordf_t cy = linint(j + 0.5, 0, cellh, cells_bb.min.y, cells_bb.max.y);
+ coordf_t cx = linint(i + 0.5, 0, cellw, cells_bb.min(0), cells_bb.max(0));
+ coordf_t cy = linint(j + 0.5, 0, cellh, cells_bb.min(1), cells_bb.max(1));
- coordf_t xd = fabs((area.x / 2) - cx);
- coordf_t yd = fabs((area.y / 2) - cy);
+ coordf_t xd = fabs((area(0) / 2) - cx);
+ coordf_t yd = fabs((area(1) / 2) - cy);
ArrangeItem c;
- c.pos.x = cx;
- c.pos.y = cy;
+ c.pos(0) = cx;
+ c.pos(1) = cy;
c.index_x = i;
c.index_y = j;
c.dist = xd * xd + yd * yd - fabs((cellw / 2) - (i + 0.5));
@@ -548,13 +596,13 @@ arrange(size_t total_parts, const Pointf &part_size, coordf_t dist, const Boundi
coordf_t cx = c.item.index_x - lx;
coordf_t cy = c.item.index_y - ty;
- positions.push_back(Pointf(cx * part.x, cy * part.y));
+ positions.push_back(Vec2d(cx * part(0), cy * part(1)));
}
if (bb != NULL && bb->defined) {
for (Pointfs::iterator p = positions.begin(); p != positions.end(); ++p) {
- p->x += bb->min.x;
- p->y += bb->min.y;
+ p->x() += bb->min(0);
+ p->y() += bb->min(1);
}
}
@@ -623,15 +671,15 @@ namespace Voronoi { namespace Internal {
if (cell1.contains_point() && cell2.contains_point()) {
point_type p1 = retrieve_point(segments, cell1);
point_type p2 = retrieve_point(segments, cell2);
- origin.x((p1.x() + p2.x()) * 0.5);
- origin.y((p1.y() + p2.y()) * 0.5);
- direction.x(p1.y() - p2.y());
- direction.y(p2.x() - p1.x());
+ origin.x((p1(0) + p2(0)) * 0.5);
+ origin.y((p1(1) + p2(1)) * 0.5);
+ direction.x(p1(1) - p2(1));
+ direction.y(p2(0) - p1(0));
} else {
origin = cell1.contains_segment() ? retrieve_point(segments, cell2) : retrieve_point(segments, cell1);
segment_type segment = cell1.contains_segment() ? segments[cell1.source_index()] : segments[cell2.source_index()];
- coordinate_type dx = high(segment).x() - low(segment).x();
- coordinate_type dy = high(segment).y() - low(segment).y();
+ coordinate_type dx = high(segment)(0) - low(segment)(0);
+ coordinate_type dy = high(segment)(1) - low(segment)(1);
if ((low(segment) == origin) ^ cell1.contains_point()) {
direction.x(dy);
direction.y(-dx);
@@ -640,19 +688,19 @@ namespace Voronoi { namespace Internal {
direction.y(dx);
}
}
- coordinate_type koef = bbox_max_size / (std::max)(fabs(direction.x()), fabs(direction.y()));
+ coordinate_type koef = bbox_max_size / (std::max)(fabs(direction(0)), fabs(direction(1)));
if (edge.vertex0() == NULL) {
clipped_edge->push_back(point_type(
- origin.x() - direction.x() * koef,
- origin.y() - direction.y() * koef));
+ origin(0) - direction(0) * koef,
+ origin(1) - direction(1) * koef));
} else {
clipped_edge->push_back(
point_type(edge.vertex0()->x(), edge.vertex0()->y()));
}
if (edge.vertex1() == NULL) {
clipped_edge->push_back(point_type(
- origin.x() + direction.x() * koef,
- origin.y() + direction.y() * koef));
+ origin(0) + direction(0) * koef,
+ origin(1) + direction(1) * koef));
} else {
clipped_edge->push_back(
point_type(edge.vertex1()->x(), edge.vertex1()->y()));
@@ -691,10 +739,10 @@ static inline void dump_voronoi_to_svg(const Lines &lines, /* const */ voronoi_d
const bool primaryEdgesOnly = false;
BoundingBox bbox = BoundingBox(lines);
- bbox.min.x -= coord_t(1. / SCALING_FACTOR);
- bbox.min.y -= coord_t(1. / SCALING_FACTOR);
- bbox.max.x += coord_t(1. / SCALING_FACTOR);
- bbox.max.y += coord_t(1. / SCALING_FACTOR);
+ bbox.min(0) -= coord_t(1. / SCALING_FACTOR);
+ bbox.min(1) -= coord_t(1. / SCALING_FACTOR);
+ bbox.max(0) += coord_t(1. / SCALING_FACTOR);
+ bbox.max(1) += coord_t(1. / SCALING_FACTOR);
::Slic3r::SVG svg(path, bbox);
@@ -704,7 +752,7 @@ static inline void dump_voronoi_to_svg(const Lines &lines, /* const */ voronoi_d
// bbox.scale(1.2);
// For clipping of half-lines to some reasonable value.
// The line will then be clipped by the SVG viewer anyway.
- const double bbox_dim_max = double(bbox.max.x - bbox.min.x) + double(bbox.max.y - bbox.min.y);
+ const double bbox_dim_max = double(bbox.max(0) - bbox.min(0)) + double(bbox.max(1) - bbox.min(1));
// For the discretization of the Voronoi parabolic segments.
const double discretization_step = 0.0005 * bbox_dim_max;
@@ -712,8 +760,8 @@ static inline void dump_voronoi_to_svg(const Lines &lines, /* const */ voronoi_d
std::vector<Voronoi::Internal::segment_type> segments;
for (Lines::const_iterator it = lines.begin(); it != lines.end(); ++ it)
segments.push_back(Voronoi::Internal::segment_type(
- Voronoi::Internal::point_type(double(it->a.x), double(it->a.y)),
- Voronoi::Internal::point_type(double(it->b.x), double(it->b.y))));
+ Voronoi::Internal::point_type(double(it->a(0)), double(it->a(1))),
+ Voronoi::Internal::point_type(double(it->b(0)), double(it->b(1)))));
// Color exterior edges.
for (voronoi_diagram<double>::const_edge_iterator it = vd.edges().begin(); it != vd.edges().end(); ++it)
@@ -727,13 +775,13 @@ static inline void dump_voronoi_to_svg(const Lines &lines, /* const */ voronoi_d
}
// Draw the input polygon.
for (Lines::const_iterator it = lines.begin(); it != lines.end(); ++it)
- svg.draw(Line(Point(coord_t(it->a.x), coord_t(it->a.y)), Point(coord_t(it->b.x), coord_t(it->b.y))), inputSegmentColor, inputSegmentLineWidth);
+ svg.draw(Line(Point(coord_t(it->a(0)), coord_t(it->a(1))), Point(coord_t(it->b(0)), coord_t(it->b(1)))), inputSegmentColor, inputSegmentLineWidth);
#if 1
// Draw voronoi vertices.
for (voronoi_diagram<double>::const_vertex_iterator it = vd.vertices().begin(); it != vd.vertices().end(); ++it)
if (! internalEdgesOnly || it->color() != Voronoi::Internal::EXTERNAL_COLOR)
- svg.draw(Point(coord_t(it->x()), coord_t(it->y())), voronoiPointColor, voronoiPointRadius);
+ svg.draw(Point(coord_t((*it)(0)), coord_t((*it)(1))), voronoiPointColor, voronoiPointRadius);
for (voronoi_diagram<double>::const_edge_iterator it = vd.edges().begin(); it != vd.edges().end(); ++it) {
if (primaryEdgesOnly && !it->is_primary())
@@ -758,7 +806,7 @@ static inline void dump_voronoi_to_svg(const Lines &lines, /* const */ voronoi_d
color = voronoiLineColorSecondary;
}
for (std::size_t i = 0; i + 1 < samples.size(); ++i)
- svg.draw(Line(Point(coord_t(samples[i].x()), coord_t(samples[i].y())), Point(coord_t(samples[i+1].x()), coord_t(samples[i+1].y()))), color, voronoiLineWidth);
+ svg.draw(Line(Point(coord_t(samples[i](0)), coord_t(samples[i](1))), Point(coord_t(samples[i+1](0)), coord_t(samples[i+1](1)))), color, voronoiLineWidth);
}
#endif
@@ -773,8 +821,8 @@ static inline void dump_voronoi_to_svg(const Lines &lines, /* const */ voronoi_d
template<typename T>
T dist(const boost::polygon::point_data<T> &p1,const boost::polygon::point_data<T> &p2)
{
- T dx = p2.x() - p1.x();
- T dy = p2.y() - p1.y();
+ T dx = p2(0) - p1(0);
+ T dy = p2(1) - p1(1);
return sqrt(dx*dx+dy*dy);
}
@@ -785,11 +833,11 @@ inline point_type project_point_to_segment(segment_type &seg, point_type &px)
typedef typename point_type::coordinate_type T;
const point_type &p0 = low(seg);
const point_type &p1 = high(seg);
- const point_type dir(p1.x()-p0.x(), p1.y()-p0.y());
- const point_type dproj(px.x()-p0.x(), px.y()-p0.y());
- const T t = (dir.x()*dproj.x() + dir.y()*dproj.y()) / (dir.x()*dir.x() + dir.y()*dir.y());
+ const point_type dir(p1(0)-p0(0), p1(1)-p0(1));
+ const point_type dproj(px(0)-p0(0), px(1)-p0(1));
+ const T t = (dir(0)*dproj(0) + dir(1)*dproj(1)) / (dir(0)*dir(0) + dir(1)*dir(1));
assert(t >= T(-1e-6) && t <= T(1. + 1e-6));
- return point_type(p0.x() + t*dir.x(), p0.y() + t*dir.y());
+ return point_type(p0(0) + t*dir(0), p0(1) + t*dir(1));
}
template<typename VD, typename SEGMENTS>
@@ -843,8 +891,8 @@ public:
Lines2VDSegments(const Lines &alines) : lines(alines) {}
typename VD::segment_type operator[](size_t idx) const {
return typename VD::segment_type(
- typename VD::point_type(typename VD::coord_type(lines[idx].a.x), typename VD::coord_type(lines[idx].a.y)),
- typename VD::point_type(typename VD::coord_type(lines[idx].b.x), typename VD::coord_type(lines[idx].b.y)));
+ typename VD::point_type(typename VD::coord_type(lines[idx].a(0)), typename VD::coord_type(lines[idx].a(1))),
+ typename VD::point_type(typename VD::coord_type(lines[idx].b(0)), typename VD::coord_type(lines[idx].b(1))));
}
private:
const Lines &lines;
@@ -925,7 +973,7 @@ MedialAxis::build(ThickPolylines* polylines)
assert(polyline.width.size() == polyline.points.size()*2 - 2);
// prevent loop endpoints from being extended
- if (polyline.first_point().coincides_with(polyline.last_point())) {
+ if (polyline.first_point() == polyline.last_point()) {
polyline.endpoints.first = false;
polyline.endpoints.second = false;
}
@@ -1018,7 +1066,7 @@ MedialAxis::validate_edge(const VD::edge_type* edge)
// this could maybe be optimized (checking inclusion of the endpoints
// might give false positives as they might belong to the contour itself)
if (this->expolygon != NULL) {
- if (line.a.coincides_with(line.b)) {
+ if (line.a == line.b) {
// in this case, contains(line) returns a false positive
if (!this->expolygon->contains(line.a)) return false;
} else {
@@ -1057,12 +1105,12 @@ MedialAxis::validate_edge(const VD::edge_type* edge)
calculate the distance to that endpoint instead. */
coordf_t w0 = cell_r->contains_segment()
- ? line.a.distance_to(segment_r)*2
- : line.a.distance_to(this->retrieve_endpoint(cell_r))*2;
+ ? segment_r.distance_to(line.a)*2
+ : (this->retrieve_endpoint(cell_r) - line.a).cast<double>().norm()*2;
coordf_t w1 = cell_l->contains_segment()
- ? line.b.distance_to(segment_l)*2
- : line.b.distance_to(this->retrieve_endpoint(cell_l))*2;
+ ? segment_l.distance_to(line.b)*2
+ : (this->retrieve_endpoint(cell_l) - line.b).cast<double>().norm()*2;
if (cell_l->contains_segment() && cell_r->contains_segment()) {
// calculate the relative angle between the two boundary segments
diff --git a/xs/src/libslic3r/Geometry.hpp b/xs/src/libslic3r/Geometry.hpp
index 956ef82aa..3698b996f 100644
--- a/xs/src/libslic3r/Geometry.hpp
+++ b/xs/src/libslic3r/Geometry.hpp
@@ -30,9 +30,9 @@ enum Orientation
static inline Orientation orient(const Point &a, const Point &b, const Point &c)
{
// BOOST_STATIC_ASSERT(sizeof(coord_t) * 2 == sizeof(int64_t));
- int64_t u = int64_t(b.x) * int64_t(c.y) - int64_t(b.y) * int64_t(c.x);
- int64_t v = int64_t(a.x) * int64_t(c.y) - int64_t(a.y) * int64_t(c.x);
- int64_t w = int64_t(a.x) * int64_t(b.y) - int64_t(a.y) * int64_t(b.x);
+ int64_t u = int64_t(b(0)) * int64_t(c(1)) - int64_t(b(1)) * int64_t(c(0));
+ int64_t v = int64_t(a(0)) * int64_t(c(1)) - int64_t(a(1)) * int64_t(c(0));
+ int64_t w = int64_t(a(0)) * int64_t(b(1)) - int64_t(a(1)) * int64_t(b(0));
int64_t d = u - v + w;
return (d > 0) ? ORIENTATION_CCW : ((d == 0) ? ORIENTATION_COLINEAR : ORIENTATION_CW);
}
@@ -52,7 +52,7 @@ static inline bool is_ccw(const Polygon &poly)
for (unsigned int i = 1; i < poly.points.size(); ++ i) {
const Point &pmin = poly.points[imin];
const Point &p = poly.points[i];
- if (p.x < pmin.x || (p.x == pmin.x && p.y < pmin.y))
+ if (p(0) < pmin(0) || (p(0) == pmin(0) && p(1) < pmin(1)))
imin = i;
}
@@ -66,26 +66,26 @@ static inline bool is_ccw(const Polygon &poly)
return o == ORIENTATION_CCW;
}
-inline bool ray_ray_intersection(const Pointf &p1, const Vectorf &v1, const Pointf &p2, const Vectorf &v2, Pointf &res)
+inline bool ray_ray_intersection(const Vec2d &p1, const Vec2d &v1, const Vec2d &p2, const Vec2d &v2, Vec2d &res)
{
- double denom = v1.x * v2.y - v2.x * v1.y;
+ double denom = v1(0) * v2(1) - v2(0) * v1(1);
if (std::abs(denom) < EPSILON)
return false;
- double t = (v2.x * (p1.y - p2.y) - v2.y * (p1.x - p2.x)) / denom;
- res.x = p1.x + t * v1.x;
- res.y = p1.y + t * v1.y;
+ double t = (v2(0) * (p1(1) - p2(1)) - v2(1) * (p1(0) - p2(0))) / denom;
+ res(0) = p1(0) + t * v1(0);
+ res(1) = p1(1) + t * v1(1);
return true;
}
-inline bool segment_segment_intersection(const Pointf &p1, const Vectorf &v1, const Pointf &p2, const Vectorf &v2, Pointf &res)
+inline bool segment_segment_intersection(const Vec2d &p1, const Vec2d &v1, const Vec2d &p2, const Vec2d &v2, Vec2d &res)
{
- double denom = v1.x * v2.y - v2.x * v1.y;
+ double denom = v1(0) * v2(1) - v2(0) * v1(1);
if (std::abs(denom) < EPSILON)
// Lines are collinear.
return false;
- double s12_x = p1.x - p2.x;
- double s12_y = p1.y - p2.y;
- double s_numer = v1.x * s12_y - v1.y * s12_x;
+ double s12_x = p1(0) - p2(0);
+ double s12_y = p1(1) - p2(1);
+ double s_numer = v1(0) * s12_y - v1(1) * s12_x;
bool denom_is_positive = false;
if (denom < 0.) {
denom_is_positive = true;
@@ -95,7 +95,7 @@ inline bool segment_segment_intersection(const Pointf &p1, const Vectorf &v1, co
if (s_numer < 0.)
// Intersection outside of the 1st segment.
return false;
- double t_numer = v2.x * s12_y - v2.y * s12_x;
+ double t_numer = v2(0) * s12_y - v2(1) * s12_x;
if (! denom_is_positive)
t_numer = - t_numer;
if (t_numer < 0. || s_numer > denom || t_numer > denom)
@@ -103,8 +103,8 @@ inline bool segment_segment_intersection(const Pointf &p1, const Vectorf &v1, co
return false;
// Intersection inside both of the segments.
double t = t_numer / denom;
- res.x = p1.x + t * v1.x;
- res.y = p1.y + t * v1.y;
+ res(0) = p1(0) + t * v1(0);
+ res(1) = p1(1) + t * v1(1);
return true;
}
@@ -125,7 +125,7 @@ void simplify_polygons(const Polygons &polygons, double tolerance, Polygons* ret
double linint(double value, double oldmin, double oldmax, double newmin, double newmax);
bool arrange(
// input
- size_t num_parts, const Pointf &part_size, coordf_t gap, const BoundingBoxf* bed_bounding_box,
+ size_t num_parts, const Vec2d &part_size, coordf_t gap, const BoundingBoxf* bed_bounding_box,
// output
Pointfs &positions);
diff --git a/xs/src/libslic3r/Layer.cpp b/xs/src/libslic3r/Layer.cpp
index 652bcdaa0..20e8f8ae1 100644
--- a/xs/src/libslic3r/Layer.cpp
+++ b/xs/src/libslic3r/Layer.cpp
@@ -168,8 +168,8 @@ void Layer::export_region_slices_to_svg(const char *path) const
for (Surfaces::const_iterator surface = (*region)->slices.surfaces.begin(); surface != (*region)->slices.surfaces.end(); ++surface)
bbox.merge(get_extents(surface->expolygon));
Point legend_size = export_surface_type_legend_to_svg_box_size();
- Point legend_pos(bbox.min.x, bbox.max.y);
- bbox.merge(Point(std::max(bbox.min.x + legend_size.x, bbox.max.x), bbox.max.y + legend_size.y));
+ Point legend_pos(bbox.min(0), bbox.max(1));
+ bbox.merge(Point(std::max(bbox.min(0) + legend_size(0), bbox.max(0)), bbox.max(1) + legend_size(1)));
SVG svg(path, bbox);
const float transparency = 0.5f;
@@ -194,8 +194,8 @@ void Layer::export_region_fill_surfaces_to_svg(const char *path) const
for (Surfaces::const_iterator surface = (*region)->fill_surfaces.surfaces.begin(); surface != (*region)->fill_surfaces.surfaces.end(); ++surface)
bbox.merge(get_extents(surface->expolygon));
Point legend_size = export_surface_type_legend_to_svg_box_size();
- Point legend_pos(bbox.min.x, bbox.max.y);
- bbox.merge(Point(std::max(bbox.min.x + legend_size.x, bbox.max.x), bbox.max.y + legend_size.y));
+ Point legend_pos(bbox.min(0), bbox.max(1));
+ bbox.merge(Point(std::max(bbox.min(0) + legend_size(0), bbox.max(0)), bbox.max(1) + legend_size(1)));
SVG svg(path, bbox);
const float transparency = 0.5f;
diff --git a/xs/src/libslic3r/LayerRegion.cpp b/xs/src/libslic3r/LayerRegion.cpp
index 68e17407e..afdc9c5a2 100644
--- a/xs/src/libslic3r/LayerRegion.cpp
+++ b/xs/src/libslic3r/LayerRegion.cpp
@@ -395,8 +395,8 @@ void LayerRegion::export_region_slices_to_svg(const char *path) const
for (Surfaces::const_iterator surface = this->slices.surfaces.begin(); surface != this->slices.surfaces.end(); ++surface)
bbox.merge(get_extents(surface->expolygon));
Point legend_size = export_surface_type_legend_to_svg_box_size();
- Point legend_pos(bbox.min.x, bbox.max.y);
- bbox.merge(Point(std::max(bbox.min.x + legend_size.x, bbox.max.x), bbox.max.y + legend_size.y));
+ Point legend_pos(bbox.min(0), bbox.max(1));
+ bbox.merge(Point(std::max(bbox.min(0) + legend_size(0), bbox.max(0)), bbox.max(1) + legend_size(1)));
SVG svg(path, bbox);
const float transparency = 0.5f;
@@ -422,8 +422,8 @@ void LayerRegion::export_region_fill_surfaces_to_svg(const char *path) const
for (Surfaces::const_iterator surface = this->fill_surfaces.surfaces.begin(); surface != this->fill_surfaces.surfaces.end(); ++surface)
bbox.merge(get_extents(surface->expolygon));
Point legend_size = export_surface_type_legend_to_svg_box_size();
- Point legend_pos(bbox.min.x, bbox.max.y);
- bbox.merge(Point(std::max(bbox.min.x + legend_size.x, bbox.max.x), bbox.max.y + legend_size.y));
+ Point legend_pos(bbox.min(0), bbox.max(1));
+ bbox.merge(Point(std::max(bbox.min(0) + legend_size(0), bbox.max(0)), bbox.max(1) + legend_size(1)));
SVG svg(path, bbox);
const float transparency = 0.5f;
diff --git a/xs/src/libslic3r/Line.cpp b/xs/src/libslic3r/Line.cpp
index e9d5d7742..a29e4ce4e 100644
--- a/xs/src/libslic3r/Line.cpp
+++ b/xs/src/libslic3r/Line.cpp
@@ -7,133 +7,58 @@
namespace Slic3r {
-std::string
-Line::wkt() const
-{
- std::ostringstream ss;
- ss << "LINESTRING(" << this->a.x << " " << this->a.y << ","
- << this->b.x << " " << this->b.y << ")";
- return ss.str();
-}
-
-Line::operator Lines() const
-{
- Lines lines;
- lines.push_back(*this);
- return lines;
-}
-
-Line::operator Polyline() const
-{
- Polyline pl;
- pl.points.push_back(this->a);
- pl.points.push_back(this->b);
- return pl;
-}
-
-void
-Line::scale(double factor)
-{
- this->a.scale(factor);
- this->b.scale(factor);
-}
-
-void
-Line::translate(double x, double y)
-{
- this->a.translate(x, y);
- this->b.translate(x, y);
-}
-
-void
-Line::rotate(double angle, const Point &center)
-{
- this->a.rotate(angle, center);
- this->b.rotate(angle, center);
-}
-
-void
-Line::reverse()
-{
- std::swap(this->a, this->b);
-}
-
-double
-Line::length() const
-{
- return this->a.distance_to(this->b);
-}
-
-Point
-Line::midpoint() const
-{
- return Point((this->a.x + this->b.x) / 2.0, (this->a.y + this->b.y) / 2.0);
-}
-
-void
-Line::point_at(double distance, Point* point) const
-{
- double len = this->length();
- *point = this->a;
- if (this->a.x != this->b.x)
- point->x = this->a.x + (this->b.x - this->a.x) * distance / len;
- if (this->a.y != this->b.y)
- point->y = this->a.y + (this->b.y - this->a.y) * distance / len;
-}
-
-Point
-Line::point_at(double distance) const
-{
- Point p;
- this->point_at(distance, &p);
- return p;
-}
-
-bool
-Line::intersection_infinite(const Line &other, Point* point) const
-{
- Vector x = this->a.vector_to(other.a);
- Vector d1 = this->vector();
- Vector d2 = other.vector();
-
- double cross = d1.x * d2.y - d1.y * d2.x;
- if (std::fabs(cross) < EPSILON)
+bool Line::intersection_infinite(const Line &other, Point* point) const
+{
+ Vec2d a1 = this->a.cast<double>();
+ Vec2d a2 = other.a.cast<double>();
+ Vec2d v12 = (other.a - this->a).cast<double>();
+ Vec2d v1 = (this->b - this->a).cast<double>();
+ Vec2d v2 = (other.b - other.a).cast<double>();
+ double denom = cross2(v1, v2);
+ if (std::fabs(denom) < EPSILON)
return false;
-
- double t1 = (x.x * d2.y - x.y * d2.x)/cross;
- point->x = this->a.x + d1.x * t1;
- point->y = this->a.y + d1.y * t1;
+ double t1 = cross2(v12, v2) / denom;
+ *point = (a1 + t1 * v1).cast<coord_t>();
return true;
}
-bool
-Line::coincides_with(const Line &line) const
+/* distance to the closest point of line */
+double Line::distance_to(const Point &point) const
{
- return this->a.coincides_with(line.a) && this->b.coincides_with(line.b);
+ const Line &line = *this;
+ const Vec2d v = (line.b - line.a).cast<double>();
+ const Vec2d va = (point - line.a).cast<double>();
+ const double l2 = v.squaredNorm(); // avoid a sqrt
+ if (l2 == 0.0)
+ // line.a == line.b case
+ return va.norm();
+ // Consider the line extending the segment, parameterized as line.a + t (line.b - line.a).
+ // We find projection of this point onto the line.
+ // It falls where t = [(this-line.a) . (line.b-line.a)] / |line.b-line.a|^2
+ const double t = va.dot(v) / l2;
+ if (t < 0.0) return va.norm(); // beyond the 'a' end of the segment
+ else if (t > 1.0) return (point - line.b).cast<double>().norm(); // beyond the 'b' end of the segment
+ return (t * v - va).norm();
}
-double
-Line::distance_to(const Point &point) const
+double Line::perp_distance_to(const Point &point) const
{
- return point.distance_to(*this);
+ const Line &line = *this;
+ const Vec2d v = (line.b - line.a).cast<double>();
+ const Vec2d va = (point - line.a).cast<double>();
+ if (line.a == line.b)
+ return va.norm();
+ return std::abs(cross2(v, va)) / v.norm();
}
-double
-Line::atan2_() const
-{
- return atan2(this->b.y - this->a.y, this->b.x - this->a.x);
-}
-
-double
-Line::orientation() const
+double Line::orientation() const
{
double angle = this->atan2_();
if (angle < 0) angle = 2*PI + angle;
return angle;
}
-double
-Line::direction() const
+double Line::direction() const
{
double atan2 = this->atan2_();
return (fabs(atan2 - PI) < EPSILON) ? 0
@@ -141,108 +66,42 @@ Line::direction() const
: atan2;
}
-bool
-Line::parallel_to(double angle) const {
- return Slic3r::Geometry::directions_parallel(this->direction(), angle);
-}
-
-bool
-Line::parallel_to(const Line &line) const {
- return this->parallel_to(line.direction());
-}
-
-Vector
-Line::vector() const
-{
- return Vector(this->b.x - this->a.x, this->b.y - this->a.y);
-}
-
-Vector
-Line::normal() const
+bool Line::parallel_to(double angle) const
{
- return Vector((this->b.y - this->a.y), -(this->b.x - this->a.x));
-}
-
-void
-Line::extend_end(double distance)
-{
- // relocate last point by extending the segment by the specified length
- Line line = *this;
- line.reverse();
- this->b = line.point_at(-distance);
-}
-
-void
-Line::extend_start(double distance)
-{
- // relocate first point by extending the first segment by the specified length
- this->a = this->point_at(-distance);
+ return Slic3r::Geometry::directions_parallel(this->direction(), angle);
}
-bool
-Line::intersection(const Line& line, Point* intersection) const
-{
- double denom = ((double)(line.b.y - line.a.y)*(this->b.x - this->a.x)) -
- ((double)(line.b.x - line.a.x)*(this->b.y - this->a.y));
-
- double nume_a = ((double)(line.b.x - line.a.x)*(this->a.y - line.a.y)) -
- ((double)(line.b.y - line.a.y)*(this->a.x - line.a.x));
-
- double nume_b = ((double)(this->b.x - this->a.x)*(this->a.y - line.a.y)) -
- ((double)(this->b.y - this->a.y)*(this->a.x - line.a.x));
-
- if (fabs(denom) < EPSILON) {
- if (fabs(nume_a) < EPSILON && fabs(nume_b) < EPSILON) {
- return false; // coincident
- }
- return false; // parallel
- }
-
- double ua = nume_a / denom;
- double ub = nume_b / denom;
-
- if (ua >= 0 && ua <= 1.0f && ub >= 0 && ub <= 1.0f)
- {
+bool Line::intersection(const Line &l2, Point *intersection) const
+{
+ const Line &l1 = *this;
+ const Vec2d v1 = (l1.b - l1.a).cast<double>();
+ const Vec2d v2 = (l2.b - l2.a).cast<double>();
+ const Vec2d v12 = (l1.a - l2.a).cast<double>();
+ double denom = cross2(v1, v2);
+ double nume_a = cross2(v2, v12);
+ double nume_b = cross2(v1, v12);
+ if (fabs(denom) < EPSILON)
+#if 0
+ // Lines are collinear. Return true if they are coincident (overlappign).
+ return ! (fabs(nume_a) < EPSILON && fabs(nume_b) < EPSILON);
+#else
+ return false;
+#endif
+ double t1 = nume_a / denom;
+ double t2 = nume_b / denom;
+ if (t1 >= 0 && t1 <= 1.0f && t2 >= 0 && t2 <= 1.0f) {
// Get the intersection point.
- intersection->x = this->a.x + ua*(this->b.x - this->a.x);
- intersection->y = this->a.y + ua*(this->b.y - this->a.y);
+ (*intersection) = (l1.a.cast<double>() + t1 * v1).cast<coord_t>();
return true;
}
-
return false; // not intersecting
}
-double
-Line::ccw(const Point& point) const
-{
- return point.ccw(*this);
-}
-
-double Line3::length() const
-{
- return a.distance_to(b);
-}
-
-Vector3 Line3::vector() const
-{
- return Vector3(b.x - a.x, b.y - a.y, b.z - a.z);
-}
-
-Pointf3
-Linef3::intersect_plane(double z) const
-{
- return Pointf3(
- this->a.x + (this->b.x - this->a.x) * (z - this->a.z) / (this->b.z - this->a.z),
- this->a.y + (this->b.y - this->a.y) * (z - this->a.z) / (this->b.z - this->a.z),
- z
- );
-}
-
-void
-Linef3::scale(double factor)
+Vec3d Linef3::intersect_plane(double z) const
{
- this->a.scale(factor);
- this->b.scale(factor);
+ auto v = (this->b - this->a).cast<double>();
+ double t = (z - this->a(2)) / v(2);
+ return Vec3d(this->a(0) + v(0) * t, this->a(1) + v(1) * t, z);
}
}
diff --git a/xs/src/libslic3r/Line.hpp b/xs/src/libslic3r/Line.hpp
index 4826017ab..5b77a4b61 100644
--- a/xs/src/libslic3r/Line.hpp
+++ b/xs/src/libslic3r/Line.hpp
@@ -18,77 +18,80 @@ typedef std::vector<ThickLine> ThickLines;
class Line
{
public:
- Point a;
- Point b;
- Line() {};
- explicit Line(Point _a, Point _b): a(_a), b(_b) {};
- std::string wkt() const;
- operator Lines() const;
- operator Polyline() const;
- void scale(double factor);
- void translate(double x, double y);
- void rotate(double angle, const Point &center);
- void reverse();
- double length() const;
- Point midpoint() const;
- void point_at(double distance, Point* point) const;
- Point point_at(double distance) const;
- bool intersection_infinite(const Line &other, Point* point) const;
- bool coincides_with(const Line &line) const;
+ Line() {}
+ Line(const Point& _a, const Point& _b) : a(_a), b(_b) {}
+ explicit operator Lines() const { Lines lines; lines.emplace_back(*this); return lines; }
+ void scale(double factor) { this->a *= factor; this->b *= factor; }
+ void translate(double x, double y) { Vector v(x, y); this->a += v; this->b += v; }
+ void rotate(double angle, const Point &center) { this->a.rotate(angle, center); this->b.rotate(angle, center); }
+ void reverse() { std::swap(this->a, this->b); }
+ double length() const { return (b - a).cast<double>().norm(); }
+ Point midpoint() const { return (this->a + this->b) / 2; }
+ bool intersection_infinite(const Line &other, Point* point) const;
+ bool operator==(const Line &rhs) const { return this->a == rhs.a && this->b == rhs.b; }
double distance_to(const Point &point) const;
- bool parallel_to(double angle) const;
- bool parallel_to(const Line &line) const;
- double atan2_() const;
+ double perp_distance_to(const Point &point) const;
+ bool parallel_to(double angle) const;
+ bool parallel_to(const Line &line) const { return this->parallel_to(line.direction()); }
+ double atan2_() const { return atan2(this->b(1) - this->a(1), this->b(0) - this->a(0)); }
double orientation() const;
double direction() const;
- Vector vector() const;
- Vector normal() const;
- void extend_end(double distance);
- void extend_start(double distance);
- bool intersection(const Line& line, Point* intersection) const;
- double ccw(const Point& point) const;
+ Vector vector() const { return this->b - this->a; }
+ Vector normal() const { return Vector((this->b(1) - this->a(1)), -(this->b(0) - this->a(0))); }
+ bool intersection(const Line& line, Point* intersection) const;
+ double ccw(const Point& point) const { return point.ccw(*this); }
+
+ Point a;
+ Point b;
};
class ThickLine : public Line
{
- public:
- coordf_t a_width, b_width;
-
- ThickLine() : a_width(0), b_width(0) {};
- ThickLine(Point _a, Point _b) : Line(_a, _b), a_width(0), b_width(0) {};
+public:
+ ThickLine() : a_width(0), b_width(0) {}
+ ThickLine(const Point& a, const Point& b) : Line(a, b), a_width(0), b_width(0) {}
+ ThickLine(const Point& a, const Point& b, double wa, double wb) : Line(a, b), a_width(wa), b_width(wb) {}
+
+ double a_width, b_width;
};
class Line3
{
public:
- Point3 a;
- Point3 b;
+ Line3() : a(Vec3crd::Zero()), b(Vec3crd::Zero()) {}
+ Line3(const Vec3crd& _a, const Vec3crd& _b) : a(_a), b(_b) {}
- Line3() {}
- Line3(const Point3& _a, const Point3& _b) : a(_a), b(_b) {}
+ double length() const { return (this->a - this->b).cast<double>().norm(); }
+ Vec3crd vector() const { return this->b - this->a; }
- double length() const;
- Vector3 vector() const;
+ Vec3crd a;
+ Vec3crd b;
};
class Linef
{
- public:
- Pointf a;
- Pointf b;
- Linef() {};
- explicit Linef(Pointf _a, Pointf _b): a(_a), b(_b) {};
+public:
+ Linef() : a(Vec2d::Zero()), b(Vec2d::Zero()) {}
+ Linef(const Vec2d& _a, const Vec2d& _b) : a(_a), b(_b) {}
+
+ Vec2d a;
+ Vec2d b;
};
class Linef3
{
- public:
- Pointf3 a;
- Pointf3 b;
- Linef3() {};
- explicit Linef3(Pointf3 _a, Pointf3 _b): a(_a), b(_b) {};
- Pointf3 intersect_plane(double z) const;
- void scale(double factor);
+public:
+ Linef3() : a(Vec3d::Zero()), b(Vec3d::Zero()) {}
+ Linef3(const Vec3d& _a, const Vec3d& _b) : a(_a), b(_b) {}
+
+ Vec3d intersect_plane(double z) const;
+ void scale(double factor) { this->a *= factor; this->b *= factor; }
+ Vec3d vector() const { return this->b - this->a; }
+ Vec3d unit_vector() const { return (length() == 0.0) ? Vec3d::Zero() : vector().normalized(); }
+ double length() const { return vector().norm(); }
+
+ Vec3d a;
+ Vec3d b;
};
} // namespace Slic3r
diff --git a/xs/src/libslic3r/Model.cpp b/xs/src/libslic3r/Model.cpp
index 09b515c2f..f723ca856 100644
--- a/xs/src/libslic3r/Model.cpp
+++ b/xs/src/libslic3r/Model.cpp
@@ -17,11 +17,6 @@
#include "SVG.hpp"
#include <Eigen/Dense>
-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 {
unsigned int Model::s_auto_extruder_id = 1;
@@ -240,7 +235,7 @@ BoundingBoxf3 Model::bounding_box() const
return bb;
}
-void Model::center_instances_around_point(const Pointf &point)
+void Model::center_instances_around_point(const Vec2d &point)
{
// BoundingBoxf3 bb = this->bounding_box();
BoundingBoxf3 bb;
@@ -248,12 +243,10 @@ void Model::center_instances_around_point(const Pointf &point)
for (size_t i = 0; i < o->instances.size(); ++ i)
bb.merge(o->instance_bounding_box(i, false));
- Sizef3 size = bb.size();
- coordf_t shift_x = -bb.min.x + point.x - size.x/2;
- coordf_t shift_y = -bb.min.y + point.y - size.y/2;
+ Vec2d shift = point - 0.5 * to_2d(bb.size()) - to_2d(bb.min);
for (ModelObject *o : this->objects) {
for (ModelInstance *i : o->instances)
- i->offset.translate(shift_x, shift_y);
+ i->offset += shift;
o->invalidate_bounding_box();
}
}
@@ -308,8 +301,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.emplace_back(to_2d(bbox.size()));
+ instance_centers.emplace_back(to_2d(bbox.center()));
}
Pointfs positions;
@@ -331,7 +324,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, to_2d(this->bounding_box().size()));
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");
@@ -342,9 +335,9 @@ void Model::duplicate(size_t copies_num, coordf_t dist, const BoundingBoxf* bb)
// make a copy of the pointers in order to avoid recursion when appending their copies
ModelInstancePtrs instances = o->instances;
for (const ModelInstance *i : instances) {
- for (const Pointf &pos : positions) {
+ for (const Vec2d &pos : positions) {
ModelInstance *instance = o->add_instance(*i);
- instance->offset.translate(pos);
+ instance->offset += pos;
}
}
o->invalidate_bounding_box();
@@ -374,13 +367,13 @@ void Model::duplicate_objects_grid(size_t x, size_t y, coordf_t dist)
ModelObject* object = this->objects.front();
object->clear_instances();
- Sizef3 size = object->bounding_box().size();
+ Vec3d size = object->bounding_box().size();
for (size_t x_copy = 1; x_copy <= x; ++x_copy) {
for (size_t y_copy = 1; y_copy <= y; ++y_copy) {
ModelInstance* instance = object->add_instance();
- instance->offset.x = (size.x + dist) * (x_copy-1);
- instance->offset.y = (size.y + dist) * (y_copy-1);
+ instance->offset(0) = (size(0) + dist) * (x_copy-1);
+ instance->offset(1) = (size(1) + dist) * (y_copy-1);
}
}
}
@@ -394,7 +387,7 @@ bool Model::looks_like_multipart_object() const
if (obj->volumes.size() > 1 || obj->config.keys().size() > 1)
return false;
for (const ModelVolume *vol : obj->volumes) {
- double zmin_this = vol->mesh.bounding_box().min.z;
+ double zmin_this = vol->mesh.bounding_box().min(2);
if (zmin == std::numeric_limits<double>::max())
zmin = zmin_this;
else if (std::abs(zmin - zmin_this) > EPSILON)
@@ -438,13 +431,13 @@ void Model::adjust_min_z()
if (objects.empty())
return;
- if (bounding_box().min.z < 0.0)
+ if (bounding_box().min(2) < 0.0)
{
for (ModelObject* obj : objects)
{
if (obj != nullptr)
{
- coordf_t obj_min_z = obj->bounding_box().min.z;
+ coordf_t obj_min_z = obj->bounding_box().min(2);
if (obj_min_z < 0.0)
obj->translate(0.0, 0.0, -obj_min_z);
}
@@ -677,25 +670,22 @@ void ModelObject::center_around_origin()
if (! v->modifier)
bb.merge(v->mesh.bounding_box());
- // first align to origin on XYZ
- Vectorf3 vector(-bb.min.x, -bb.min.y, -bb.min.z);
-
- // then center it on XY
- Sizef3 size = bb.size();
- vector.x -= size.x/2;
- vector.y -= size.y/2;
+ // First align to origin on XYZ, then center it on XY.
+ Vec3d size = bb.size();
+ size(2) = 0.;
+ Vec3d shift3 = - bb.min - 0.5 * size;
+ // Unaligned vector, for the Rotation2D to work on Visual Studio 2013.
+ Eigen::Vector2d shift2 = to_2d(shift3);
- this->translate(vector);
- this->origin_translation.translate(vector);
+ this->translate(shift3);
+ this->origin_translation += shift3;
if (!this->instances.empty()) {
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();
- v.rotate(i->rotation);
- v.scale(i->scaling_factor);
- i->offset.translate(v.x, v.y);
+ Eigen::Rotation2Dd rot(i->rotation);
+ i->offset -= rot * shift2 * i->scaling_factor;
}
this->invalidate_bounding_box();
}
@@ -713,7 +703,7 @@ void ModelObject::translate(coordf_t x, coordf_t y, coordf_t z)
m_bounding_box.translate(x, y, z);
}
-void ModelObject::scale(const Pointf3 &versor)
+void ModelObject::scale(const Vec3d &versor)
{
for (ModelVolume *v : this->volumes)
{
@@ -721,11 +711,25 @@ void ModelObject::scale(const Pointf3 &versor)
v->m_convex_hull.scale(versor);
}
// reset origin translation since it doesn't make sense anymore
- this->origin_translation = Pointf3(0,0,0);
+ this->origin_translation = Vec3d::Zero();
+ this->invalidate_bounding_box();
+}
+
+void ModelObject::rotate(float angle, const Axis& axis)
+{
+ for (ModelVolume *v : this->volumes)
+ {
+ v->mesh.rotate(angle, axis);
+ v->m_convex_hull.rotate(angle, axis);
+ }
+
+ center_around_origin();
+
+ this->origin_translation = Vec3d::Zero();
this->invalidate_bounding_box();
}
-void ModelObject::rotate(float angle, const Pointf3& axis)
+void ModelObject::rotate(float angle, const Vec3d& axis)
{
for (ModelVolume *v : this->volumes)
{
@@ -735,7 +739,7 @@ void ModelObject::rotate(float angle, const Pointf3& axis)
center_around_origin();
- this->origin_translation = Pointf3(0, 0, 0);
+ this->origin_translation = Vec3d::Zero();
this->invalidate_bounding_box();
}
@@ -750,8 +754,8 @@ void ModelObject::transform(const float* matrix3x4)
v->m_convex_hull.transform(matrix3x4);
}
- origin_translation = Pointf3(0.0, 0.0, 0.0);
- invalidate_bounding_box();
+ this->origin_translation = Vec3d::Zero();
+ this->invalidate_bounding_box();
}
void ModelObject::mirror(const Axis &axis)
@@ -762,7 +766,7 @@ void ModelObject::mirror(const Axis &axis)
v->m_convex_hull.mirror(axis);
}
- this->origin_translation = Pointf3(0, 0, 0);
+ this->origin_translation = Vec3d::Zero();
this->invalidate_bounding_box();
}
@@ -872,14 +876,12 @@ void ModelObject::check_instances_print_volume_state(const BoundingBoxf3& print_
{
for (ModelInstance* inst : this->instances)
{
- std::vector<float> world_mat(UNIT_MATRIX, std::end(UNIT_MATRIX));
- Eigen::Transform<float, 3, Eigen::Affine> m = Eigen::Transform<float, 3, Eigen::Affine>::Identity();
- m.translate(Eigen::Vector3f((float)inst->offset.x, (float)inst->offset.y, 0.0f));
- m.rotate(Eigen::AngleAxisf(inst->rotation, Eigen::Vector3f::UnitZ()));
+ Transform3d m = Transform3d::Identity();
+ m.translate(Vec3d(inst->offset(0), inst->offset(1), 0.0));
+ m.rotate(Eigen::AngleAxisd(inst->rotation, Vec3d::UnitZ()));
m.scale(inst->scaling_factor);
- ::memcpy((void*)world_mat.data(), (const void*)m.data(), 16 * sizeof(float));
- BoundingBoxf3 bb = vol->get_convex_hull().transformed_bounding_box(world_mat);
+ BoundingBoxf3 bb = vol->get_convex_hull().transformed_bounding_box(m);
if (print_volume.contains(bb))
inst->print_volume_state = ModelInstance::PVS_Inside;
@@ -901,16 +903,16 @@ void ModelObject::print_info() const
TriangleMesh mesh = this->raw_mesh();
mesh.check_topology();
BoundingBoxf3 bb = mesh.bounding_box();
- Sizef3 size = bb.size();
- cout << "size_x = " << size.x << endl;
- cout << "size_y = " << size.y << endl;
- cout << "size_z = " << size.z << endl;
- cout << "min_x = " << bb.min.x << endl;
- cout << "min_y = " << bb.min.y << endl;
- cout << "min_z = " << bb.min.z << endl;
- cout << "max_x = " << bb.max.x << endl;
- cout << "max_y = " << bb.max.y << endl;
- cout << "max_z = " << bb.max.z << endl;
+ Vec3d size = bb.size();
+ cout << "size_x = " << size(0) << endl;
+ cout << "size_y = " << size(1) << endl;
+ cout << "size_z = " << size(2) << endl;
+ cout << "min_x = " << bb.min(0) << endl;
+ cout << "min_y = " << bb.min(1) << endl;
+ cout << "min_z = " << bb.min(2) << endl;
+ cout << "max_x = " << bb.max(0) << endl;
+ cout << "max_y = " << bb.max(1) << endl;
+ cout << "max_z = " << bb.max(2) << endl;
cout << "number_of_facets = " << mesh.stl.stats.number_of_facets << endl;
cout << "manifold = " << (mesh.is_manifold() ? "yes" : "no") << endl;
@@ -1011,7 +1013,7 @@ void ModelInstance::transform_mesh(TriangleMesh* mesh, bool dont_translate) cons
mesh->rotate_z(this->rotation); // rotate around mesh origin
mesh->scale(this->scaling_factor); // scale around mesh origin
if (!dont_translate)
- mesh->translate(this->offset.x, this->offset.y, 0);
+ mesh->translate(this->offset(0), this->offset(1), 0);
}
BoundingBoxf3 ModelInstance::transform_mesh_bounding_box(const TriangleMesh* mesh, bool dont_translate) const
@@ -1023,30 +1025,20 @@ BoundingBoxf3 ModelInstance::transform_mesh_bounding_box(const TriangleMesh* mes
for (int i = 0; i < mesh->stl.stats.number_of_facets; ++ i) {
const stl_facet &facet = mesh->stl.facet_start[i];
for (int j = 0; j < 3; ++ j) {
- stl_vertex v = facet.vertex[j];
- double xold = v.x;
- double yold = v.y;
- v.x = float(c * xold - s * yold);
- v.y = float(s * xold + c * yold);
- bbox.merge(Pointf3(v.x, v.y, v.z));
+ const stl_vertex &v = facet.vertex[j];
+ bbox.merge(Vec3d(c * v(0) - s * v(1), s * v(0) + c * v(1), v(2)));
}
}
if (! empty(bbox)) {
// Scale the bounding box uniformly.
if (std::abs(this->scaling_factor - 1.) > EPSILON) {
- bbox.min.x *= float(this->scaling_factor);
- bbox.min.y *= float(this->scaling_factor);
- bbox.min.z *= float(this->scaling_factor);
- bbox.max.x *= float(this->scaling_factor);
- bbox.max.y *= float(this->scaling_factor);
- bbox.max.z *= float(this->scaling_factor);
+ bbox.min *= this->scaling_factor;
+ bbox.max *= this->scaling_factor;
}
// Translate the bounding box.
if (! dont_translate) {
- bbox.min.x += float(this->offset.x);
- bbox.min.y += float(this->offset.y);
- bbox.max.x += float(this->offset.x);
- bbox.max.y += float(this->offset.y);
+ Eigen::Map<Vec2d>(bbox.min.data()) += this->offset;
+ Eigen::Map<Vec2d>(bbox.max.data()) += this->offset;
}
}
return bbox;
@@ -1054,16 +1046,13 @@ 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();
+ Transform3d matrix = Transform3d::Identity();
if (!dont_translate)
- matrix.translate(Eigen::Vector3f((float)offset.x, (float)offset.y, 0.0f));
+ matrix.translate(Vec3d(offset(0), offset(1), 0.0));
- matrix.rotate(Eigen::AngleAxisf(rotation, Eigen::Vector3f::UnitZ()));
+ matrix.rotate(Eigen::AngleAxisd(rotation, Vec3d::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
diff --git a/xs/src/libslic3r/Model.hpp b/xs/src/libslic3r/Model.hpp
index dadd515de..140a0270a 100644
--- a/xs/src/libslic3r/Model.hpp
+++ b/xs/src/libslic3r/Model.hpp
@@ -84,7 +84,7 @@ public:
center_around_origin() method. Callers might want to apply the same translation
to new volumes before adding them to this object in order to preserve alignment
when user expects that. */
- Pointf3 origin_translation;
+ Vec3d origin_translation;
Model* get_model() const { return m_model; };
@@ -117,11 +117,12 @@ public:
// A snug bounding box around the transformed non-modifier object volumes.
BoundingBoxf3 instance_bounding_box(size_t instance_idx, bool dont_translate = false) const;
void center_around_origin();
- void translate(const Vectorf3 &vector) { this->translate(vector.x, vector.y, vector.z); }
+ void translate(const Vec3d &vector) { this->translate(vector(0), vector(1), vector(2)); }
void translate(coordf_t x, coordf_t y, coordf_t z);
- void scale(const Pointf3 &versor);
- void rotate(float angle, const Pointf3& axis);
- void transform(const float* matrix3x4);
+ void scale(const Vec3d &versor);
+ void rotate(float angle, const Axis &axis);
+ void rotate(float angle, const Vec3d& axis);
+ void transform(const float* matrix3x4); // <<<<<<<<< FIXME (using eigen)
void mirror(const Axis &axis);
size_t materials_count() const;
size_t facets_count() const;
@@ -135,7 +136,7 @@ public:
void print_info() const;
private:
- ModelObject(Model *model) : layer_height_profile_valid(false), m_model(model), m_bounding_box_valid(false) {}
+ ModelObject(Model *model) : layer_height_profile_valid(false), m_model(model), origin_translation(Vec3d::Zero()), m_bounding_box_valid(false) {}
ModelObject(Model *model, const ModelObject &other, bool copy_volumes = true);
ModelObject& operator= (ModelObject other);
void swap(ModelObject &other);
@@ -224,9 +225,10 @@ public:
friend class ModelObject;
+// Transform3d transform;
double rotation; // Rotation around the Z axis, in radians around mesh center point
double scaling_factor;
- Pointf offset; // in unscaled coordinates
+ Vec2d offset; // in unscaled coordinates
// flag showing the position of this instance with respect to the print volume (set by Print::validate() using ModelObject::check_instances_print_volume_state())
EPrintVolumeState print_volume_state;
@@ -248,7 +250,7 @@ private:
// Parent object, owning this instance.
ModelObject* object;
- ModelInstance(ModelObject *object) : rotation(0), scaling_factor(1), object(object), print_volume_state(PVS_Inside) {}
+ ModelInstance(ModelObject *object) : rotation(0), scaling_factor(1), offset(Vec2d::Zero()), object(object), print_volume_state(PVS_Inside) {}
ModelInstance(ModelObject *object, const ModelInstance &other) :
rotation(other.rotation), scaling_factor(other.scaling_factor), offset(other.offset), object(object), print_volume_state(PVS_Inside) {}
};
@@ -299,7 +301,7 @@ public:
bool add_default_instances();
// Returns approximate axis aligned bounding box of this model
BoundingBoxf3 bounding_box() const;
- void center_instances_around_point(const Pointf &point);
+ void center_instances_around_point(const Vec2d &point);
void translate(coordf_t x, coordf_t y, coordf_t z) { for (ModelObject *o : this->objects) o->translate(x, y, z); }
TriangleMesh mesh() const;
bool arrange_objects(coordf_t dist, const BoundingBoxf* bb = NULL);
diff --git a/xs/src/libslic3r/ModelArrange.hpp b/xs/src/libslic3r/ModelArrange.hpp
index f2d399ac6..db18e6731 100644
--- a/xs/src/libslic3r/ModelArrange.hpp
+++ b/xs/src/libslic3r/ModelArrange.hpp
@@ -44,11 +44,11 @@ std::string toString(const Model& model, bool holes = true) {
ss << "\t\t{\n";
for(auto v : expoly.contour.points) ss << "\t\t\t{"
- << v.x << ", "
- << v.y << "},\n";
+ << v(0) << ", "
+ << v(1) << "},\n";
{
auto v = expoly.contour.points.front();
- ss << "\t\t\t{" << v.x << ", " << v.y << "},\n";
+ ss << "\t\t\t{" << v(0) << ", " << v(1) << "},\n";
}
ss << "\t\t},\n";
@@ -57,11 +57,11 @@ std::string toString(const Model& model, bool holes = true) {
if(holes) for(auto h : expoly.holes) {
ss << "\t\t\t{\n";
for(auto v : h.points) ss << "\t\t\t\t{"
- << v.x << ", "
- << v.y << "},\n";
+ << v(0) << ", "
+ << v(1) << "},\n";
{
auto v = h.points.front();
- ss << "\t\t\t\t{" << v.x << ", " << v.y << "},\n";
+ ss << "\t\t\t\t{" << v(0) << ", " << v(1) << "},\n";
}
ss << "\t\t\t},\n";
}
@@ -427,8 +427,8 @@ ShapeData2D projectModelFromTop(const Slic3r::Model &model) {
if(item.vertexCount() > 3) {
item.rotation(objinst->rotation);
item.translation( {
- ClipperLib::cInt(objinst->offset.x/SCALING_FACTOR),
- ClipperLib::cInt(objinst->offset.y/SCALING_FACTOR)
+ ClipperLib::cInt(objinst->offset(0)/SCALING_FACTOR),
+ ClipperLib::cInt(objinst->offset(1)/SCALING_FACTOR)
});
ret.emplace_back(objinst, item);
}
@@ -468,7 +468,7 @@ void applyResult(
// appropriately
auto off = item.translation();
Radians rot = item.rotation();
- Pointf foff(off.X*SCALING_FACTOR + batch_offset,
+ Vec2d foff(off.X*SCALING_FACTOR + batch_offset,
off.Y*SCALING_FACTOR);
// write the tranformation data into the model instance
@@ -528,12 +528,12 @@ bool arrange(Model &model, coordf_t min_obj_distance,
BoundingBox bbb(bed.points);
auto binbb = Box({
- static_cast<libnest2d::Coord>(bbb.min.x),
- static_cast<libnest2d::Coord>(bbb.min.y)
+ static_cast<libnest2d::Coord>(bbb.min(0)),
+ static_cast<libnest2d::Coord>(bbb.min(1))
},
{
- static_cast<libnest2d::Coord>(bbb.max.x),
- static_cast<libnest2d::Coord>(bbb.max.y)
+ static_cast<libnest2d::Coord>(bbb.max(0)),
+ static_cast<libnest2d::Coord>(bbb.max(1))
});
switch(bedhint) {
diff --git a/xs/src/libslic3r/MotionPlanner.cpp b/xs/src/libslic3r/MotionPlanner.cpp
index e8605d68c..ff3475ed8 100644
--- a/xs/src/libslic3r/MotionPlanner.cpp
+++ b/xs/src/libslic3r/MotionPlanner.cpp
@@ -58,7 +58,7 @@ Polyline MotionPlanner::shortest_path(const Point &from, const Point &to)
{
// If we have an empty configuration space, return a straight move.
if (m_islands.empty())
- return Line(from, to);
+ return Polyline(from, to);
// Are both points in the same island?
int island_idx_from = -1;
@@ -74,7 +74,7 @@ Polyline MotionPlanner::shortest_path(const Point &from, const Point &to)
// Since both points are in the same island, is a direct move possible?
// If so, we avoid generating the visibility environment.
if (island.m_island.contains(Line(from, to)))
- return Line(from, to);
+ return Polyline(from, to);
// Both points are inside a single island, but the straight line crosses the island boundary.
island_idx = idx;
break;
@@ -90,7 +90,7 @@ Polyline MotionPlanner::shortest_path(const Point &from, const Point &to)
if (env.m_env.expolygons.empty()) {
// if this environment is empty (probably because it's too small), perform straight move
// and avoid running the algorithms on empty dataset
- return Line(from, to);
+ return Polyline(from, to);
}
// Now check whether points are inside the environment.
@@ -224,7 +224,7 @@ const MotionPlannerGraph& MotionPlanner::init_graph(int island_idx)
else
v1_idx = i_v1->second;
// Euclidean distance is used as weight for the graph edge
- graph->add_edge(v0_idx, v1_idx, p0.distance_to(p1));
+ graph->add_edge(v0_idx, v1_idx, (p1 - p0).cast<double>().norm());
}
}
}
@@ -238,7 +238,7 @@ static inline size_t nearest_waypoint_index(const Point &start_point, const Poin
size_t idx = size_t(-1);
double dmin = std::numeric_limits<double>::infinity();
for (const Point &p : middle_points) {
- double d = start_point.distance_to(p) + p.distance_to(end_point);
+ double d = (p - start_point).cast<double>().norm() + (end_point - p).cast<double>().norm();
if (d < dmin) {
idx = &p - middle_points.data();
dmin = d;
diff --git a/xs/src/libslic3r/MultiPoint.cpp b/xs/src/libslic3r/MultiPoint.cpp
index 2e65492cd..f44897a04 100644
--- a/xs/src/libslic3r/MultiPoint.cpp
+++ b/xs/src/libslic3r/MultiPoint.cpp
@@ -8,59 +8,52 @@ 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 *= 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);
- }
+ Vector v(x, y);
+ for (Point &pt : points)
+ pt += v;
}
-void
-MultiPoint::translate(const Point &vector)
+void MultiPoint::translate(const Point &v)
{
- this->translate(vector.x, vector.y);
+ for (Point &pt : points)
+ pt += v;
}
void MultiPoint::rotate(double cos_angle, double sin_angle)
{
for (Point &pt : this->points) {
- double cur_x = double(pt.x);
- double cur_y = double(pt.y);
- pt.x = coord_t(round(cos_angle * cur_x - sin_angle * cur_y));
- pt.y = coord_t(round(cos_angle * cur_y + sin_angle * cur_x));
+ double cur_x = double(pt(0));
+ double cur_y = double(pt(1));
+ pt(0) = coord_t(round(cos_angle * cur_x - sin_angle * cur_y));
+ pt(1) = coord_t(round(cos_angle * cur_y + sin_angle * cur_x));
}
}
-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 v(pt - center);
+ pt(0) = (coord_t)round(double(center(0)) + c * v[0] - s * v[1]);
+ pt(1) = (coord_t)round(double(center(1)) + c * v[1] + s * v[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();
}
@@ -79,16 +72,16 @@ MultiPoint::length() const
int
MultiPoint::find_point(const Point &point) const
{
- for (Points::const_iterator it = this->points.begin(); it != this->points.end(); ++it) {
- if (it->coincides_with(point)) return it - this->points.begin();
- }
+ for (const Point &pt : this->points)
+ if (pt == point)
+ return &pt - &this->points.front();
return -1; // not found
}
bool
MultiPoint::has_boundary_point(const Point &point) const
{
- double dist = point.distance_to(point.projection_onto(*this));
+ double dist = (point.projection_onto(*this) - point).cast<double>().norm();
return dist < SCALED_EPSILON;
}
@@ -102,7 +95,7 @@ bool
MultiPoint::has_duplicate_points() const
{
for (size_t i = 1; i < points.size(); ++i)
- if (points[i-1].coincides_with(points[i]))
+ if (points[i-1] == points[i])
return true;
return false;
}
@@ -112,7 +105,7 @@ MultiPoint::remove_duplicate_points()
{
size_t j = 0;
for (size_t i = 1; i < points.size(); ++i) {
- if (points[j].coincides_with(points[i])) {
+ if (points[j] == points[i]) {
// Just increase index i.
} else {
++ j;
@@ -146,10 +139,10 @@ bool MultiPoint::first_intersection(const Line& line, Point* intersection) const
if (l.intersection(line, &ip)) {
if (! found) {
found = true;
- dmin = ip.distance_to(line.a);
+ dmin = (line.a - ip).cast<double>().norm();
*intersection = ip;
} else {
- double d = ip.distance_to(line.a);
+ double d = (line.a - ip).cast<double>().norm();
if (d < dmin) {
dmin = d;
*intersection = ip;
@@ -160,19 +153,6 @@ bool MultiPoint::first_intersection(const Line& line, Point* intersection) const
return found;
}
-std::string
-MultiPoint::dump_perl() const
-{
- std::ostringstream ret;
- ret << "[";
- for (Points::const_iterator p = this->points.begin(); p != this->points.end(); ++p) {
- ret << p->dump_perl();
- if (p != this->points.end()-1) ret << ",";
- }
- ret << "]";
- return ret.str();
-}
-
//FIXME This is very inefficient in term of memory use.
// The recursive algorithm shall run in place, not allocating temporary data in each recursion.
Points
@@ -185,7 +165,7 @@ MultiPoint::_douglas_peucker(const Points &points, const double tolerance)
Line full(points.front(), points.back());
for (Points::const_iterator it = points.begin() + 1; it != points.end(); ++it) {
// we use shortest distance, not perpendicular distance
- double d = it->distance_to(full);
+ double d = full.distance_to(*it);
if (d > dmax) {
index = it - points.begin();
dmax = d;
@@ -216,25 +196,22 @@ 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 (Vec3crd &p : points) {
+ p(0) += x;
+ p(1) += y;
}
}
void MultiPoint3::translate(const Point& vector)
{
- translate(vector.x, vector.y);
+ this->translate(vector(0), vector(1));
}
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;
}
@@ -246,15 +223,11 @@ BoundingBox3 MultiPoint3::bounding_box() const
bool MultiPoint3::remove_duplicate_points()
{
size_t j = 0;
- for (size_t i = 1; i < points.size(); ++i)
- {
- if (points[j].coincides_with(points[i]))
- {
+ for (size_t i = 1; i < points.size(); ++i) {
+ if (points[j] == points[i]) {
// Just increase index i.
- }
- else
- {
- ++j;
+ } else {
+ ++ j;
if (j < i)
points[j] = points[i];
}
@@ -281,19 +254,19 @@ BoundingBox get_extents_rotated(const Points &points, double angle)
double s = sin(angle);
double c = cos(angle);
Points::const_iterator it = points.begin();
- double cur_x = (double)it->x;
- double cur_y = (double)it->y;
- bbox.min.x = bbox.max.x = (coord_t)round(c * cur_x - s * cur_y);
- bbox.min.y = bbox.max.y = (coord_t)round(c * cur_y + s * cur_x);
+ double cur_x = (double)(*it)(0);
+ double cur_y = (double)(*it)(1);
+ bbox.min(0) = bbox.max(0) = (coord_t)round(c * cur_x - s * cur_y);
+ bbox.min(1) = bbox.max(1) = (coord_t)round(c * cur_y + s * cur_x);
for (++it; it != points.end(); ++it) {
- double cur_x = (double)it->x;
- double cur_y = (double)it->y;
+ double cur_x = (double)(*it)(0);
+ double cur_y = (double)(*it)(1);
coord_t x = (coord_t)round(c * cur_x - s * cur_y);
coord_t y = (coord_t)round(c * cur_y + s * cur_x);
- bbox.min.x = std::min(x, bbox.min.x);
- bbox.min.y = std::min(y, bbox.min.y);
- bbox.max.x = std::max(x, bbox.max.x);
- bbox.max.y = std::max(y, bbox.max.y);
+ bbox.min(0) = std::min(x, bbox.min(0));
+ bbox.min(1) = std::min(y, bbox.min(1));
+ bbox.max(0) = std::max(x, bbox.max(0));
+ bbox.max(1) = std::max(y, bbox.max(1));
}
bbox.defined = true;
}
diff --git a/xs/src/libslic3r/MultiPoint.hpp b/xs/src/libslic3r/MultiPoint.hpp
index 0970e9a67..1fef4083b 100644
--- a/xs/src/libslic3r/MultiPoint.hpp
+++ b/xs/src/libslic3r/MultiPoint.hpp
@@ -18,10 +18,11 @@ public:
Points points;
operator Points() const;
- MultiPoint() {};
+ MultiPoint() {}
MultiPoint(const MultiPoint &other) : points(other.points) {}
MultiPoint(MultiPoint &&other) : points(std::move(other.points)) {}
- explicit MultiPoint(const Points &_points): points(_points) {}
+ MultiPoint(std::initializer_list<Point> list) : points(list) {}
+ explicit MultiPoint(const Points &_points) : points(_points) {}
MultiPoint& operator=(const MultiPoint &other) { points = other.points; return *this; }
MultiPoint& operator=(MultiPoint &&other) { points = std::move(other.points); return *this; }
void scale(double factor);
@@ -43,9 +44,9 @@ public:
int idx = -1;
if (! this->points.empty()) {
idx = 0;
- double dist_min = this->points.front().distance_to(point);
+ double dist_min = (point - this->points.front()).cast<double>().norm();
for (int i = 1; i < int(this->points.size()); ++ i) {
- double d = this->points[i].distance_to(point);
+ double d = (this->points[i] - point).cast<double>().norm();
if (d < dist_min) {
dist_min = d;
idx = i;
@@ -75,7 +76,6 @@ public:
bool intersection(const Line& line, Point* intersection) const;
bool first_intersection(const Line& line, Point* intersection) const;
- std::string dump_perl() const;
static Points _douglas_peucker(const Points &points, const double tolerance);
};
@@ -85,7 +85,7 @@ class MultiPoint3
public:
Points3 points;
- void append(const Point3& point) { this->points.push_back(point); }
+ void append(const Vec3crd& point) { this->points.push_back(point); }
void translate(double x, double y);
void translate(const Point& vector);
diff --git a/xs/src/libslic3r/PerimeterGenerator.cpp b/xs/src/libslic3r/PerimeterGenerator.cpp
index 1d2e6248f..de8aeeb2a 100644
--- a/xs/src/libslic3r/PerimeterGenerator.cpp
+++ b/xs/src/libslic3r/PerimeterGenerator.cpp
@@ -243,7 +243,7 @@ void PerimeterGenerator::process()
perimeter_spacing / 2;
// only apply infill overlap if we actually have one perimeter
if (inset > 0)
- inset -= scale_(this->config->get_abs_value("infill_overlap", unscale(inset + solid_infill_spacing / 2)));
+ inset -= scale_(this->config->get_abs_value("infill_overlap", unscale<double>(inset + solid_infill_spacing / 2)));
// simplify infill contours according to resolution
Polygons pp;
for (ExPolygon &ex : last)
@@ -366,99 +366,103 @@ ExtrusionEntityCollection PerimeterGenerator::_traverse_loops(
return entities;
}
-ExtrusionEntityCollection PerimeterGenerator::_variable_width(const ThickPolylines &polylines, ExtrusionRole role, Flow flow) const
+static inline ExtrusionPaths thick_polyline_to_extrusion_paths(const ThickPolyline &thick_polyline, ExtrusionRole role, Flow &flow, const float tolerance)
{
- // this value determines granularity of adaptive width, as G-code does not allow
- // variable extrusion within a single move; this value shall only affect the amount
- // of segments, and any pruning shall be performed before we apply this tolerance
- const double tolerance = scale_(0.05);
+ ExtrusionPaths paths;
+ ExtrusionPath path(role);
+ ThickLines lines = thick_polyline.thicklines();
- ExtrusionEntityCollection coll;
- for (const ThickPolyline &p : polylines) {
- ExtrusionPaths paths;
- ExtrusionPath path(role);
- ThickLines lines = p.thicklines();
+ for (int i = 0; i < (int)lines.size(); ++i) {
+ const ThickLine& line = lines[i];
- for (int i = 0; i < (int)lines.size(); ++i) {
- const ThickLine& line = lines[i];
-
- const coordf_t line_len = line.length();
- if (line_len < SCALED_EPSILON) continue;
-
- double thickness_delta = fabs(line.a_width - line.b_width);
- if (thickness_delta > tolerance) {
- const unsigned short segments = ceil(thickness_delta / tolerance);
- const coordf_t seg_len = line_len / segments;
- Points pp;
- std::vector<coordf_t> width;
- {
- pp.push_back(line.a);
- width.push_back(line.a_width);
- for (size_t j = 1; j < segments; ++j) {
- pp.push_back(line.point_at(j*seg_len));
-
- coordf_t w = line.a_width + (j*seg_len) * (line.b_width-line.a_width) / line_len;
- width.push_back(w);
- width.push_back(w);
- }
- pp.push_back(line.b);
- width.push_back(line.b_width);
+ const coordf_t line_len = line.length();
+ if (line_len < SCALED_EPSILON) continue;
+
+ double thickness_delta = fabs(line.a_width - line.b_width);
+ if (thickness_delta > tolerance) {
+ const unsigned short segments = ceil(thickness_delta / tolerance);
+ const coordf_t seg_len = line_len / segments;
+ Points pp;
+ std::vector<coordf_t> width;
+ {
+ pp.push_back(line.a);
+ width.push_back(line.a_width);
+ for (size_t j = 1; j < segments; ++j) {
+ pp.push_back((line.a.cast<double>() + (line.b - line.a).cast<double>().normalized() * (j * seg_len)).cast<coord_t>());
- assert(pp.size() == segments + 1);
- assert(width.size() == segments*2);
- }
-
- // delete this line and insert new ones
- lines.erase(lines.begin() + i);
- for (size_t j = 0; j < segments; ++j) {
- ThickLine new_line(pp[j], pp[j+1]);
- new_line.a_width = width[2*j];
- new_line.b_width = width[2*j+1];
- lines.insert(lines.begin() + i + j, new_line);
+ coordf_t w = line.a_width + (j*seg_len) * (line.b_width-line.a_width) / line_len;
+ width.push_back(w);
+ width.push_back(w);
}
+ pp.push_back(line.b);
+ width.push_back(line.b_width);
- -- i;
- continue;
+ assert(pp.size() == segments + 1);
+ assert(width.size() == segments*2);
+ }
+
+ // delete this line and insert new ones
+ lines.erase(lines.begin() + i);
+ for (size_t j = 0; j < segments; ++j) {
+ ThickLine new_line(pp[j], pp[j+1]);
+ new_line.a_width = width[2*j];
+ new_line.b_width = width[2*j+1];
+ lines.insert(lines.begin() + i + j, new_line);
}
- const double w = fmax(line.a_width, line.b_width);
- if (path.polyline.points.empty()) {
- path.polyline.append(line.a);
+ -- i;
+ continue;
+ }
+
+ const double w = fmax(line.a_width, line.b_width);
+ if (path.polyline.points.empty()) {
+ path.polyline.append(line.a);
+ path.polyline.append(line.b);
+ // Convert from spacing to extrusion width based on the extrusion model
+ // of a square extrusion ended with semi circles.
+ flow.width = unscale<float>(w) + flow.height * (1. - 0.25 * PI);
+ #ifdef SLIC3R_DEBUG
+ printf(" filling %f gap\n", flow.width);
+ #endif
+ path.mm3_per_mm = flow.mm3_per_mm();
+ path.width = flow.width;
+ path.height = flow.height;
+ } else {
+ thickness_delta = fabs(scale_(flow.width) - w);
+ if (thickness_delta <= tolerance) {
+ // the width difference between this line and the current flow width is
+ // within the accepted tolerance
path.polyline.append(line.b);
- // Convert from spacing to extrusion width based on the extrusion model
- // of a square extrusion ended with semi circles.
- flow.width = unscale(w) + flow.height * (1. - 0.25 * PI);
- #ifdef SLIC3R_DEBUG
- printf(" filling %f gap\n", flow.width);
- #endif
- path.mm3_per_mm = flow.mm3_per_mm();
- path.width = flow.width;
- path.height = flow.height;
} else {
- thickness_delta = fabs(scale_(flow.width) - w);
- if (thickness_delta <= tolerance) {
- // the width difference between this line and the current flow width is
- // within the accepted tolerance
- path.polyline.append(line.b);
- } else {
- // we need to initialize a new line
- paths.emplace_back(std::move(path));
- path = ExtrusionPath(role);
- -- i;
- }
+ // we need to initialize a new line
+ paths.emplace_back(std::move(path));
+ path = ExtrusionPath(role);
+ -- i;
}
}
- if (path.polyline.is_valid())
- paths.emplace_back(std::move(path));
+ }
+ if (path.polyline.is_valid())
+ paths.emplace_back(std::move(path));
+ return paths;
+}
+
+ExtrusionEntityCollection PerimeterGenerator::_variable_width(const ThickPolylines &polylines, ExtrusionRole role, Flow flow) const
+{
+ // This value determines granularity of adaptive width, as G-code does not allow
+ // variable extrusion within a single move; this value shall only affect the amount
+ // of segments, and any pruning shall be performed before we apply this tolerance.
+ ExtrusionEntityCollection coll;
+ const double tolerance = scale_(0.05);
+ for (const ThickPolyline &p : polylines) {
+ ExtrusionPaths paths = thick_polyline_to_extrusion_paths(p, role, flow, tolerance);
// Append paths to collection.
if (! paths.empty()) {
- if (paths.front().first_point().coincides_with(paths.back().last_point()))
- coll.append(ExtrusionLoop(paths));
+ if (paths.front().first_point() == paths.back().last_point())
+ coll.append(ExtrusionLoop(std::move(paths)));
else
- coll.append(paths);
+ coll.append(std::move(paths));
}
}
-
return coll;
}
diff --git a/xs/src/libslic3r/PlaceholderParser.cpp b/xs/src/libslic3r/PlaceholderParser.cpp
index 80740b20d..1cfd51141 100644
--- a/xs/src/libslic3r/PlaceholderParser.cpp
+++ b/xs/src/libslic3r/PlaceholderParser.cpp
@@ -693,7 +693,7 @@ namespace client
case coInts: output.set_i(static_cast<const ConfigOptionInts *>(opt.opt)->values[idx]); break;
case coStrings: output.set_s(static_cast<const ConfigOptionStrings *>(opt.opt)->values[idx]); break;
case coPercents: output.set_d(static_cast<const ConfigOptionPercents*>(opt.opt)->values[idx]); break;
- case coPoints: output.set_s(static_cast<const ConfigOptionPoints *>(opt.opt)->values[idx].dump_perl()); break;
+ case coPoints: output.set_s(to_string(static_cast<const ConfigOptionPoints *>(opt.opt)->values[idx])); break;
case coBools: output.set_b(static_cast<const ConfigOptionBools *>(opt.opt)->values[idx] != 0); break;
default:
ctx->throw_exception("Unknown vector variable type", opt.it_range);
diff --git a/xs/src/libslic3r/Point.cpp b/xs/src/libslic3r/Point.cpp
index 349b00bb6..ec6c28fe8 100644
--- a/xs/src/libslic3r/Point.cpp
+++ b/xs/src/libslic3r/Point.cpp
@@ -3,84 +3,32 @@
#include "MultiPoint.hpp"
#include "Int128.hpp"
#include <algorithm>
-#include <cmath>
namespace Slic3r {
-Point::Point(double x, double y)
+void Point::rotate(double angle)
{
- this->x = lrint(x);
- this->y = lrint(y);
+ double cur_x = (double)(*this)(0);
+ double cur_y = (double)(*this)(1);
+ double s = ::sin(angle);
+ double c = ::cos(angle);
+ (*this)(0) = (coord_t)round(c * cur_x - s * cur_y);
+ (*this)(1) = (coord_t)round(c * cur_y + s * cur_x);
}
-std::string
-Point::wkt() const
+void Point::rotate(double angle, const Point &center)
{
- std::ostringstream ss;
- ss << "POINT(" << this->x << " " << this->y << ")";
- return ss.str();
+ double cur_x = (double)(*this)(0);
+ double cur_y = (double)(*this)(1);
+ double s = ::sin(angle);
+ double c = ::cos(angle);
+ double dx = cur_x - (double)center(0);
+ double dy = cur_y - (double)center(1);
+ (*this)(0) = (coord_t)round( (double)center(0) + c * dx - s * dy );
+ (*this)(1) = (coord_t)round( (double)center(1) + c * dy + s * dx );
}
-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)
-{
- double cur_x = (double)this->x;
- double cur_y = (double)this->y;
- double s = sin(angle);
- double c = cos(angle);
- this->x = (coord_t)round(c * cur_x - s * cur_y);
- this->y = (coord_t)round(c * cur_y + s * cur_x);
-}
-
-void
-Point::rotate(double angle, const Point &center)
-{
- double cur_x = (double)this->x;
- double cur_y = (double)this->y;
- double s = sin(angle);
- double c = cos(angle);
- double dx = cur_x - (double)center.x;
- double dy = cur_y - (double)center.y;
- this->x = (coord_t)round( (double)center.x + c * dx - s * dy );
- this->y = (coord_t)round( (double)center.y + c * dy + s * dx );
-}
-
-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());
@@ -97,12 +45,12 @@ int Point::nearest_point_index(const PointConstPtrs &points) const
for (PointConstPtrs::const_iterator it = points.begin(); it != points.end(); ++it) {
/* If the X distance of the candidate is > than the total distance of the
best previous candidate, we know we don't want it */
- double d = sqr<double>(this->x - (*it)->x);
+ double d = sqr<double>((*this)(0) - (*it)->x());
if (distance != -1 && d > distance) continue;
/* If the Y distance of the candidate is > than the total distance of the
best previous candidate, we know we don't want it */
- d += sqr<double>(this->y - (*it)->y);
+ d += sqr<double>((*this)(1) - (*it)->y());
if (distance != -1 && d > distance) continue;
idx = it - points.begin();
@@ -114,8 +62,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());
@@ -124,8 +71,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;
@@ -133,40 +79,6 @@ Point::nearest_point(const Points &points, Point* point) const
return true;
}
-/* distance to the closest point of line */
-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;
-
- const double l2 = dx*dx + dy*dy; // avoid a sqrt
- if (l2 == 0.0) return this->distance_to(line.a); // line.a == line.b case
-
- // Consider the line extending the segment, parameterized as line.a + t (line.b - line.a).
- // We find projection of this point onto the line.
- // It falls where t = [(this-line.a) . (line.b-line.a)] / |line.b-line.a|^2
- const double t = ((this->x - line.a.x) * dx + (this->y - line.a.y) * dy) / l2;
- if (t < 0.0) return this->distance_to(line.a); // beyond the 'a' end of the segment
- else if (t > 1.0) return this->distance_to(line.b); // beyond the 'b' end of the segment
- Point projection(
- line.a.x + t * dx,
- line.a.y + t * dy
- );
- return this->distance_to(projection);
-}
-
-double
-Point::perp_distance_to(const Line &line) const
-{
- if (line.a.coincides_with(line.b)) return this->distance_to(line.a);
-
- double n = (double)(line.b.x - line.a.x) * (double)(line.a.y - this->y)
- - (double)(line.a.x - this->x) * (double)(line.b.y - line.a.y);
-
- return std::abs(n) / line.length();
-}
-
/* Three points are a counter-clockwise turn if ccw > 0, clockwise if
* ccw < 0, and collinear if ccw = 0 because ccw is a determinant that
* gives the signed area of the triangle formed by p1, p2 and this point.
@@ -174,51 +86,46 @@ 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);
+ return (double)(p2(0) - p1(0))*(double)((*this)(1) - p1(1)) - (double)(p2(1) - p1(1))*(double)((*this)(0) - p1(0));
}
-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);
+ double angle = atan2(p1(0) - (*this)(0), p1(1) - (*this)(1))
+ - atan2(p2(0) - (*this)(0), p2(1) - (*this)(1));
// we only want to return only positive angles
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);
+ double running_min = (running_projection - *this).cast<double>().norm();
Lines lines = poly.lines();
for (Lines::const_iterator line = lines.begin(); line != lines.end(); ++line) {
Point point_temp = this->projection_onto(*line);
- if (this->distance_to(point_temp) < running_min) {
+ if ((point_temp - *this).cast<double>().norm() < running_min) {
running_projection = point_temp;
- running_min = this->distance_to(running_projection);
+ running_min = (running_projection - *this).cast<double>().norm();
}
}
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;
+ if (line.a == line.b) return line.a;
/*
(Ported from VisiLibity by Karl J. Obermeyer)
@@ -229,171 +136,35 @@ Point::projection_onto(const Line &line) const
If theta is outside the interval [0,1], then one of the Line_Segment's endpoints
must be closest to calling Point.
*/
- double lx = (double)(line.b.x - line.a.x);
- double ly = (double)(line.b.y - line.a.y);
- double theta = ( (double)(line.b.x - this->x)*lx + (double)(line.b.y- this->y)*ly )
+ double lx = (double)(line.b(0) - line.a(0));
+ double ly = (double)(line.b(1) - line.a(1));
+ double theta = ( (double)(line.b(0) - (*this)(0))*lx + (double)(line.b(1)- (*this)(1))*ly )
/ ( sqr<double>(lx) + sqr<double>(ly) );
if (0.0 <= theta && theta <= 1.0)
- return theta * line.a + (1.0-theta) * line.b;
+ return (theta * line.a.cast<coordf_t>() + (1.0-theta) * line.b.cast<coordf_t>()).cast<coord_t>();
// Else pick closest endpoint.
- if (this->distance_to(line.a) < this->distance_to(line.b)) {
- return line.a;
- } else {
- return line.b;
- }
-}
-
-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)
-{
- return stm << pointf.x << "," << pointf.y;
-}
-
-double
-Pointf::ccw(const Pointf &p1, const Pointf &p2) const
-{
- return (double)(p2.x - p1.x)*(double)(this->y - p1.y) - (double)(p2.y - p1.y)*(double)(this->x - p1.x);
-}
-
-std::string
-Pointf::wkt() const
-{
- std::ostringstream ss;
- ss << "POINT(" << this->x << " " << this->y << ")";
- return ss.str();
-}
-
-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)
-{
- double cur_x = this->x;
- double cur_y = this->y;
- double s = sin(angle);
- double c = cos(angle);
- this->x = c * cur_x - s * cur_y;
- this->y = c * cur_y + s * cur_x;
-}
-
-void
-Pointf::rotate(double angle, const Pointf &center)
-{
- double cur_x = this->x;
- double cur_y = this->y;
- double s = sin(angle);
- double c = cos(angle);
- double dx = cur_x - center.x;
- double dy = cur_y - center.y;
- this->x = center.x + c * dx - s * dy;
- 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);
+ return ((line.a - *this).cast<double>().squaredNorm() < (line.b - *this).cast<double>().squaredNorm()) ? line.a : line.b;
}
-Vectorf3
-Pointf3::vector_to(const Pointf3 &point) const
+std::ostream& operator<<(std::ostream &stm, const Vec2d &pointf)
{
- return Vectorf3(point.x - this->x, point.y - this->y, point.z - this->z);
+ return stm << pointf(0) << "," << pointf(1);
}
namespace int128 {
-int orient(const Point &p1, const Point &p2, const Point &p3)
+int orient(const Vec2crd &p1, const Vec2crd &p2, const Vec2crd &p3)
{
Slic3r::Vector v1(p2 - p1);
Slic3r::Vector v2(p3 - p1);
- return Int128::sign_determinant_2x2_filtered(v1.x, v1.y, v2.x, v2.y);
+ return Int128::sign_determinant_2x2_filtered(v1(0), v1(1), v2(0), v2(1));
}
-int cross(const Point &v1, const Point &v2)
+int cross(const Vec2crd &v1, const Vec2crd &v2)
{
- return Int128::sign_determinant_2x2_filtered(v1.x, v1.y, v2.x, v2.y);
+ return Int128::sign_determinant_2x2_filtered(v1(0), v1(1), v2(0), v2(1));
}
}
diff --git a/xs/src/libslic3r/Point.hpp b/xs/src/libslic3r/Point.hpp
index 347966c03..b969b9839 100644
--- a/xs/src/libslic3r/Point.hpp
+++ b/xs/src/libslic3r/Point.hpp
@@ -2,100 +2,128 @@
#define slic3r_Point_hpp_
#include "libslic3r.h"
+#include <cstddef>
#include <vector>
-#include <math.h>
+#include <cmath>
#include <string>
#include <sstream>
#include <unordered_map>
+#include <Eigen/Geometry>
+
namespace Slic3r {
class Line;
-class Linef;
class MultiPoint;
class Point;
-class Point3;
-class Pointf;
-class Pointf3;
typedef Point Vector;
-typedef Point3 Vector3;
-typedef Pointf Vectorf;
-typedef Pointf3 Vectorf3;
-typedef std::vector<Point> Points;
-typedef std::vector<Point*> PointPtrs;
-typedef std::vector<const Point*> PointConstPtrs;
-typedef std::vector<Point3> Points3;
-typedef std::vector<Pointf> Pointfs;
-typedef std::vector<Pointf3> Pointf3s;
-class 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<int64_t, 2, 1, Eigen::DontAlign> Vec2i64;
+typedef Eigen::Matrix<int64_t, 3, 1, Eigen::DontAlign> Vec3i64;
+
+// 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;
+
+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<Vec3d> Pointf3s;
+
+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;
+
+inline bool operator<(const Vec2d &lhs, const Vec2d &rhs) { return lhs(0) < rhs(0) || (lhs(0) == rhs(0) && lhs(1) < rhs(1)); }
+
+inline int64_t cross2(const Vec2i64 &v1, const Vec2i64 &v2) { return v1(0) * v2(1) - v1(1) * v2(0); }
+inline coord_t cross2(const Vec2crd &v1, const Vec2crd &v2) { return v1(0) * v2(1) - v1(1) * v2(0); }
+inline float cross2(const Vec2f &v1, const Vec2f &v2) { return v1(0) * v2(1) - v1(1) * v2(0); }
+inline double cross2(const Vec2d &v1, const Vec2d &v2) { return v1(0) * v2(1) - v1(1) * v2(0); }
+
+inline Vec2crd to_2d(const Vec3crd &pt3) { return Vec2crd(pt3(0), pt3(1)); }
+inline Vec2i64 to_2d(const Vec3i64 &pt3) { return Vec2i64(pt3(0), pt3(1)); }
+inline Vec2f to_2d(const Vec3f &pt3) { return Vec2f (pt3(0), pt3(1)); }
+inline Vec2d to_2d(const Vec3d &pt3) { return Vec2d (pt3(0), pt3(1)); }
+
+inline Vec2d unscale(coord_t x, coord_t y) { return Vec2d(unscale<double>(x), unscale<double>(y)); }
+inline Vec2d unscale(const Vec2crd &pt) { return Vec2d(unscale<double>(pt(0)), unscale<double>(pt(1))); }
+inline Vec2d unscale(const Vec2d &pt) { return Vec2d(unscale<double>(pt(0)), unscale<double>(pt(1))); }
+inline Vec3d unscale(coord_t x, coord_t y, coord_t z) { return Vec3d(unscale<double>(x), unscale<double>(y), unscale<double>(z)); }
+inline Vec3d unscale(const Vec3crd &pt) { return Vec3d(unscale<double>(pt(0)), unscale<double>(pt(1)), unscale<double>(pt(2))); }
+inline Vec3d unscale(const Vec3d &pt) { return Vec3d(unscale<double>(pt(0)), unscale<double>(pt(1)), unscale<double>(pt(2))); }
+
+inline std::string to_string(const Vec2crd &pt) { return std::string("[") + std::to_string(pt(0)) + ", " + std::to_string(pt(1)) + "]"; }
+inline std::string to_string(const Vec2d &pt) { return std::string("[") + std::to_string(pt(0)) + ", " + std::to_string(pt(1)) + "]"; }
+inline std::string to_string(const Vec3crd &pt) { return std::string("[") + std::to_string(pt(0)) + ", " + std::to_string(pt(1)) + ", " + std::to_string(pt(2)) + "]"; }
+inline std::string to_string(const Vec3d &pt) { return std::string("[") + std::to_string(pt(0)) + ", " + std::to_string(pt(1)) + ", " + std::to_string(pt(2)) + "]"; }
+
+class Point : public Vec2crd
{
public:
typedef coord_t coord_type;
- coord_t x;
- coord_t y;
- Point(coord_t _x = 0, coord_t _y = 0): x(_x), y(_y) {};
- Point(int64_t _x, int64_t _y): x(coord_t(_x)), y(coord_t(_y)) {}; // for Clipper
- Point(double x, double y);
+
+ Point() : Vec2crd() { (*this)(0) = 0; (*this)(1) = 0; }
+ Point(coord_t x, coord_t y) { (*this)(0) = x; (*this)(1) = y; }
+ Point(int64_t x, int64_t y) { (*this)(0) = coord_t(x); (*this)(1) = coord_t(y); } // for Clipper
+ Point(double x, double y) { (*this)(0) = coord_t(lrint(x)); (*this)(1) = coord_t(lrint(y)); }
+ Point(const Point &rhs) { *this = rhs; }
+ // This constructor allows you to construct Point from Eigen expressions
+ template<typename OtherDerived>
+ Point(const Eigen::MatrixBase<OtherDerived> &other) : Vec2crd(other) {}
static Point new_scale(coordf_t x, coordf_t y) { return Point(coord_t(scale_(x)), coord_t(scale_(y))); }
- 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); }
+ // This method allows you to assign Eigen expressions to MyVectorType
+ template<typename OtherDerived>
+ Point& operator=(const Eigen::MatrixBase<OtherDerived> &other)
+ {
+ this->Vec2crd::operator=(other);
+ return *this;
+ }
+
+ bool operator< (const Point& rhs) const { return (*this)(0) < rhs(0) || ((*this)(0) == rhs(0) && (*this)(1) < rhs(1)); }
- Point& operator+=(const Point& rhs) { this->x += rhs.x; this->y += rhs.y; return *this; }
- Point& operator-=(const Point& rhs) { this->x -= rhs.x; this->y -= rhs.y; return *this; }
- Point& operator*=(const coord_t& rhs) { this->x *= rhs; this->y *= rhs; return *this; }
+ Point& operator+=(const Point& rhs) { (*this)(0) += rhs(0); (*this)(1) += rhs(1); return *this; }
+ Point& operator-=(const Point& rhs) { (*this)(0) -= rhs(0); (*this)(1) -= rhs(1); return *this; }
+ Point& operator*=(const double &rhs) { (*this)(0) *= rhs; (*this)(1) *= rhs; return *this; }
- 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 rotate(double angle);
- void rotate(double angle, const Point &center);
- Point rotated(double angle) const { Point res(*this); res.rotate(angle); return res; }
- Point rotated(double angle, const Point &center) const { Point res(*this); res.rotate(angle, center); return res; }
- bool coincides_with(const Point &point) const { return this->x == point.x && this->y == point.y; }
- bool coincides_with_epsilon(const Point &point) const;
- int nearest_point_index(const Points &points) const;
- int nearest_point_index(const PointConstPtrs &points) const;
- int nearest_point_index(const PointPtrs &points) const;
- bool nearest_point(const Points &points, Point* point) const;
- double distance_to(const Point &point) const { return sqrt(distance_to_sq(point)); }
- double distance_to_sq(const Point &point) const { double dx = double(point.x - this->x); double dy = double(point.y - this->y); return dx*dx + dy*dy; }
- double distance_to(const Line &line) const;
- double perp_distance_to(const Line &line) const;
+ void rotate(double angle);
+ void rotate(double angle, const Point &center);
+ Point rotated(double angle) const { Point res(*this); res.rotate(angle); return res; }
+ Point rotated(double angle, const Point &center) const { Point res(*this); res.rotate(angle, center); return res; }
+ int nearest_point_index(const Points &points) const;
+ int nearest_point_index(const PointConstPtrs &points) const;
+ int nearest_point_index(const PointPtrs &points) const;
+ bool nearest_point(const Points &points, Point* point) const;
double ccw(const Point &p1, const Point &p2) const;
double ccw(const Line &line) const;
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 projection_onto(const MultiPoint &poly) const;
+ Point projection_onto(const Line &line) const;
};
-inline Point operator+(const Point& point1, const Point& point2) { return Point(point1.x + point2.x, point1.y + point2.y); }
-inline Point operator-(const Point& point1, const Point& point2) { return Point(point1.x - point2.x, point1.y - point2.y); }
-inline Point operator*(double scalar, const Point& point2) { return Point(scalar * point2.x, scalar * point2.y); }
-inline int64_t cross(const Point &v1, const Point &v2) { return int64_t(v1.x) * int64_t(v2.y) - int64_t(v1.y) * int64_t(v2.x); }
-inline int64_t dot(const Point &v1, const Point &v2) { return int64_t(v1.x) * int64_t(v2.x) + int64_t(v1.y) * int64_t(v2.y); }
-
namespace int128 {
-
-// Exact orientation predicate,
-// returns +1: CCW, 0: collinear, -1: CW.
-int orient(const Point &p1, const Point &p2, const Point &p3);
-
-// Exact orientation predicate,
-// returns +1: CCW, 0: collinear, -1: CW.
-int cross(const Point &v1, const Slic3r::Point &v2);
+ // Exact orientation predicate,
+ // returns +1: CCW, 0: collinear, -1: CW.
+ int orient(const Vec2crd &p1, const Vec2crd &p2, const Vec2crd &p3);
+ // Exact orientation predicate,
+ // returns +1: CCW, 0: collinear, -1: CW.
+ int cross(const Vec2crd &v1, const Vec2crd &v2);
}
// To be used by std::unordered_map, std::unordered_multimap and friends.
struct PointHash {
- size_t operator()(const Point &pt) const {
- return std::hash<coord_t>()(pt.x) ^ std::hash<coord_t>()(pt.y);
+ size_t operator()(const Vec2crd &pt) const {
+ return std::hash<coord_t>()(pt(0)) ^ std::hash<coord_t>()(pt(1));
}
};
@@ -139,36 +167,36 @@ public:
}
void insert(const ValueType &value) {
- const Point *pt = m_point_accessor(value);
+ const Vec2crd *pt = m_point_accessor(value);
if (pt != nullptr)
- m_map.emplace(std::make_pair(Point(pt->x>>m_grid_log2, pt->y>>m_grid_log2), value));
+ m_map.emplace(std::make_pair(Vec2crd(pt->x()>>m_grid_log2, pt->y()>>m_grid_log2), value));
}
void insert(ValueType &&value) {
- const Point *pt = m_point_accessor(value);
+ const Vec2crd *pt = m_point_accessor(value);
if (pt != nullptr)
- m_map.emplace(std::make_pair(Point(pt->x>>m_grid_log2, pt->y>>m_grid_log2), std::move(value)));
+ m_map.emplace(std::make_pair(Vec2crd(pt->x()>>m_grid_log2, pt->y()>>m_grid_log2), std::move(value)));
}
// Return a pair of <ValueType*, distance_squared>
- std::pair<const ValueType*, double> find(const Point &pt) {
+ std::pair<const ValueType*, double> find(const Vec2crd &pt) {
// Iterate over 4 closest grid cells around pt,
// find the closest start point inside these cells to pt.
const ValueType *value_min = nullptr;
double dist_min = std::numeric_limits<double>::max();
// Round pt to a closest grid_cell corner.
- Point grid_corner((pt.x+(m_grid_resolution>>1))>>m_grid_log2, (pt.y+(m_grid_resolution>>1))>>m_grid_log2);
+ Vec2crd grid_corner((pt(0)+(m_grid_resolution>>1))>>m_grid_log2, (pt(1)+(m_grid_resolution>>1))>>m_grid_log2);
// For four neighbors of grid_corner:
for (coord_t neighbor_y = -1; neighbor_y < 1; ++ neighbor_y) {
for (coord_t neighbor_x = -1; neighbor_x < 1; ++ neighbor_x) {
// Range of fragment starts around grid_corner, close to pt.
- auto range = m_map.equal_range(Point(grid_corner.x + neighbor_x, grid_corner.y + neighbor_y));
+ auto range = m_map.equal_range(Vec2crd(grid_corner(0) + neighbor_x, grid_corner(1) + neighbor_y));
// Find the map entry closest to pt.
for (auto it = range.first; it != range.second; ++it) {
const ValueType &value = it->second;
- const Point *pt2 = m_point_accessor(value);
+ const Vec2crd *pt2 = m_point_accessor(value);
if (pt2 != nullptr) {
- const double d2 = pt.distance_to_sq(*pt2);
+ const double d2 = (pt - *pt2).squaredNorm();
if (d2 < dist_min) {
dist_min = d2;
value_min = &value;
@@ -183,7 +211,7 @@ public:
}
private:
- typedef typename std::unordered_multimap<Point, ValueType, PointHash> map_type;
+ typedef typename std::unordered_multimap<Vec2crd, ValueType, PointHash> map_type;
PointAccessor m_point_accessor;
map_type m_map;
coord_t m_search_radius;
@@ -191,113 +219,7 @@ private:
coord_t m_grid_log2;
};
-class Point3 : public Point
-{
-public:
- coord_t z;
- explicit Point3(coord_t _x = 0, coord_t _y = 0, coord_t _z = 0): Point(_x, _y), z(_z) {};
- 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))); }
- 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;
-};
-
-std::ostream& operator<<(std::ostream &stm, const Pointf &pointf);
-
-class Pointf
-{
-public:
- typedef coordf_t coord_type;
- coordf_t x;
- coordf_t y;
- explicit Pointf(coordf_t _x = 0, coordf_t _y = 0): x(_x), y(_y) {};
- 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));
- };
- double ccw(const Pointf &p1, const Pointf &p2) const;
- 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 rotate(double angle);
- void rotate(double angle, const Pointf &center);
- Pointf negative() const;
- Vectorf vector_to(const Pointf &point) const;
-
- 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; }
-
- bool operator==(const Pointf &rhs) const { return this->x == rhs.x && this->y == rhs.y; }
- bool operator!=(const Pointf &rhs) const { return ! (*this == rhs); }
- bool operator< (const Pointf& rhs) const { return this->x < rhs.x || (this->x == rhs.x && this->y < rhs.y); }
-};
-
-inline Pointf operator+(const Pointf& point1, const Pointf& point2) { return Pointf(point1.x + point2.x, point1.y + point2.y); }
-inline Pointf operator-(const Pointf& point1, const Pointf& point2) { return Pointf(point1.x - point2.x, point1.y - point2.y); }
-inline Pointf operator*(double scalar, const Pointf& point2) { return Pointf(scalar * point2.x, scalar * point2.y); }
-inline Pointf operator*(const Pointf& point2, double scalar) { return Pointf(scalar * point2.x, scalar * point2.y); }
-inline coordf_t cross(const Pointf &v1, const Pointf &v2) { return v1.x * v2.y - v1.y * v2.x; }
-inline coordf_t dot(const Pointf &v1, const Pointf &v2) { return v1.x * v2.x + v1.y * v2.y; }
-inline coordf_t dot(const Pointf &v) { return v.x * v.x + v.y * v.y; }
-inline double length(const Vectorf &v) { return sqrt(dot(v)); }
-inline double l2(const Vectorf &v) { return dot(v); }
-inline Vectorf normalize(const Vectorf& v)
-{
- coordf_t len = ::sqrt(sqr(v.x) + sqr(v.y));
- return (len != 0.0) ? 1.0 / len * v : Vectorf(0.0, 0.0);
-}
-
-class Pointf3 : public Pointf
-{
-public:
- coordf_t z;
- explicit Pointf3(coordf_t _x = 0, coordf_t _y = 0, coordf_t _z = 0): Pointf(_x, _y), z(_z) {};
- 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;
-
- 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;
-};
-
-inline Pointf3 operator+(const Pointf3& p1, const Pointf3& p2) { return Pointf3(p1.x + p2.x, p1.y + p2.y, p1.z + p2.z); }
-inline Pointf3 operator-(const Pointf3& p1, const Pointf3& p2) { return Pointf3(p1.x - p2.x, p1.y - p2.y, p1.z - p2.z); }
-inline Pointf3 operator-(const Pointf3& p) { return Pointf3(-p.x, -p.y, -p.z); }
-inline Pointf3 operator*(double scalar, const Pointf3& p) { return Pointf3(scalar * p.x, scalar * p.y, scalar * p.z); }
-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 Pointf3 normalize(const Pointf3& v)
-{
- coordf_t len = ::sqrt(sqr(v.x) + sqr(v.y) + sqr(v.z));
- return (len != 0.0) ? 1.0 / len * v : Pointf3(0.0, 0.0, 0.0);
-}
-
-template<typename TO> inline TO convert_to(const Point &src) { return TO(typename TO::coord_type(src.x), typename TO::coord_type(src.y)); }
-template<typename TO> inline TO convert_to(const Pointf &src) { return TO(typename TO::coord_type(src.x), typename TO::coord_type(src.y)); }
-template<typename TO> inline TO convert_to(const Point3 &src) { return TO(typename TO::coord_type(src.x), typename TO::coord_type(src.y), typename TO::coord_type(src.z)); }
-template<typename TO> inline TO convert_to(const Pointf3 &src) { return TO(typename TO::coord_type(src.x), typename TO::coord_type(src.y), typename TO::coord_type(src.z)); }
+std::ostream& operator<<(std::ostream &stm, const Vec2d &pointf);
} // namespace Slic3r
@@ -313,7 +235,7 @@ namespace boost { namespace polygon {
typedef coord_t coordinate_type;
static inline coordinate_type get(const Slic3r::Point& point, orientation_2d orient) {
- return (orient == HORIZONTAL) ? point.x : point.y;
+ return (orient == HORIZONTAL) ? (coordinate_type)point(0) : (coordinate_type)point(1);
}
};
@@ -322,14 +244,14 @@ namespace boost { namespace polygon {
typedef coord_t coordinate_type;
static inline void set(Slic3r::Point& point, orientation_2d orient, coord_t value) {
if (orient == HORIZONTAL)
- point.x = value;
+ point(0) = value;
else
- point.y = value;
+ point(1) = value;
}
static inline Slic3r::Point construct(coord_t x_value, coord_t y_value) {
Slic3r::Point retval;
- retval.x = x_value;
- retval.y = y_value;
+ retval(0) = x_value;
+ retval(1) = y_value;
return retval;
}
};
diff --git a/xs/src/libslic3r/Polygon.cpp b/xs/src/libslic3r/Polygon.cpp
index b5fd7e64f..14248d84f 100644
--- a/xs/src/libslic3r/Polygon.cpp
+++ b/xs/src/libslic3r/Polygon.cpp
@@ -44,11 +44,9 @@ Polyline
Polygon::split_at_vertex(const Point &point) const
{
// find index of point
- for (Points::const_iterator it = this->points.begin(); it != this->points.end(); ++it) {
- if (it->coincides_with(point)) {
- return this->split_at_index(it - this->points.begin());
- }
- }
+ for (const Point &pt : this->points)
+ if (pt == point)
+ return this->split_at_index(&pt - &this->points.front());
CONFESS("Point not found");
return Polyline();
}
@@ -88,7 +86,7 @@ int64_t Polygon::area2x() const
int64_t a = 0;
for (size_t i = 0, j = n - 1; i < n; ++i)
- a += int64_t(poly[j].x + poly[i].x) * int64_t(poly[j].y - poly[i].y);
+ a += int64_t(poly[j](0) + poly[i](0)) * int64_t(poly[j](1) - poly[i](1));
j = i;
}
return -a * 0.5;
@@ -103,7 +101,7 @@ double Polygon::area() const
double a = 0.;
for (size_t i = 0, j = n - 1; i < n; ++i) {
- a += ((double)points[j].x + (double)points[i].x) * ((double)points[i].y - (double)points[j].y);
+ a += ((double)points[j](0) + (double)points[i](0)) * ((double)points[i](1) - (double)points[j](1));
j = i;
}
return 0.5 * a;
@@ -157,17 +155,17 @@ Polygon::contains(const Point &point) const
Points::const_iterator i = this->points.begin();
Points::const_iterator j = this->points.end() - 1;
for (; i != this->points.end(); j = i++) {
- //FIXME this test is not numerically robust. Particularly, it does not handle horizontal segments at y == point.y well.
- // Does the ray with y == point.y intersect this line segment?
+ //FIXME this test is not numerically robust. Particularly, it does not handle horizontal segments at y == point(1) well.
+ // Does the ray with y == point(1) intersect this line segment?
#if 1
- if ( ((i->y > point.y) != (j->y > point.y))
- && ((double)point.x < (double)(j->x - i->x) * (double)(point.y - i->y) / (double)(j->y - i->y) + (double)i->x) )
+ if ( (((*i)(1) > point(1)) != ((*j)(1) > point(1)))
+ && ((double)point(0) < (double)((*j)(0) - (*i)(0)) * (double)(point(1) - (*i)(1)) / (double)((*j)(1) - (*i)(1)) + (double)(*i)(0)) )
result = !result;
#else
- if ((i->y > point.y) != (j->y > point.y)) {
+ if (((*i)(1) > point(1)) != ((*j)(1) > point(1))) {
// Orientation predicated relative to i-th point.
- double orient = (double)(point.x - i->x) * (double)(j->y - i->y) - (double)(point.y - i->y) * (double)(j->x - i->x);
- if ((i->y > j->y) ? (orient > 0.) : (orient < 0.))
+ double orient = (double)(point(0) - (*i)(0)) * (double)((*j)(1) - (*i)(1)) - (double)(point(1) - (*i)(1)) * (double)((*j)(0) - (*i)(0));
+ if (((*i)(1) > (*j)(1)) ? (orient > 0.) : (orient < 0.))
result = !result;
}
#endif
@@ -225,26 +223,13 @@ Polygon::centroid() const
Polyline polyline = this->split_at_first_point();
for (Points::const_iterator point = polyline.points.begin(); point != polyline.points.end() - 1; ++point) {
- x_temp += (double)( point->x + (point+1)->x ) * ( (double)point->x*(point+1)->y - (double)(point+1)->x*point->y );
- y_temp += (double)( point->y + (point+1)->y ) * ( (double)point->x*(point+1)->y - (double)(point+1)->x*point->y );
+ x_temp += (double)( point->x() + (point+1)->x() ) * ( (double)point->x()*(point+1)->y() - (double)(point+1)->x()*point->y() );
+ y_temp += (double)( point->y() + (point+1)->y() ) * ( (double)point->x()*(point+1)->y() - (double)(point+1)->x()*point->y() );
}
return Point(x_temp/(6*area_temp), y_temp/(6*area_temp));
}
-std::string
-Polygon::wkt() const
-{
- std::ostringstream wkt;
- wkt << "POLYGON((";
- for (Points::const_iterator p = this->points.begin(); p != this->points.end(); ++p) {
- wkt << p->x << " " << p->y;
- if (p != this->points.end()-1) wkt << ",";
- }
- wkt << "))";
- return wkt.str();
-}
-
// find all concave vertices (i.e. having an internal angle greater than the supplied angle)
// (external = right side, thus we consider ccw orientation)
Points
@@ -302,24 +287,24 @@ Point Polygon::point_projection(const Point &point) const
for (size_t i = 0; i < this->points.size(); ++ i) {
const Point &pt0 = this->points[i];
const Point &pt1 = this->points[(i + 1 == this->points.size()) ? 0 : i + 1];
- double d = pt0.distance_to(point);
+ double d = (point - pt0).cast<double>().norm();
if (d < dmin) {
dmin = d;
proj = pt0;
}
- d = pt1.distance_to(point);
+ d = (point - pt1).cast<double>().norm();
if (d < dmin) {
dmin = d;
proj = pt1;
}
- Pointf v1(coordf_t(pt1.x - pt0.x), coordf_t(pt1.y - pt0.y));
- coordf_t div = dot(v1);
+ Vec2d v1(coordf_t(pt1(0) - pt0(0)), coordf_t(pt1(1) - pt0(1)));
+ coordf_t div = v1.squaredNorm();
if (div > 0.) {
- Pointf v2(coordf_t(point.x - pt0.x), coordf_t(point.y - pt0.y));
- coordf_t t = dot(v1, v2) / div;
+ Vec2d v2(coordf_t(point(0) - pt0(0)), coordf_t(point(1) - pt0(1)));
+ coordf_t t = v1.dot(v2) / div;
if (t > 0. && t < 1.) {
- Point foot(coord_t(floor(coordf_t(pt0.x) + t * v1.x + 0.5)), coord_t(floor(coordf_t(pt0.y) + t * v1.y + 0.5)));
- d = foot.distance_to(point);
+ Point foot(coord_t(floor(coordf_t(pt0(0)) + t * v1(0) + 0.5)), coord_t(floor(coordf_t(pt0(1)) + t * v1(1) + 0.5)));
+ d = (point - foot).cast<double>().norm();
if (d < dmin) {
dmin = d;
proj = foot;
@@ -376,12 +361,12 @@ static inline bool is_stick(const Point &p1, const Point &p2, const Point &p3)
{
Point v1 = p2 - p1;
Point v2 = p3 - p2;
- int64_t dir = int64_t(v1.x) * int64_t(v2.x) + int64_t(v1.y) * int64_t(v2.y);
+ int64_t dir = int64_t(v1(0)) * int64_t(v2(0)) + int64_t(v1(1)) * int64_t(v2(1));
if (dir > 0)
// p3 does not turn back to p1. Do not remove p2.
return false;
- double l2_1 = double(v1.x) * double(v1.x) + double(v1.y) * double(v1.y);
- double l2_2 = double(v2.x) * double(v2.x) + double(v2.y) * double(v2.y);
+ double l2_1 = double(v1(0)) * double(v1(0)) + double(v1(1)) * double(v1(1));
+ double l2_2 = double(v2(0)) * double(v2(0)) + double(v2(1)) * double(v2(1));
if (dir == 0)
// p1, p2, p3 may make a perpendicular corner, or there is a zero edge length.
// Remove p2 if it is coincident with p1 or p2.
@@ -389,7 +374,7 @@ static inline bool is_stick(const Point &p1, const Point &p2, const Point &p3)
// p3 turns back to p1 after p2. Are p1, p2, p3 collinear?
// Calculate distance from p3 to a segment (p1, p2) or from p1 to a segment(p2, p3),
// whichever segment is longer
- double cross = double(v1.x) * double(v2.y) - double(v2.x) * double(v1.y);
+ double cross = double(v1(0)) * double(v2(1)) - double(v2(0)) * double(v1(1));
double dist2 = cross * cross / std::max(l2_1, l2_2);
return dist2 < EPSILON * EPSILON;
}
diff --git a/xs/src/libslic3r/Polygon.hpp b/xs/src/libslic3r/Polygon.hpp
index 1a02d78b7..54909352c 100644
--- a/xs/src/libslic3r/Polygon.hpp
+++ b/xs/src/libslic3r/Polygon.hpp
@@ -24,11 +24,12 @@ public:
explicit Polygon(const Points &points): MultiPoint(points) {}
Polygon(const Polygon &other) : MultiPoint(other.points) {}
Polygon(Polygon &&other) : MultiPoint(std::move(other.points)) {}
- static Polygon new_scale(std::vector<Pointf> points) {
- Points int_points;
- for (auto pt : points)
- int_points.push_back(Point::new_scale(pt.x, pt.y));
- return Polygon(int_points);
+ static Polygon new_scale(const std::vector<Vec2d> &points) {
+ Polygon pgn;
+ pgn.points.reserve(points.size());
+ for (const Vec2d &pt : points)
+ pgn.points.emplace_back(Point::new_scale(pt(0), pt(1)));
+ return pgn;
}
Polygon& operator=(const Polygon &other) { points = other.points; return *this; }
Polygon& operator=(Polygon &&other) { points = std::move(other.points); return *this; }
@@ -54,7 +55,6 @@ public:
void simplify(double tolerance, Polygons &polygons) const;
void triangulate_convex(Polygons* polygons) const;
Point centroid() const;
- std::string wkt() const;
Points concave_points(double angle = PI) const;
Points convex_points(double angle = PI) const;
// Projection of a point onto the polygon.
diff --git a/xs/src/libslic3r/Polyline.cpp b/xs/src/libslic3r/Polyline.cpp
index 3432506c6..b2e50bca3 100644
--- a/xs/src/libslic3r/Polyline.cpp
+++ b/xs/src/libslic3r/Polyline.cpp
@@ -33,7 +33,7 @@ Polyline::leftmost_point() const
{
Point p = this->points.front();
for (Points::const_iterator it = this->points.begin() + 1; it != this->points.end(); ++it) {
- if (it->x < p.x) p = *it;
+ if ((*it)(0) < p(0)) p = *it;
}
return p;
}
@@ -52,92 +52,82 @@ Polyline::lines() const
}
// removes the given distance from the end of the polyline
-void
-Polyline::clip_end(double distance)
+void Polyline::clip_end(double distance)
{
while (distance > 0) {
- Point last_point = this->last_point();
+ Vec2d last_point = this->last_point().cast<double>();
this->points.pop_back();
- if (this->points.empty()) break;
-
- double last_segment_length = last_point.distance_to(this->last_point());
- if (last_segment_length <= distance) {
- distance -= last_segment_length;
- continue;
+ if (this->points.empty())
+ break;
+ Vec2d v = this->last_point().cast<double>() - last_point;
+ double lsqr = v.squaredNorm();
+ if (lsqr > distance * distance) {
+ this->points.emplace_back((last_point + v * (distance / sqrt(lsqr))).cast<coord_t>());
+ return;
}
-
- Line segment(last_point, this->last_point());
- this->points.push_back(segment.point_at(distance));
- distance = 0;
+ distance -= sqrt(lsqr);
}
}
// removes the given distance from the start of the polyline
-void
-Polyline::clip_start(double distance)
+void Polyline::clip_start(double distance)
{
this->reverse();
this->clip_end(distance);
- if (this->points.size() >= 2) this->reverse();
+ if (this->points.size() >= 2)
+ this->reverse();
}
-void
-Polyline::extend_end(double distance)
+void Polyline::extend_end(double distance)
{
// relocate last point by extending the last segment by the specified length
- Line line(
- this->points.back(),
- *(this->points.end() - 2)
- );
- this->points.back() = line.point_at(-distance);
+ Vec2d v = (this->points.back() - *(this->points.end() - 2)).cast<double>().normalized();
+ this->points.back() += (v * distance).cast<coord_t>();
}
-void
-Polyline::extend_start(double distance)
+void Polyline::extend_start(double distance)
{
// relocate first point by extending the first segment by the specified length
- this->points.front() = Line(this->points.front(), this->points[1]).point_at(-distance);
+ Vec2d v = (this->points.front() - this->points[1]).cast<double>().normalized();
+ this->points.front() += (v * distance).cast<coord_t>();
}
/* this method returns a collection of points picked on the polygon contour
so that they are evenly spaced according to the input distance */
-Points
-Polyline::equally_spaced_points(double distance) const
+Points Polyline::equally_spaced_points(double distance) const
{
Points points;
- points.push_back(this->first_point());
+ points.emplace_back(this->first_point());
double len = 0;
for (Points::const_iterator it = this->points.begin() + 1; it != this->points.end(); ++it) {
- double segment_length = it->distance_to(*(it-1));
+ Vec2d p1 = (it-1)->cast<double>();
+ Vec2d v = it->cast<double>() - p1;
+ double segment_length = v.norm();
len += segment_length;
- if (len < distance) continue;
-
+ if (len < distance)
+ continue;
if (len == distance) {
- points.push_back(*it);
+ points.emplace_back(*it);
len = 0;
continue;
}
-
double take = segment_length - (len - distance); // how much we take of this segment
- Line segment(*(it-1), *it);
- points.push_back(segment.point_at(take));
- --it;
- len = -take;
+ points.emplace_back((p1 + v * (take / v.norm())).cast<coord_t>());
+ -- it;
+ len = - take;
}
return points;
}
-void
-Polyline::simplify(double tolerance)
+void Polyline::simplify(double tolerance)
{
this->points = MultiPoint::_douglas_peucker(this->points, tolerance);
}
/* This method simplifies all *lines* contained in the supplied area */
template <class T>
-void
-Polyline::simplify_by_visibility(const T &area)
+void Polyline::simplify_by_visibility(const T &area)
{
Points &pp = this->points;
@@ -157,30 +147,29 @@ Polyline::simplify_by_visibility(const T &area)
template void Polyline::simplify_by_visibility<ExPolygon>(const ExPolygon &area);
template void Polyline::simplify_by_visibility<ExPolygonCollection>(const ExPolygonCollection &area);
-void
-Polyline::split_at(const Point &point, Polyline* p1, Polyline* p2) const
+void Polyline::split_at(const Point &point, Polyline* p1, Polyline* p2) const
{
if (this->points.empty()) return;
// find the line to split at
size_t line_idx = 0;
Point p = this->first_point();
- double min = point.distance_to(p);
+ double min = (p - point).cast<double>().norm();
Lines lines = this->lines();
for (Lines::const_iterator line = lines.begin(); line != lines.end(); ++line) {
Point p_tmp = point.projection_onto(*line);
- if (point.distance_to(p_tmp) < min) {
+ if ((p_tmp - point).cast<double>().norm() < min) {
p = p_tmp;
- min = point.distance_to(p);
+ min = (p - point).cast<double>().norm();
line_idx = line - lines.begin();
}
}
// create first half
p1->points.clear();
- for (Lines::const_iterator line = lines.begin(); line != lines.begin() + line_idx + 1; ++line) {
- if (!line->a.coincides_with(p)) p1->points.push_back(line->a);
- }
+ for (Lines::const_iterator line = lines.begin(); line != lines.begin() + line_idx + 1; ++line)
+ if (line->a != p)
+ p1->points.push_back(line->a);
// we add point instead of p because they might differ because of numerical issues
// and caller might want to rely on point belonging to result polylines
p1->points.push_back(point);
@@ -193,8 +182,7 @@ Polyline::split_at(const Point &point, Polyline* p1, Polyline* p2) const
}
}
-bool
-Polyline::is_straight() const
+bool Polyline::is_straight() const
{
/* Check that each segment's direction is equal to the line connecting
first point and last point. (Checking each line against the previous
@@ -208,19 +196,6 @@ Polyline::is_straight() const
return true;
}
-std::string
-Polyline::wkt() const
-{
- std::ostringstream wkt;
- wkt << "LINESTRING((";
- for (Points::const_iterator p = this->points.begin(); p != this->points.end(); ++p) {
- wkt << p->x << " " << p->y;
- if (p != this->points.end()-1) wkt << ",";
- }
- wkt << "))";
- return wkt.str();
-}
-
BoundingBox get_extents(const Polyline &polyline)
{
return polyline.bounding_box();
@@ -254,30 +229,17 @@ bool remove_degenerate(Polylines &polylines)
return modified;
}
-ThickLines
-ThickPolyline::thicklines() const
+ThickLines ThickPolyline::thicklines() const
{
ThickLines lines;
if (this->points.size() >= 2) {
lines.reserve(this->points.size() - 1);
- for (size_t i = 0; i < this->points.size()-1; ++i) {
- ThickLine line(this->points[i], this->points[i+1]);
- line.a_width = this->width[2*i];
- line.b_width = this->width[2*i+1];
- lines.push_back(line);
- }
+ for (size_t i = 0; i + 1 < this->points.size(); ++ i)
+ lines.emplace_back(this->points[i], this->points[i + 1], this->width[2 * i], this->width[2 * i + 1]);
}
return lines;
}
-void
-ThickPolyline::reverse()
-{
- Polyline::reverse();
- std::reverse(this->width.begin(), this->width.end());
- std::swap(this->endpoints.first, this->endpoints.second);
-}
-
Lines3 Polyline3::lines() const
{
Lines3 lines;
diff --git a/xs/src/libslic3r/Polyline.hpp b/xs/src/libslic3r/Polyline.hpp
index b64743d84..0c934e074 100644
--- a/xs/src/libslic3r/Polyline.hpp
+++ b/xs/src/libslic3r/Polyline.hpp
@@ -19,14 +19,15 @@ public:
Polyline() {};
Polyline(const Polyline &other) : MultiPoint(other.points) {}
Polyline(Polyline &&other) : MultiPoint(std::move(other.points)) {}
+ Polyline(std::initializer_list<Point> list) : MultiPoint(list) {}
+ explicit Polyline(const Point &p1, const Point &p2) { points.reserve(2); points.emplace_back(p1); points.emplace_back(p2); }
Polyline& operator=(const Polyline &other) { points = other.points; return *this; }
Polyline& operator=(Polyline &&other) { points = std::move(other.points); return *this; }
- static Polyline new_scale(std::vector<Pointf> points) {
+ static Polyline new_scale(const std::vector<Vec2d> &points) {
Polyline pl;
- Points int_points;
- for (auto pt : points)
- int_points.push_back(Point::new_scale(pt.x, pt.y));
- pl.append(int_points);
+ pl.points.reserve(points.size());
+ for (const Vec2d &pt : points)
+ pl.points.emplace_back(Point::new_scale(pt(0), pt(1)));
return pl;
}
@@ -71,7 +72,6 @@ public:
template <class T> void simplify_by_visibility(const T &area);
void split_at(const Point &point, Polyline* p1, Polyline* p2) const;
bool is_straight() const;
- std::string wkt() const;
};
extern BoundingBox get_extents(const Polyline &polyline);
@@ -129,12 +129,17 @@ inline void polylines_append(Polylines &dst, Polylines &&src)
bool remove_degenerate(Polylines &polylines);
class ThickPolyline : public Polyline {
- public:
- std::vector<coordf_t> width;
- std::pair<bool,bool> endpoints;
- ThickPolyline() : endpoints(std::make_pair(false, false)) {};
+public:
+ ThickPolyline() : endpoints(std::make_pair(false, false)) {}
ThickLines thicklines() const;
- void reverse();
+ void reverse() {
+ Polyline::reverse();
+ std::reverse(this->width.begin(), this->width.end());
+ std::swap(this->endpoints.first, this->endpoints.second);
+ }
+
+ std::vector<coordf_t> width;
+ std::pair<bool,bool> endpoints;
};
class Polyline3 : public MultiPoint3
diff --git a/xs/src/libslic3r/PolylineCollection.cpp b/xs/src/libslic3r/PolylineCollection.cpp
index ca9c64d23..3f65ea699 100644
--- a/xs/src/libslic3r/PolylineCollection.cpp
+++ b/xs/src/libslic3r/PolylineCollection.cpp
@@ -15,9 +15,9 @@ inline int nearest_point_index(const std::vector<Chaining> &pairs, const Point &
T dmin = std::numeric_limits<T>::max();
int idx = 0;
for (std::vector<Chaining>::const_iterator it = pairs.begin(); it != pairs.end(); ++it) {
- T d = sqr(T(start_near.x - it->first.x));
+ T d = sqr(T(start_near(0) - it->first(0)));
if (d <= dmin) {
- d += sqr(T(start_near.y - it->first.y));
+ d += sqr(T(start_near(1) - it->first(1)));
if (d < dmin) {
idx = (it - pairs.begin()) * 2;
dmin = d;
@@ -26,9 +26,9 @@ inline int nearest_point_index(const std::vector<Chaining> &pairs, const Point &
}
}
if (! no_reverse) {
- d = sqr(T(start_near.x - it->last.x));
+ d = sqr(T(start_near(0) - it->last(0)));
if (d <= dmin) {
- d += sqr(T(start_near.y - it->last.y));
+ d += sqr(T(start_near(1) - it->last(1)));
if (d < dmin) {
idx = (it - pairs.begin()) * 2 + 1;
dmin = d;
@@ -82,7 +82,7 @@ Point PolylineCollection::leftmost_point(const Polylines &polylines)
Point p = it->leftmost_point();
for (++ it; it != polylines.end(); ++it) {
Point p2 = it->leftmost_point();
- if (p2.x < p.x)
+ if (p2(0) < p(0))
p = p2;
}
return p;
diff --git a/xs/src/libslic3r/Print.cpp b/xs/src/libslic3r/Print.cpp
index bd14837d9..6739366e5 100644
--- a/xs/src/libslic3r/Print.cpp
+++ b/xs/src/libslic3r/Print.cpp
@@ -538,9 +538,9 @@ bool Print::has_skirt() const
std::string Print::validate() const
{
BoundingBox bed_box_2D = get_extents(Polygon::new_scale(config.bed_shape.values));
- BoundingBoxf3 print_volume(Pointf3(unscale(bed_box_2D.min.x), unscale(bed_box_2D.min.y), 0.0), Pointf3(unscale(bed_box_2D.max.x), unscale(bed_box_2D.max.y), config.max_print_height));
+ BoundingBoxf3 print_volume(unscale(bed_box_2D.min(0), bed_box_2D.min(1), 0.0), unscale(bed_box_2D.max(0), bed_box_2D.max(1), scale_(config.max_print_height)));
// Allow the objects to protrude below the print bed, only the part of the object above the print bed will be sliced.
- print_volume.min.z = -1e10;
+ print_volume.min(2) = -1e10;
unsigned int printable_count = 0;
for (PrintObject *po : this->objects) {
po->model_object()->check_instances_print_volume_state(print_volume);
@@ -585,7 +585,7 @@ std::string Print::validate() const
{
std::vector<coord_t> object_height;
for (const PrintObject *object : this->objects)
- object_height.insert(object_height.end(), object->copies().size(), object->size.z);
+ object_height.insert(object_height.end(), object->copies().size(), object->size(2));
std::sort(object_height.begin(), object_height.end());
// Ignore the tallest *copy* (this is why we repeat height for all of them):
// it will be printed as last one so its height doesn't matter.
@@ -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 += to_2d(object->size);
bb.merge(copy);
}
return bb;
@@ -902,7 +902,7 @@ void Print::_make_skirt()
for (const Point &shift : object->_shifted_copies) {
Points copy_points = object_points;
for (Point &pt : copy_points)
- pt.translate(shift);
+ pt += shift;
append(points, copy_points);
}
}
@@ -969,7 +969,7 @@ void Print::_make_skirt()
this->skirt.append(eloop);
if (this->config.min_skirt_length.value > 0) {
// The skirt length is limited. Sum the total amount of filament length extruded, in mm.
- extruded_length[extruder_idx] += unscale(loop.length()) * extruders_e_per_mm[extruder_idx];
+ extruded_length[extruder_idx] += unscale<double>(loop.length()) * extruders_e_per_mm[extruder_idx];
if (extruded_length[extruder_idx] < this->config.min_skirt_length.value) {
// Not extruded enough yet with the current extruder. Add another loop.
if (i == 1)
@@ -1054,7 +1054,7 @@ void Print::_make_wipe_tower()
m_wipe_tower_depth = 0.f;
// Get wiping matrix to get number of extruders and convert vector<double> to vector<float>:
- std::vector<float> wiping_matrix((this->config.wiping_volumes_matrix.values).begin(),(this->config.wiping_volumes_matrix.values).end());
+ std::vector<float> wiping_matrix(cast<float>(this->config.wiping_volumes_matrix.values));
// Extract purging volumes for each extruder pair:
std::vector<std::vector<float>> wipe_volumes;
const unsigned int number_of_extruders = (unsigned int)(sqrt(wiping_matrix.size())+EPSILON);
diff --git a/xs/src/libslic3r/Print.hpp b/xs/src/libslic3r/Print.hpp
index e3430ad0e..82fedbc7b 100644
--- a/xs/src/libslic3r/Print.hpp
+++ b/xs/src/libslic3r/Print.hpp
@@ -118,7 +118,7 @@ public:
// so that next call to make_perimeters() performs a union() before computing loops
bool typed_slices;
- Point3 size; // XYZ in scaled coordinates
+ Vec3crd size; // XYZ in scaled coordinates
// scaled coordinates to add to copies (to compensate for the alignment
// operated when creating the object but still preserving a coherent API
@@ -138,13 +138,13 @@ public:
const ModelObject* model_object() const { return this->_model_object; }
const Points& copies() const { return this->_copies; }
- bool add_copy(const Pointf &point);
+ bool add_copy(const Vec2d &point);
bool delete_last_copy();
bool delete_all_copies() { return this->set_copies(Points()); }
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), to_2d(this->size)); }
// adds region_id, too, if necessary
void add_region_volume(unsigned int region_id, int volume_id) {
diff --git a/xs/src/libslic3r/PrintConfig.cpp b/xs/src/libslic3r/PrintConfig.cpp
index f9f0b2056..748e1fb72 100644
--- a/xs/src/libslic3r/PrintConfig.cpp
+++ b/xs/src/libslic3r/PrintConfig.cpp
@@ -35,7 +35,7 @@ PrintConfigDef::PrintConfigDef()
def = this->add("bed_shape", coPoints);
def->label = L("Bed shape");
- def->default_value = new ConfigOptionPoints { Pointf(0,0), Pointf(200,0), Pointf(200,200), Pointf(0,200) };
+ def->default_value = new ConfigOptionPoints { Vec2d(0,0), Vec2d(200,0), Vec2d(200,200), Vec2d(0,200) };
def = this->add("bed_temperature", coInts);
def->label = L("Other layers");
@@ -392,7 +392,7 @@ PrintConfigDef::PrintConfigDef()
"from the XY coordinate).");
def->sidetext = L("mm");
def->cli = "extruder-offset=s@";
- def->default_value = new ConfigOptionPoints { Pointf(0,0) };
+ def->default_value = new ConfigOptionPoints { Vec2d(0,0) };
def = this->add("extrusion_axis", coString);
def->label = L("Extrusion axis");
@@ -2133,7 +2133,7 @@ void PrintConfigDef::handle_legacy(t_config_option_key &opt_key, std::string &va
ConfigOptionPoint p;
p.deserialize(value);
std::ostringstream oss;
- oss << "0x0," << p.value.x << "x0," << p.value.x << "x" << p.value.y << ",0x" << p.value.y;
+ oss << "0x0," << p.value(0) << "x0," << p.value(0) << "x" << p.value(1) << ",0x" << p.value(1);
value = oss.str();
} else if ((opt_key == "perimeter_acceleration" && value == "25")
|| (opt_key == "infill_acceleration" && value == "50")) {
diff --git a/xs/src/libslic3r/PrintObject.cpp b/xs/src/libslic3r/PrintObject.cpp
index 7150ead59..d03b99416 100644
--- a/xs/src/libslic3r/PrintObject.cpp
+++ b/xs/src/libslic3r/PrintObject.cpp
@@ -38,6 +38,7 @@ PrintObject::PrintObject(Print* print, ModelObject* model_object, const Bounding
typed_slices(false),
_print(print),
_model_object(model_object),
+ size(Vec3crd::Zero()),
layer_height_profile_valid(false)
{
// Compute the translation to be applied to our meshes so that we work with smaller coordinates
@@ -48,10 +49,9 @@ PrintObject::PrintObject(Print* print, ModelObject* model_object, const Bounding
// don't assume it's already aligned and we don't alter the original position in model.
// We store the XY translation so that we can place copies correctly in the output G-code
// (copies are expressed in G-code coordinates and this translation is not publicly exposed).
- this->_copies_shift = Point::new_scale(modobj_bbox.min.x, modobj_bbox.min.y);
+ this->_copies_shift = Point::new_scale(modobj_bbox.min(0), modobj_bbox.min(1));
// Scale the object size and store it
- Pointf3 size = modobj_bbox.size();
- this->size = Point3::new_scale(size.x, size.y, size.z);
+ this->size = (modobj_bbox.size() * (1. / SCALING_FACTOR)).cast<coord_t>();
}
this->reload_model_instances();
@@ -59,10 +59,10 @@ PrintObject::PrintObject(Print* print, ModelObject* model_object, const Bounding
this->layer_height_profile = model_object->layer_height_profile;
}
-bool PrintObject::add_copy(const Pointf &point)
+bool PrintObject::add_copy(const Vec2d &point)
{
Points points = this->_copies;
- points.push_back(Point::new_scale(point.x, point.y));
+ points.push_back(Point::new_scale(point(0), point(1)));
return this->set_copies(points);
}
@@ -86,11 +86,8 @@ bool PrintObject::set_copies(const Points &points)
std::vector<Points::size_type> ordered_copies;
Slic3r::Geometry::chained_path(points, ordered_copies);
- for (size_t point_idx : ordered_copies) {
- Point copy = points[point_idx];
- copy.translate(this->_copies_shift);
- this->_shifted_copies.push_back(copy);
- }
+ for (size_t point_idx : ordered_copies)
+ this->_shifted_copies.push_back(points[point_idx] + this->_copies_shift);
bool invalidated = this->_print->invalidate_step(psSkirt);
invalidated |= this->_print->invalidate_step(psBrim);
@@ -106,7 +103,7 @@ bool PrintObject::reload_model_instances()
for (const ModelInstance *mi : this->_model_object->instances)
{
if (mi->is_printable())
- copies.emplace_back(Point::new_scale(mi->offset.x, mi->offset.y));
+ copies.emplace_back(Point::new_scale(mi->offset(0), mi->offset(1)));
}
return this->set_copies(copies);
}
@@ -1124,7 +1121,7 @@ SlicingParameters PrintObject::slicing_parameters() const
{
return SlicingParameters::create_from_config(
this->print()->config, this->config,
- unscale(this->size.z), this->print()->object_extruders());
+ unscale<double>(this->size(2)), this->print()->object_extruders());
}
bool PrintObject::update_layer_height_profile(std::vector<coordf_t> &layer_height_profile) const
@@ -1338,7 +1335,7 @@ std::vector<ExPolygons> PrintObject::_slice_region(size_t region_id, const std::
// consider the first one
this->model_object()->instances.front()->transform_mesh(&mesh, true);
// align mesh to Z = 0 (it should be already aligned actually) and apply XY shift
- mesh.translate(- float(unscale(this->_copies_shift.x)), - float(unscale(this->_copies_shift.y)), -float(this->model_object()->bounding_box().min.z));
+ mesh.translate(- unscale<float>(this->_copies_shift(0)), - unscale<float>(this->_copies_shift(1)), - float(this->model_object()->bounding_box().min(2)));
// perform actual slicing
TriangleMeshSlicer mslicer(&mesh);
mslicer.slice(z, &layers);
diff --git a/xs/src/libslic3r/SVG.cpp b/xs/src/libslic3r/SVG.cpp
index c94db8e74..03f55802e 100644
--- a/xs/src/libslic3r/SVG.cpp
+++ b/xs/src/libslic3r/SVG.cpp
@@ -3,7 +3,7 @@
#include <boost/nowide/cstdio.hpp>
-#define COORD(x) ((float)unscale((x))*10)
+#define COORD(x) (unscale<float>((x))*10)
namespace Slic3r {
@@ -32,8 +32,8 @@ bool SVG::open(const char* afilename, const BoundingBox &bbox, const coord_t bbo
this->f = boost::nowide::fopen(afilename, "w");
if (f == NULL)
return false;
- float w = COORD(bbox.max.x - bbox.min.x + 2 * bbox_offset);
- float h = COORD(bbox.max.y - bbox.min.y + 2 * bbox_offset);
+ float w = COORD(bbox.max(0) - bbox.min(0) + 2 * bbox_offset);
+ float h = COORD(bbox.max(1) - bbox.min(1) + 2 * bbox_offset);
fprintf(this->f,
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n"
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.0//EN\" \"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\">\n"
@@ -50,7 +50,7 @@ SVG::draw(const Line &line, std::string stroke, coordf_t stroke_width)
{
fprintf(this->f,
" <line x1=\"%f\" y1=\"%f\" x2=\"%f\" y2=\"%f\" style=\"stroke: %s; stroke-width: %f\"",
- COORD(line.a.x - origin.x), COORD(line.a.y - origin.y), COORD(line.b.x - origin.x), COORD(line.b.y - origin.y), stroke.c_str(), (stroke_width == 0) ? 1.f : COORD(stroke_width));
+ COORD(line.a(0) - origin(0)), COORD(line.a(1) - origin(1)), COORD(line.b(0) - origin(0)), COORD(line.b(1) - origin(1)), stroke.c_str(), (stroke_width == 0) ? 1.f : COORD(stroke_width));
if (this->arrows)
fprintf(this->f, " marker-end=\"url(#endArrow)\"");
fprintf(this->f, "/>\n");
@@ -58,21 +58,21 @@ SVG::draw(const Line &line, std::string stroke, coordf_t stroke_width)
void SVG::draw(const ThickLine &line, const std::string &fill, const std::string &stroke, coordf_t stroke_width)
{
- Pointf dir(line.b.x-line.a.x, line.b.y-line.a.y);
- Pointf perp(-dir.y, dir.x);
- coordf_t len = sqrt(perp.x*perp.x + perp.y*perp.y);
+ Vec2d dir(line.b(0)-line.a(0), line.b(1)-line.a(1));
+ Vec2d perp(-dir(1), dir(0));
+ coordf_t len = sqrt(perp(0)*perp(0) + perp(1)*perp(1));
coordf_t da = coordf_t(0.5)*line.a_width/len;
coordf_t db = coordf_t(0.5)*line.b_width/len;
fprintf(this->f,
" <polygon points=\"%f,%f %f,%f %f,%f %f,%f\" style=\"fill:%s; stroke: %s; stroke-width: %f\"/>\n",
- COORD(line.a.x-da*perp.x-origin.x),
- COORD(line.a.y-da*perp.y-origin.y),
- COORD(line.b.x-db*perp.x-origin.x),
- COORD(line.b.y-db*perp.y-origin.y),
- COORD(line.b.x+db*perp.x-origin.x),
- COORD(line.b.y+db*perp.y-origin.y),
- COORD(line.a.x+da*perp.x-origin.x),
- COORD(line.a.y+da*perp.y-origin.y),
+ COORD(line.a(0)-da*perp(0)-origin(0)),
+ COORD(line.a(1)-da*perp(1)-origin(1)),
+ COORD(line.b(0)-db*perp(0)-origin(0)),
+ COORD(line.b(1)-db*perp(1)-origin(1)),
+ COORD(line.b(0)+db*perp(0)-origin(0)),
+ COORD(line.b(1)+db*perp(1)-origin(1)),
+ COORD(line.a(0)+da*perp(0)-origin(0)),
+ COORD(line.a(1)+da*perp(1)-origin(1)),
fill.c_str(), stroke.c_str(),
(stroke_width == 0) ? 1.f : COORD(stroke_width));
}
@@ -220,7 +220,7 @@ SVG::draw(const Point &point, std::string fill, coord_t iradius)
{
float radius = (iradius == 0) ? 3.f : COORD(iradius);
std::ostringstream svg;
- svg << " <circle cx=\"" << COORD(point.x - origin.x) << "\" cy=\"" << COORD(point.y - origin.y)
+ svg << " <circle cx=\"" << COORD(point(0) - origin(0)) << "\" cy=\"" << COORD(point(1) - origin(1))
<< "\" r=\"" << radius << "\" "
<< "style=\"stroke: none; fill: " << fill << "\" />";
@@ -287,8 +287,8 @@ SVG::get_path_d(const MultiPoint &mp, bool closed) const
std::ostringstream d;
d << "M ";
for (Points::const_iterator p = mp.points.begin(); p != mp.points.end(); ++p) {
- d << COORD(p->x - origin.x) << " ";
- d << COORD(p->y - origin.y) << " ";
+ d << COORD((*p)(0) - origin(0)) << " ";
+ d << COORD((*p)(1) - origin(1)) << " ";
}
if (closed) d << "z";
return d.str();
@@ -300,8 +300,8 @@ SVG::get_path_d(const ClipperLib::Path &path, double scale, bool closed) const
std::ostringstream d;
d << "M ";
for (ClipperLib::Path::const_iterator p = path.begin(); p != path.end(); ++p) {
- d << COORD(scale * p->X - origin.x) << " ";
- d << COORD(scale * p->Y - origin.y) << " ";
+ d << COORD(scale * p->X - origin(0)) << " ";
+ d << COORD(scale * p->Y - origin(1)) << " ";
}
if (closed) d << "z";
return d.str();
@@ -311,8 +311,8 @@ void SVG::draw_text(const Point &pt, const char *text, const char *color)
{
fprintf(this->f,
"<text x=\"%f\" y=\"%f\" font-family=\"sans-serif\" font-size=\"20px\" fill=\"%s\">%s</text>",
- COORD(pt.x-origin.x),
- COORD(pt.y-origin.y),
+ COORD(pt(0)-origin(0)),
+ COORD(pt(1)-origin(1)),
color, text);
}
@@ -320,13 +320,13 @@ void SVG::draw_legend(const Point &pt, const char *text, const char *color)
{
fprintf(this->f,
"<circle cx=\"%f\" cy=\"%f\" r=\"10\" fill=\"%s\"/>",
- COORD(pt.x-origin.x),
- COORD(pt.y-origin.y),
+ COORD(pt(0)-origin(0)),
+ COORD(pt(1)-origin(1)),
color);
fprintf(this->f,
"<text x=\"%f\" y=\"%f\" font-family=\"sans-serif\" font-size=\"10px\" fill=\"%s\">%s</text>",
- COORD(pt.x-origin.x) + 20.f,
- COORD(pt.y-origin.y),
+ COORD(pt(0)-origin(0)) + 20.f,
+ COORD(pt(1)-origin(1)),
"black", text);
}
diff --git a/xs/src/libslic3r/Slicing.cpp b/xs/src/libslic3r/Slicing.cpp
index e9295d1e3..1bc38502b 100644
--- a/xs/src/libslic3r/Slicing.cpp
+++ b/xs/src/libslic3r/Slicing.cpp
@@ -561,15 +561,15 @@ int generate_layer_height_texture(
void *data, int rows, int cols, bool level_of_detail_2nd_level)
{
// https://github.com/aschn/gnuplot-colorbrewer
- std::vector<Point3> palette_raw;
- palette_raw.push_back(Point3(0x01A, 0x098, 0x050));
- palette_raw.push_back(Point3(0x066, 0x0BD, 0x063));
- palette_raw.push_back(Point3(0x0A6, 0x0D9, 0x06A));
- palette_raw.push_back(Point3(0x0D9, 0x0F1, 0x0EB));
- palette_raw.push_back(Point3(0x0FE, 0x0E6, 0x0EB));
- palette_raw.push_back(Point3(0x0FD, 0x0AE, 0x061));
- palette_raw.push_back(Point3(0x0F4, 0x06D, 0x043));
- palette_raw.push_back(Point3(0x0D7, 0x030, 0x027));
+ std::vector<Vec3crd> palette_raw;
+ palette_raw.push_back(Vec3crd(0x01A, 0x098, 0x050));
+ palette_raw.push_back(Vec3crd(0x066, 0x0BD, 0x063));
+ palette_raw.push_back(Vec3crd(0x0A6, 0x0D9, 0x06A));
+ palette_raw.push_back(Vec3crd(0x0D9, 0x0F1, 0x0EB));
+ palette_raw.push_back(Vec3crd(0x0FE, 0x0E6, 0x0EB));
+ palette_raw.push_back(Vec3crd(0x0FD, 0x0AE, 0x061));
+ palette_raw.push_back(Vec3crd(0x0F4, 0x06D, 0x043));
+ palette_raw.push_back(Vec3crd(0x0D7, 0x030, 0x027));
// Clear the main texture and the 2nd LOD level.
// memset(data, 0, rows * cols * (level_of_detail_2nd_level ? 5 : 4));
@@ -600,25 +600,25 @@ int generate_layer_height_texture(
int idx1 = clamp(0, int(palette_raw.size() - 1), int(floor(idxf)));
int idx2 = std::min(int(palette_raw.size() - 1), idx1 + 1);
coordf_t t = idxf - coordf_t(idx1);
- const Point3 &color1 = palette_raw[idx1];
- const Point3 &color2 = palette_raw[idx2];
+ const Vec3crd &color1 = palette_raw[idx1];
+ const Vec3crd &color2 = palette_raw[idx2];
coordf_t z = cell_to_z * coordf_t(cell);
assert(z >= lo && z <= hi);
// Intensity profile to visualize the layers.
coordf_t intensity = cos(M_PI * 0.7 * (mid - z) / h);
// Color mapping from layer height to RGB.
- Pointf3 color(
- intensity * lerp(coordf_t(color1.x), coordf_t(color2.x), t),
- intensity * lerp(coordf_t(color1.y), coordf_t(color2.y), t),
- intensity * lerp(coordf_t(color1.z), coordf_t(color2.z), t));
+ Vec3d color(
+ intensity * lerp(coordf_t(color1(0)), coordf_t(color2(0)), t),
+ intensity * lerp(coordf_t(color1(1)), coordf_t(color2(1)), t),
+ intensity * lerp(coordf_t(color1(2)), coordf_t(color2(2)), t));
int row = cell / (cols - 1);
int col = cell - row * (cols - 1);
assert(row >= 0 && row < rows);
assert(col >= 0 && col < cols);
unsigned char *ptr = (unsigned char*)data + (row * cols + col) * 4;
- ptr[0] = (unsigned char)clamp<int>(0, 255, int(floor(color.x + 0.5)));
- ptr[1] = (unsigned char)clamp<int>(0, 255, int(floor(color.y + 0.5)));
- ptr[2] = (unsigned char)clamp<int>(0, 255, int(floor(color.z + 0.5)));
+ ptr[0] = (unsigned char)clamp<int>(0, 255, int(floor(color(0) + 0.5)));
+ ptr[1] = (unsigned char)clamp<int>(0, 255, int(floor(color(1) + 0.5)));
+ ptr[2] = (unsigned char)clamp<int>(0, 255, int(floor(color(2) + 0.5)));
ptr[3] = 255;
if (col == 0 && row > 0) {
// Duplicate the first value in a row as a last value of the preceding row.
@@ -636,21 +636,21 @@ int generate_layer_height_texture(
int idx1 = clamp(0, int(palette_raw.size() - 1), int(floor(idxf)));
int idx2 = std::min(int(palette_raw.size() - 1), idx1 + 1);
coordf_t t = idxf - coordf_t(idx1);
- const Point3 &color1 = palette_raw[idx1];
- const Point3 &color2 = palette_raw[idx2];
+ const Vec3crd &color1 = palette_raw[idx1];
+ const Vec3crd &color2 = palette_raw[idx2];
// Color mapping from layer height to RGB.
- Pointf3 color(
- lerp(coordf_t(color1.x), coordf_t(color2.x), t),
- lerp(coordf_t(color1.y), coordf_t(color2.y), t),
- lerp(coordf_t(color1.z), coordf_t(color2.z), t));
+ Vec3d color(
+ lerp(coordf_t(color1(0)), coordf_t(color2(0)), t),
+ lerp(coordf_t(color1(1)), coordf_t(color2(1)), t),
+ lerp(coordf_t(color1(2)), coordf_t(color2(2)), t));
int row = cell / (cols1 - 1);
int col = cell - row * (cols1 - 1);
assert(row >= 0 && row < rows/2);
assert(col >= 0 && col < cols/2);
unsigned char *ptr = data1 + (row * cols1 + col) * 4;
- ptr[0] = (unsigned char)clamp<int>(0, 255, int(floor(color.x + 0.5)));
- ptr[1] = (unsigned char)clamp<int>(0, 255, int(floor(color.y + 0.5)));
- ptr[2] = (unsigned char)clamp<int>(0, 255, int(floor(color.z + 0.5)));
+ ptr[0] = (unsigned char)clamp<int>(0, 255, int(floor(color(0) + 0.5)));
+ ptr[1] = (unsigned char)clamp<int>(0, 255, int(floor(color(1) + 0.5)));
+ ptr[2] = (unsigned char)clamp<int>(0, 255, int(floor(color(2) + 0.5)));
ptr[3] = 255;
if (col == 0 && row > 0) {
// Duplicate the first value in a row as a last value of the preceding row.
diff --git a/xs/src/libslic3r/SlicingAdaptive.cpp b/xs/src/libslic3r/SlicingAdaptive.cpp
index ff0da7636..2ef4aec8c 100644
--- a/xs/src/libslic3r/SlicingAdaptive.cpp
+++ b/xs/src/libslic3r/SlicingAdaptive.cpp
@@ -15,8 +15,8 @@ void SlicingAdaptive::clear()
std::pair<float, float> face_z_span(const stl_facet *f)
{
return std::pair<float, float>(
- std::min(std::min(f->vertex[0].z, f->vertex[1].z), f->vertex[2].z),
- std::max(std::max(f->vertex[0].z, f->vertex[1].z), f->vertex[2].z));
+ std::min(std::min(f->vertex[0](2), f->vertex[1](2)), f->vertex[2](2)),
+ std::max(std::max(f->vertex[0](2), f->vertex[1](2)), f->vertex[2](2)));
}
void SlicingAdaptive::prepare()
@@ -40,7 +40,7 @@ void SlicingAdaptive::prepare()
// 3) Generate Z components of the facet normals.
m_face_normal_z.assign(m_faces.size(), 0.f);
for (size_t iface = 0; iface < m_faces.size(); ++ iface)
- m_face_normal_z[iface] = m_faces[iface]->normal.z;
+ m_face_normal_z[iface] = m_faces[iface]->normal(2);
}
float SlicingAdaptive::cusp_height(float z, float cusp_value, int &current_facet)
diff --git a/xs/src/libslic3r/SupportMaterial.cpp b/xs/src/libslic3r/SupportMaterial.cpp
index 0cecf0014..4b7e78976 100644
--- a/xs/src/libslic3r/SupportMaterial.cpp
+++ b/xs/src/libslic3r/SupportMaterial.cpp
@@ -67,9 +67,9 @@ Point export_support_surface_type_legend_to_svg_box_size()
void export_support_surface_type_legend_to_svg(SVG &svg, const Point &pos)
{
// 1st row
- coord_t pos_x0 = pos.x + scale_(1.);
+ coord_t pos_x0 = pos(0) + scale_(1.);
coord_t pos_x = pos_x0;
- coord_t pos_y = pos.y + scale_(1.5);
+ coord_t pos_y = pos(1) + scale_(1.5);
coord_t step_x = scale_(10.);
svg.draw_legend(Point(pos_x, pos_y), "top contact" , support_surface_type_to_color_name(PrintObjectSupportMaterial::sltTopContact));
pos_x += step_x;
@@ -82,7 +82,7 @@ void export_support_surface_type_legend_to_svg(SVG &svg, const Point &pos)
svg.draw_legend(Point(pos_x, pos_y), "bottom contact" , support_surface_type_to_color_name(PrintObjectSupportMaterial::sltBottomContact));
// 2nd row
pos_x = pos_x0;
- pos_y = pos.y+scale_(2.8);
+ pos_y = pos(1)+scale_(2.8);
svg.draw_legend(Point(pos_x, pos_y), "raft interface" , support_surface_type_to_color_name(PrintObjectSupportMaterial::sltRaftInterface));
pos_x += step_x;
svg.draw_legend(Point(pos_x, pos_y), "raft base" , support_surface_type_to_color_name(PrintObjectSupportMaterial::sltRaftBase));
@@ -98,8 +98,8 @@ void export_print_z_polygons_to_svg(const char *path, PrintObjectSupportMaterial
for (int i = 0; i < n_layers; ++ i)
bbox.merge(get_extents(layers[i]->polygons));
Point legend_size = export_support_surface_type_legend_to_svg_box_size();
- Point legend_pos(bbox.min.x, bbox.max.y);
- bbox.merge(Point(std::max(bbox.min.x + legend_size.x, bbox.max.x), bbox.max.y + legend_size.y));
+ Point legend_pos(bbox.min(0), bbox.max(1));
+ bbox.merge(Point(std::max(bbox.min(0) + legend_size(0), bbox.max(0)), bbox.max(1) + legend_size(1)));
SVG svg(path, bbox);
const float transparency = 0.5f;
for (int i = 0; i < n_layers; ++ i)
@@ -120,8 +120,8 @@ void export_print_z_polygons_and_extrusions_to_svg(
for (int i = 0; i < n_layers; ++ i)
bbox.merge(get_extents(layers[i]->polygons));
Point legend_size = export_support_surface_type_legend_to_svg_box_size();
- Point legend_pos(bbox.min.x, bbox.max.y);
- bbox.merge(Point(std::max(bbox.min.x + legend_size.x, bbox.max.x), bbox.max.y + legend_size.y));
+ Point legend_pos(bbox.min(0), bbox.max(1));
+ bbox.merge(Point(std::max(bbox.min(0) + legend_size(0), bbox.max(0)), bbox.max(1) + legend_size(1)));
SVG svg(path, bbox);
const float transparency = 0.5f;
for (int i = 0; i < n_layers; ++ i)
@@ -506,8 +506,8 @@ public:
for (ExPolygon &island : islands) {
BoundingBox bbox = get_extents(island.contour);
- auto it_lower = std::lower_bound(m_island_samples.begin(), m_island_samples.end(), bbox.min - Point(1, 1));
- auto it_upper = std::upper_bound(m_island_samples.begin(), m_island_samples.end(), bbox.max + Point(1, 1));
+ auto it_lower = std::lower_bound(m_island_samples.begin(), m_island_samples.end(), Point(bbox.min - Point(1, 1)));
+ auto it_upper = std::upper_bound(m_island_samples.begin(), m_island_samples.end(), Point(bbox.max + Point(1, 1)));
samples_inside.clear();
for (auto it = it_lower; it != it_upper; ++ it)
if (bbox.contains(*it))
@@ -519,12 +519,12 @@ public:
Points::const_iterator i = contour.points.begin();
Points::const_iterator j = contour.points.end() - 1;
for (; i != contour.points.end(); j = i ++) {
- //FIXME this test is not numerically robust. Particularly, it does not handle horizontal segments at y == point.y well.
- // Does the ray with y == point.y intersect this line segment?
+ //FIXME this test is not numerically robust. Particularly, it does not handle horizontal segments at y == point(1) well.
+ // Does the ray with y == point(1) intersect this line segment?
for (auto &sample_inside : samples_inside) {
- if ((i->y > sample_inside.first.y) != (j->y > sample_inside.first.y)) {
- double x1 = (double)sample_inside.first.x;
- double x2 = (double)i->x + (double)(j->x - i->x) * (double)(sample_inside.first.y - i->y) / (double)(j->y - i->y);
+ if (((*i)(1) > sample_inside.first(1)) != ((*j)(1) > sample_inside.first(1))) {
+ double x1 = (double)sample_inside.first(0);
+ double x2 = (double)(*i)(0) + (double)((*j)(0) - (*i)(0)) * (double)(sample_inside.first(1) - (*i)(1)) / (double)((*j)(1) - (*i)(1));
if (x1 < x2)
sample_inside.second = !sample_inside.second;
}
@@ -585,11 +585,11 @@ private:
const Point &p3 = (pt_min == &expoly.contour.points.back()) ? expoly.contour.points.front() : *(pt_min + 1);
Vector v = (p3 - p2) + (p1 - p2);
- double l2 = double(v.x)*double(v.x)+double(v.y)*double(v.y);
+ double l2 = double(v(0))*double(v(0))+double(v(1))*double(v(1));
if (l2 == 0.)
return p2;
double coef = 20. / sqrt(l2);
- return Point(p2.x + coef * v.x, p2.y + coef * v.y);
+ return Point(p2(0) + coef * v(0), p2(1) + coef * v(1));
}
static Points island_samples(const ExPolygons &expolygons)
@@ -789,7 +789,7 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::top_contact_
// workaround for Clipper bug, see Slic3r::Polygon::clip_as_polyline()
for (Polyline &polyline : overhang_perimeters)
- polyline.points[0].x += 1;
+ polyline.points[0](0) += 1;
// Trim the perimeters of this layer by the lower layer to get the unsupported pieces of perimeters.
overhang_perimeters = diff_pl(overhang_perimeters, lower_grown_slices);
@@ -2057,11 +2057,11 @@ void LoopInterfaceProcessor::generate(MyLayerExtruded &top_contact_layer, const
const Point &p1 = *(it-1);
const Point &p2 = *it;
// Intersection of a ray (p1, p2) with a circle placed at center_last, with radius of circle_distance.
- const Pointf v_seg(coordf_t(p2.x) - coordf_t(p1.x), coordf_t(p2.y) - coordf_t(p1.y));
- const Pointf v_cntr(coordf_t(p1.x - center_last.x), coordf_t(p1.y - center_last.y));
- coordf_t a = dot(v_seg);
- coordf_t b = 2. * dot(v_seg, v_cntr);
- coordf_t c = dot(v_cntr) - circle_distance * circle_distance;
+ const Vec2d v_seg(coordf_t(p2(0)) - coordf_t(p1(0)), coordf_t(p2(1)) - coordf_t(p1(1)));
+ const Vec2d v_cntr(coordf_t(p1(0) - center_last(0)), coordf_t(p1(1) - center_last(1)));
+ coordf_t a = v_seg.squaredNorm();
+ coordf_t b = 2. * v_seg.dot(v_cntr);
+ coordf_t c = v_cntr.squaredNorm() - circle_distance * circle_distance;
coordf_t disc = b * b - 4. * a * c;
if (disc > 0.) {
// The circle intersects a ray. Avoid the parts of the segment inside the circle.
@@ -2081,7 +2081,7 @@ void LoopInterfaceProcessor::generate(MyLayerExtruded &top_contact_layer, const
}
seg_current_pt = &p1;
seg_current_t = t;
- center_last = Point(p1.x + coord_t(v_seg.x * t), p1.y + coord_t(v_seg.y * t));
+ center_last = Point(p1(0) + coord_t(v_seg(0) * t), p1(1) + coord_t(v_seg(1) * t));
// It has been verified that the new point is far enough from center_last.
// Ensure, that it is far enough from all the centers.
std::pair<const Point*, coordf_t> circle_closest = circle_centers_lookup.find(center_last);
@@ -2100,9 +2100,9 @@ void LoopInterfaceProcessor::generate(MyLayerExtruded &top_contact_layer, const
circle_centers.push_back(center_last);
}
external_loops.push_back(std::move(contour));
- for (Points::const_iterator it_center = circle_centers.begin(); it_center != circle_centers.end(); ++ it_center) {
+ for (const Point &center : circle_centers) {
circles.push_back(circle);
- circles.back().translate(*it_center);
+ circles.back().translate(center);
}
}
}
@@ -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;
@@ -2392,7 +2392,7 @@ void modulate_extrusion_by_overlapping_layers(
if (end_and_dist2.first == nullptr) {
// New fragment connecting to pt_current was not found.
// Verify that the last point found is close to the original end point of the unfragmented path.
- //const double d2 = pt_end.distance_to_sq(pt_current);
+ //const double d2 = (pt_end - pt_current).squaredNorm();
//assert(d2 < coordf_t(search_radius * search_radius));
// End of the path.
break;
@@ -2887,9 +2887,9 @@ void PrintObjectSupportMaterial::clip_by_pillars(
BoundingBox bbox;
for (LayersPtr::const_iterator it = top_contacts.begin(); it != top_contacts.end(); ++ it)
bbox.merge(get_extents((*it)->polygons));
- grid.reserve(size_t(ceil(bb.size().x / pillar_spacing)) * size_t(ceil(bb.size().y / pillar_spacing)));
- for (coord_t x = bb.min.x; x <= bb.max.x - pillar_size; x += pillar_spacing) {
- for (coord_t y = bb.min.y; y <= bb.max.y - pillar_size; y += pillar_spacing) {
+ grid.reserve(size_t(ceil(bb.size()(0) / pillar_spacing)) * size_t(ceil(bb.size()(1) / pillar_spacing)));
+ for (coord_t x = bb.min(0); x <= bb.max(0) - pillar_size; x += pillar_spacing) {
+ for (coord_t y = bb.min(1); y <= bb.max(1) - pillar_size; y += pillar_spacing) {
grid.push_back(pillar);
for (size_t i = 0; i < pillar.points.size(); ++ i)
grid.back().points[i].translate(Point(x, y));
diff --git a/xs/src/libslic3r/Surface.cpp b/xs/src/libslic3r/Surface.cpp
index 384540d87..0e9eca7fd 100644
--- a/xs/src/libslic3r/Surface.cpp
+++ b/xs/src/libslic3r/Surface.cpp
@@ -106,9 +106,9 @@ Point export_surface_type_legend_to_svg_box_size()
void export_surface_type_legend_to_svg(SVG &svg, const Point &pos)
{
// 1st row
- coord_t pos_x0 = pos.x + scale_(1.);
+ coord_t pos_x0 = pos(0) + scale_(1.);
coord_t pos_x = pos_x0;
- coord_t pos_y = pos.y + scale_(1.5);
+ coord_t pos_y = pos(1) + scale_(1.5);
coord_t step_x = scale_(10.);
svg.draw_legend(Point(pos_x, pos_y), "perimeter" , surface_type_to_color_name(stPerimeter));
pos_x += step_x;
@@ -121,7 +121,7 @@ void export_surface_type_legend_to_svg(SVG &svg, const Point &pos)
svg.draw_legend(Point(pos_x, pos_y), "invalid" , surface_type_to_color_name(SurfaceType(-1)));
// 2nd row
pos_x = pos_x0;
- pos_y = pos.y+scale_(2.8);
+ pos_y = pos(1)+scale_(2.8);
svg.draw_legend(Point(pos_x, pos_y), "internal" , surface_type_to_color_name(stInternal));
pos_x += step_x;
svg.draw_legend(Point(pos_x, pos_y), "internal solid" , surface_type_to_color_name(stInternalSolid));
diff --git a/xs/src/libslic3r/SurfaceCollection.cpp b/xs/src/libslic3r/SurfaceCollection.cpp
index 42ddf9574..6db599306 100644
--- a/xs/src/libslic3r/SurfaceCollection.cpp
+++ b/xs/src/libslic3r/SurfaceCollection.cpp
@@ -170,8 +170,8 @@ void SurfaceCollection::export_to_svg(const char *path, bool show_labels)
for (Surfaces::const_iterator surface = this->surfaces.begin(); surface != this->surfaces.end(); ++surface)
bbox.merge(get_extents(surface->expolygon));
Point legend_size = export_surface_type_legend_to_svg_box_size();
- Point legend_pos(bbox.min.x, bbox.max.y);
- bbox.merge(Point(std::max(bbox.min.x + legend_size.x, bbox.max.x), bbox.max.y + legend_size.y));
+ Point legend_pos(bbox.min(0), bbox.max(1));
+ bbox.merge(Point(std::max(bbox.min(0) + legend_size(0), bbox.max(0)), bbox.max(1) + legend_size(1)));
SVG svg(path, bbox);
const float transparency = 0.5f;
diff --git a/xs/src/libslic3r/TriangleMesh.cpp b/xs/src/libslic3r/TriangleMesh.cpp
index 4c45680b6..7b9baaf77 100644
--- a/xs/src/libslic3r/TriangleMesh.cpp
+++ b/xs/src/libslic3r/TriangleMesh.cpp
@@ -36,13 +36,7 @@
namespace Slic3r {
-TriangleMesh::TriangleMesh()
- : repaired(false)
-{
- stl_initialize(&this->stl);
-}
-
-TriangleMesh::TriangleMesh(const Pointf3s &points, const std::vector<Point3>& facets )
+TriangleMesh::TriangleMesh(const Pointf3s &points, const std::vector<Vec3crd>& facets )
: repaired(false)
{
stl_initialize(&this->stl);
@@ -57,51 +51,22 @@ TriangleMesh::TriangleMesh(const Pointf3s &points, const std::vector<Point3>& fa
for (int i = 0; i < stl.stats.number_of_facets; i++) {
stl_facet facet;
-
- const Pointf3& ref_f1 = points[facets[i].x];
- facet.vertex[0].x = ref_f1.x;
- facet.vertex[0].y = ref_f1.y;
- facet.vertex[0].z = ref_f1.z;
-
- const Pointf3& ref_f2 = points[facets[i].y];
- facet.vertex[1].x = ref_f2.x;
- facet.vertex[1].y = ref_f2.y;
- facet.vertex[1].z = ref_f2.z;
-
- const Pointf3& ref_f3 = points[facets[i].z];
- facet.vertex[2].x = ref_f3.x;
- facet.vertex[2].y = ref_f3.y;
- facet.vertex[2].z = ref_f3.z;
-
+ facet.vertex[0] = points[facets[i](0)].cast<float>();
+ facet.vertex[1] = points[facets[i](1)].cast<float>();
+ facet.vertex[2] = points[facets[i](2)].cast<float>();
facet.extra[0] = 0;
facet.extra[1] = 0;
- float normal[3];
+ stl_normal normal;
stl_calculate_normal(normal, &facet);
stl_normalize_vector(normal);
- facet.normal.x = normal[0];
- facet.normal.y = normal[1];
- facet.normal.z = normal[2];
+ facet.normal = normal;
stl.facet_start[i] = facet;
}
stl_get_size(&stl);
}
-TriangleMesh::TriangleMesh(const TriangleMesh &other) :
- repaired(false)
-{
- stl_initialize(&this->stl);
- *this = other;
-}
-
-TriangleMesh::TriangleMesh(TriangleMesh &&other) :
- repaired(false)
-{
- stl_initialize(&this->stl);
- this->swap(other);
-}
-
TriangleMesh& TriangleMesh::operator=(const TriangleMesh &other)
{
stl_close(&this->stl);
@@ -129,42 +94,8 @@ TriangleMesh& TriangleMesh::operator=(const TriangleMesh &other)
return *this;
}
-TriangleMesh& TriangleMesh::operator=(TriangleMesh &&other)
-{
- this->swap(other);
- return *this;
-}
-
-void
-TriangleMesh::swap(TriangleMesh &other)
+void TriangleMesh::repair()
{
- std::swap(this->stl, other.stl);
- std::swap(this->repaired, other.repaired);
-}
-
-TriangleMesh::~TriangleMesh() {
- stl_close(&this->stl);
-}
-
-void
-TriangleMesh::ReadSTLFile(const char* input_file) {
- stl_open(&stl, input_file);
-}
-
-void
-TriangleMesh::write_ascii(const char* output_file)
-{
- stl_write_ascii(&this->stl, output_file, "");
-}
-
-void
-TriangleMesh::write_binary(const char* output_file)
-{
- stl_write_binary(&this->stl, output_file, "");
-}
-
-void
-TriangleMesh::repair() {
if (this->repaired) return;
// admesh fails when repairing empty meshes
@@ -261,13 +192,7 @@ void TriangleMesh::check_topology()
}
}
-bool TriangleMesh::is_manifold() const
-{
- return this->stl.stats.connected_facets_3_edge == this->stl.stats.number_of_facets;
-}
-
-void
-TriangleMesh::reset_repair_stats() {
+void TriangleMesh::reset_repair_stats() {
this->stl.stats.degenerate_facets = 0;
this->stl.stats.edges_fixed = 0;
this->stl.stats.facets_removed = 0;
@@ -277,8 +202,7 @@ TriangleMesh::reset_repair_stats() {
this->stl.stats.normals_fixed = 0;
}
-bool
-TriangleMesh::needed_repair() const
+bool TriangleMesh::needed_repair() const
{
return this->stl.stats.degenerate_facets > 0
|| this->stl.stats.edges_fixed > 0
@@ -288,14 +212,8 @@ TriangleMesh::needed_repair() const
|| this->stl.stats.backwards_edges > 0;
}
-size_t
-TriangleMesh::facets_count() const
+void TriangleMesh::WriteOBJFile(char* output_file)
{
- return this->stl.stats.number_of_facets;
-}
-
-void
-TriangleMesh::WriteOBJFile(char* output_file) {
stl_generate_shared_vertices(&stl);
stl_write_obj(&stl, output_file);
}
@@ -306,13 +224,9 @@ void TriangleMesh::scale(float factor)
stl_invalidate_shared_vertices(&this->stl);
}
-void TriangleMesh::scale(const Pointf3 &versor)
+void TriangleMesh::scale(const Vec3d &versor)
{
- float fversor[3];
- fversor[0] = versor.x;
- fversor[1] = versor.y;
- fversor[2] = versor.z;
- stl_scale_versor(&this->stl, fversor);
+ stl_scale_versor(&this->stl, versor.cast<float>());
stl_invalidate_shared_vertices(&this->stl);
}
@@ -324,17 +238,6 @@ void TriangleMesh::translate(float x, float y, float z)
stl_invalidate_shared_vertices(&this->stl);
}
-void TriangleMesh::rotate(float angle, Pointf3 axis)
-{
- if (angle == 0.f)
- return;
-
- axis = normalize(axis);
- Eigen::Transform<float, 3, Eigen::Affine> m = Eigen::Transform<float, 3, Eigen::Affine>::Identity();
- m.rotate(Eigen::AngleAxisf(angle, Eigen::Vector3f(axis.x, axis.y, axis.z)));
- stl_transform(&stl, (float*)m.data());
-}
-
void TriangleMesh::rotate(float angle, const Axis &axis)
{
if (angle == 0.f)
@@ -353,19 +256,15 @@ void TriangleMesh::rotate(float angle, const Axis &axis)
stl_invalidate_shared_vertices(&this->stl);
}
-void TriangleMesh::rotate_x(float angle)
-{
- this->rotate(angle, X);
-}
-
-void TriangleMesh::rotate_y(float angle)
+void TriangleMesh::rotate(float angle, const Vec3d& axis)
{
- this->rotate(angle, Y);
-}
+ if (angle == 0.f)
+ return;
-void TriangleMesh::rotate_z(float angle)
-{
- this->rotate(angle, Z);
+ Vec3f axis_norm = axis.cast<float>().normalized();
+ Transform3f m = Transform3f::Identity();
+ m.rotate(Eigen::AngleAxisf(angle, axis_norm));
+ stl_transform(&stl, (float*)m.data());
}
void TriangleMesh::mirror(const Axis &axis)
@@ -380,21 +279,6 @@ void TriangleMesh::mirror(const Axis &axis)
stl_invalidate_shared_vertices(&this->stl);
}
-void TriangleMesh::mirror_x()
-{
- this->mirror(X);
-}
-
-void TriangleMesh::mirror_y()
-{
- this->mirror(Y);
-}
-
-void TriangleMesh::mirror_z()
-{
- this->mirror(Z);
-}
-
void TriangleMesh::transform(const float* matrix3x4)
{
if (matrix3x4 == nullptr)
@@ -407,19 +291,19 @@ void TriangleMesh::transform(const float* matrix3x4)
void TriangleMesh::align_to_origin()
{
this->translate(
- -(this->stl.stats.min.x),
- -(this->stl.stats.min.y),
- -(this->stl.stats.min.z)
- );
+ - this->stl.stats.min(0),
+ - this->stl.stats.min(1),
+ - this->stl.stats.min(2));
}
void TriangleMesh::rotate(double angle, Point* center)
{
if (angle == 0.)
return;
- this->translate(float(-center->x), float(-center->y), 0);
+ Vec2f c = center->cast<float>();
+ this->translate(-c(0), -c(1), 0);
stl_rotate_z(&(this->stl), (float)angle);
- this->translate(float(+center->x), float(+center->y), 0);
+ this->translate(c(0), c(1), 0);
}
bool TriangleMesh::has_multiple_patches() const
@@ -492,14 +376,14 @@ size_t TriangleMesh::number_of_patches() const
return num_bodies;
}
-TriangleMeshPtrs
-TriangleMesh::split() const
+TriangleMeshPtrs TriangleMesh::split() const
{
- TriangleMeshPtrs meshes;
- std::set<int> seen_facets;
+ TriangleMeshPtrs meshes;
+ std::vector<unsigned char> facet_visited(this->stl.stats.number_of_facets, false);
// we need neighbors
- if (!this->repaired) CONFESS("split() requires repair()");
+ if (!this->repaired)
+ CONFESS("split() requires repair()");
// loop while we have remaining facets
for (;;) {
@@ -507,46 +391,45 @@ TriangleMesh::split() const
std::queue<int> facet_queue;
std::deque<int> facets;
for (int facet_idx = 0; facet_idx < this->stl.stats.number_of_facets; facet_idx++) {
- if (seen_facets.find(facet_idx) == seen_facets.end()) {
+ if (! facet_visited[facet_idx]) {
// if facet was not seen put it into queue and start searching
facet_queue.push(facet_idx);
break;
}
}
- if (facet_queue.empty()) break;
-
- while (!facet_queue.empty()) {
+ if (facet_queue.empty())
+ break;
+
+ while (! facet_queue.empty()) {
int facet_idx = facet_queue.front();
facet_queue.pop();
- if (seen_facets.find(facet_idx) != seen_facets.end()) continue;
- facets.push_back(facet_idx);
- for (int j = 0; j <= 2; j++) {
- facet_queue.push(this->stl.neighbors_start[facet_idx].neighbor[j]);
+ if (! facet_visited[facet_idx]) {
+ facets.emplace_back(facet_idx);
+ for (int j = 0; j < 3; ++ j)
+ facet_queue.push(this->stl.neighbors_start[facet_idx].neighbor[j]);
+ facet_visited[facet_idx] = true;
}
- seen_facets.insert(facet_idx);
}
-
+
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;
stl_clear_error(&mesh->stl);
stl_allocate(&mesh->stl);
- int first = 1;
- for (std::deque<int>::const_iterator facet = facets.begin(); facet != facets.end(); ++facet) {
+ bool first = true;
+ for (std::deque<int>::const_iterator facet = facets.begin(); facet != facets.end(); ++ facet) {
mesh->stl.facet_start[facet - facets.begin()] = this->stl.facet_start[*facet];
stl_facet_stats(&mesh->stl, this->stl.facet_start[*facet], first);
- first = 0;
}
}
return meshes;
}
-void
-TriangleMesh::merge(const TriangleMesh &mesh)
+void TriangleMesh::merge(const TriangleMesh &mesh)
{
// reset stats and metadata
int number_of_facets = this->stl.stats.number_of_facets;
@@ -577,44 +460,44 @@ ExPolygons TriangleMesh::horizontal_projection() const
stl_facet* facet = &this->stl.facet_start[i];
Polygon p;
p.points.resize(3);
- p.points[0] = Point::new_scale(facet->vertex[0].x, facet->vertex[0].y);
- 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.points[0] = Point::new_scale(facet->vertex[0](0), facet->vertex[0](1));
+ p.points[1] = Point::new_scale(facet->vertex[1](0), facet->vertex[1](1));
+ p.points[2] = Point::new_scale(facet->vertex[2](0), facet->vertex[2](1));
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
return union_ex(offset(pp, scale_(0.01)), true);
}
+const float* TriangleMesh::first_vertex() const
+{
+ return this->stl.facet_start ? &this->stl.facet_start->vertex[0](0) : nullptr;
+}
+
Polygon TriangleMesh::convex_hull()
{
this->require_shared_vertices();
Points pp;
pp.reserve(this->stl.stats.shared_vertices);
for (int i = 0; i < this->stl.stats.shared_vertices; ++ i) {
- stl_vertex* v = &this->stl.v_shared[i];
- pp.emplace_back(Point::new_scale(v->x, v->y));
+ const stl_vertex &v = this->stl.v_shared[i];
+ pp.emplace_back(Point::new_scale(v(0), v(1)));
}
return Slic3r::Geometry::convex_hull(pp);
}
-BoundingBoxf3
-TriangleMesh::bounding_box() const
+BoundingBoxf3 TriangleMesh::bounding_box() const
{
BoundingBoxf3 bb;
bb.defined = true;
- bb.min.x = this->stl.stats.min.x;
- bb.min.y = this->stl.stats.min.y;
- bb.min.z = this->stl.stats.min.z;
- bb.max.x = this->stl.stats.max.x;
- bb.max.y = this->stl.stats.max.y;
- bb.max.z = this->stl.stats.max.z;
+ bb.min = this->stl.stats.min.cast<double>();
+ bb.max = this->stl.stats.max.cast<double>();
return bb;
}
-BoundingBoxf3 TriangleMesh::transformed_bounding_box(const std::vector<float>& matrix) const
+BoundingBoxf3 TriangleMesh::transformed_bounding_box(const Transform3d& t) const
{
bool has_shared = (stl.v_shared != nullptr);
if (!has_shared)
@@ -625,16 +508,16 @@ BoundingBoxf3 TriangleMesh::transformed_bounding_box(const std::vector<float>& m
if (vertices_count == 0)
return BoundingBoxf3();
- Eigen::MatrixXf src_vertices(3, vertices_count);
+ Eigen::MatrixXd src_vertices(3, vertices_count);
if (stl.stats.shared_vertices > 0)
{
stl_vertex* vertex_ptr = stl.v_shared;
for (int i = 0; i < stl.stats.shared_vertices; ++i)
{
- src_vertices(0, i) = vertex_ptr->x;
- src_vertices(1, i) = vertex_ptr->y;
- src_vertices(2, i) = vertex_ptr->z;
+ src_vertices(0, i) = (double)(*vertex_ptr)(0);
+ src_vertices(1, i) = (double)(*vertex_ptr)(1);
+ src_vertices(2, i) = (double)(*vertex_ptr)(2);
vertex_ptr += 1;
}
}
@@ -646,9 +529,9 @@ BoundingBoxf3 TriangleMesh::transformed_bounding_box(const std::vector<float>& m
{
for (int i = 0; i < 3; ++i)
{
- src_vertices(0, v_id) = facet_ptr->vertex[i].x;
- src_vertices(1, v_id) = facet_ptr->vertex[i].y;
- src_vertices(2, v_id) = facet_ptr->vertex[i].z;
+ src_vertices(0, v_id) = (double)facet_ptr->vertex[i](0);
+ src_vertices(1, v_id) = (double)facet_ptr->vertex[i](1);
+ src_vertices(2, v_id) = (double)facet_ptr->vertex[i](2);
}
facet_ptr += 1;
++v_id;
@@ -658,30 +541,22 @@ BoundingBoxf3 TriangleMesh::transformed_bounding_box(const std::vector<float>& m
if (!has_shared && (stl.stats.shared_vertices > 0))
stl_invalidate_shared_vertices(&stl);
- Eigen::Transform<float, 3, Eigen::Affine> m;
- ::memcpy((void*)m.data(), (const void*)matrix.data(), 16 * sizeof(float));
-
- Eigen::MatrixXf dst_vertices(3, vertices_count);
- dst_vertices = m * src_vertices.colwise().homogeneous();
+ Eigen::MatrixXd dst_vertices(3, vertices_count);
+ dst_vertices = t * src_vertices.colwise().homogeneous();
- float min_x = dst_vertices(0, 0);
- float max_x = dst_vertices(0, 0);
- float min_y = dst_vertices(1, 0);
- float max_y = dst_vertices(1, 0);
- float min_z = dst_vertices(2, 0);
- float max_z = dst_vertices(2, 0);
+ Vec3d v_min(dst_vertices(0, 0), dst_vertices(1, 0), dst_vertices(2, 0));
+ Vec3d v_max = v_min;
for (int i = 1; i < vertices_count; ++i)
{
- min_x = std::min(min_x, dst_vertices(0, i));
- max_x = std::max(max_x, dst_vertices(0, i));
- min_y = std::min(min_y, dst_vertices(1, i));
- max_y = std::max(max_y, dst_vertices(1, i));
- min_z = std::min(min_z, dst_vertices(2, i));
- max_z = std::max(max_z, dst_vertices(2, i));
+ for (int j = 0; j < 3; ++j)
+ {
+ v_min(j) = std::min(v_min(j), dst_vertices(j, i));
+ v_max(j) = std::max(v_max(j), dst_vertices(j, i));
+ }
}
- return BoundingBoxf3(Pointf3((coordf_t)min_x, (coordf_t)min_y, (coordf_t)min_z), Pointf3((coordf_t)max_x, (coordf_t)max_y, (coordf_t)max_z));
+ return BoundingBoxf3(v_min, v_max);
}
TriangleMesh TriangleMesh::convex_hull_3d() const
@@ -700,7 +575,7 @@ TriangleMesh TriangleMesh::convex_hull_3d() const
for (int i = 0; i < 3; ++i)
{
const stl_vertex& v = facet_ptr->vertex[i];
- src_vertices.emplace_back(v.x, v.y, v.z);
+ src_vertices.emplace_back(v(0), v(1), v(2));
}
facet_ptr += 1;
@@ -720,8 +595,8 @@ TriangleMesh TriangleMesh::convex_hull_3d() const
}
// Let's collect results:
- Pointf3s det_vertices;
- std::vector<Point3> facets;
+ Pointf3s dst_vertices;
+ std::vector<Vec3crd> facets;
auto facet_list = qhull.facetList().toStdVector();
for (const orgQhull::QhullFacet& facet : facet_list)
{ // iterate through facets
@@ -731,25 +606,19 @@ TriangleMesh TriangleMesh::convex_hull_3d() const
orgQhull::QhullPoint p = vertices[i].point();
const float* coords = p.coordinates();
- det_vertices.emplace_back(coords[0], coords[1], coords[2]);
+ dst_vertices.emplace_back(coords[0], coords[1], coords[2]);
}
- unsigned int size = (unsigned int)det_vertices.size();
+ unsigned int size = (unsigned int)dst_vertices.size();
facets.emplace_back(size - 3, size - 2, size - 1);
}
- TriangleMesh output_mesh(det_vertices, facets);
+ TriangleMesh output_mesh(dst_vertices, facets);
output_mesh.repair();
output_mesh.require_shared_vertices();
return output_mesh;
}
-const float* TriangleMesh::first_vertex() const
-{
- return stl.facet_start ? &stl.facet_start->vertex[0].x : nullptr;
-}
-
-void
-TriangleMesh::require_shared_vertices()
+void TriangleMesh::require_shared_vertices()
{
BOOST_LOG_TRIVIAL(trace) << "TriangleMeshSlicer::require_shared_vertices - start";
if (!this->repaired)
@@ -769,11 +638,8 @@ TriangleMeshSlicer::TriangleMeshSlicer(TriangleMesh* _mesh) :
facets_edges.assign(_mesh->stl.stats.number_of_facets * 3, -1);
v_scaled_shared.assign(_mesh->stl.v_shared, _mesh->stl.v_shared + _mesh->stl.stats.shared_vertices);
// Scale the copied vertices.
- for (int i = 0; i < this->mesh->stl.stats.shared_vertices; ++ i) {
- this->v_scaled_shared[i].x /= float(SCALING_FACTOR);
- this->v_scaled_shared[i].y /= float(SCALING_FACTOR);
- this->v_scaled_shared[i].z /= float(SCALING_FACTOR);
- }
+ for (int i = 0; i < this->mesh->stl.stats.shared_vertices; ++ i)
+ this->v_scaled_shared[i] *= float(1. / SCALING_FACTOR);
// Create a mapping from triangle edge into face.
struct EdgeToFace {
@@ -847,8 +713,7 @@ TriangleMeshSlicer::TriangleMeshSlicer(TriangleMesh* _mesh) :
}
}
-void
-TriangleMeshSlicer::slice(const std::vector<float> &z, std::vector<Polygons>* layers) const
+void TriangleMeshSlicer::slice(const std::vector<float> &z, std::vector<Polygons>* layers) const
{
BOOST_LOG_TRIVIAL(debug) << "TriangleMeshSlicer::slice";
@@ -929,14 +794,14 @@ void TriangleMeshSlicer::_slice_do(size_t facet_idx, std::vector<IntersectionLin
const stl_facet &facet = this->mesh->stl.facet_start[facet_idx];
// find facet extents
- const float min_z = fminf(facet.vertex[0].z, fminf(facet.vertex[1].z, facet.vertex[2].z));
- const float max_z = fmaxf(facet.vertex[0].z, fmaxf(facet.vertex[1].z, facet.vertex[2].z));
+ const float min_z = fminf(facet.vertex[0](2), fminf(facet.vertex[1](2), facet.vertex[2](2)));
+ const float max_z = fmaxf(facet.vertex[0](2), fmaxf(facet.vertex[1](2), facet.vertex[2](2)));
#ifdef SLIC3R_DEBUG
printf("\n==> FACET %d (%f,%f,%f - %f,%f,%f - %f,%f,%f):\n", facet_idx,
- facet.vertex[0].x, facet.vertex[0].y, facet.vertex[0].z,
- facet.vertex[1].x, facet.vertex[1].y, facet.vertex[1].z,
- facet.vertex[2].x, facet.vertex[2].y, facet.vertex[2].z);
+ facet.vertex[0].x, facet.vertex[0].y, facet.vertex[0](2),
+ facet.vertex[1].x, facet.vertex[1].y, facet.vertex[1](2),
+ facet.vertex[2].x, facet.vertex[2].y, facet.vertex[2](2));
printf("z: min = %.2f, max = %.2f\n", min_z, max_z);
#endif
@@ -956,24 +821,24 @@ void TriangleMeshSlicer::_slice_do(size_t facet_idx, std::vector<IntersectionLin
if (il.edge_type == feHorizontal) {
// Insert all three edges of the face.
const int *vertices = this->mesh->stl.v_indices[facet_idx].vertex;
- const bool reverse = this->mesh->stl.facet_start[facet_idx].normal.z < 0;
+ const bool reverse = this->mesh->stl.facet_start[facet_idx].normal(2) < 0;
for (int j = 0; j < 3; ++ j) {
int a_id = vertices[j % 3];
int b_id = vertices[(j+1) % 3];
if (reverse)
std::swap(a_id, b_id);
- const stl_vertex *a = &this->v_scaled_shared[a_id];
- const stl_vertex *b = &this->v_scaled_shared[b_id];
- il.a.x = a->x;
- il.a.y = a->y;
- il.b.x = b->x;
- il.b.y = b->y;
+ const stl_vertex &a = this->v_scaled_shared[a_id];
+ const stl_vertex &b = this->v_scaled_shared[b_id];
+ il.a(0) = a(0);
+ il.a(1) = a(1);
+ il.b(0) = b(0);
+ il.b(1) = b(1);
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);
}
}
}
@@ -1013,66 +878,63 @@ bool TriangleMeshSlicer::slice_facet(
// Reorder vertices so that the first one is the one with lowest Z.
// This is needed to get all intersection lines in a consistent order
// (external on the right of the line)
- int i = (facet.vertex[1].z == min_z) ? 1 : ((facet.vertex[2].z == min_z) ? 2 : 0);
+ int i = (facet.vertex[1](2) == min_z) ? 1 : ((facet.vertex[2](2) == min_z) ? 2 : 0);
for (int j = i; j - i < 3; ++ j) { // loop through facet edges
int edge_id = this->facets_edges[facet_idx * 3 + (j % 3)];
const int *vertices = this->mesh->stl.v_indices[facet_idx].vertex;
int a_id = vertices[j % 3];
int b_id = vertices[(j+1) % 3];
- const stl_vertex *a = &this->v_scaled_shared[a_id];
- const stl_vertex *b = &this->v_scaled_shared[b_id];
+ const stl_vertex &a = this->v_scaled_shared[a_id];
+ const stl_vertex &b = this->v_scaled_shared[b_id];
// Is edge or face aligned with the cutting plane?
- if (a->z == slice_z && b->z == slice_z) {
+ if (a(2) == slice_z && b(2) == slice_z) {
// Edge is horizontal and belongs to the current layer.
const stl_vertex &v0 = this->v_scaled_shared[vertices[0]];
const stl_vertex &v1 = this->v_scaled_shared[vertices[1]];
const stl_vertex &v2 = this->v_scaled_shared[vertices[2]];
+ bool swap = false;
if (min_z == max_z) {
// All three vertices are aligned with slice_z.
line_out->edge_type = feHorizontal;
- if (this->mesh->stl.facet_start[facet_idx].normal.z < 0) {
+ if (this->mesh->stl.facet_start[facet_idx].normal(2) < 0) {
// If normal points downwards this is a bottom horizontal facet so we reverse its point order.
- std::swap(a, b);
- std::swap(a_id, b_id);
+ swap = true;
}
- } else if (v0.z < slice_z || v1.z < slice_z || v2.z < slice_z) {
+ } else if (v0(2) < slice_z || v1(2) < slice_z || v2(2) < slice_z) {
// Two vertices are aligned with the cutting plane, the third vertex is below the cutting plane.
line_out->edge_type = feTop;
- std::swap(a, b);
- std::swap(a_id, b_id);
+ swap = true;
} else {
// Two vertices are aligned with the cutting plane, the third vertex is above the cutting plane.
line_out->edge_type = feBottom;
}
- line_out->a.x = a->x;
- line_out->a.y = a->y;
- line_out->b.x = b->x;
- line_out->b.y = b->y;
- line_out->a_id = a_id;
- line_out->b_id = b_id;
+ line_out->a = to_2d(swap ? b : a).cast<coord_t>();
+ line_out->b = to_2d(swap ? a : b).cast<coord_t>();
+ line_out->a_id = swap ? b_id : a_id;
+ line_out->b_id = swap ? a_id : b_id;
return true;
}
- if (a->z == slice_z) {
+ if (a(2) == slice_z) {
// Only point a alings with the cutting plane.
points_on_layer[num_points_on_layer ++] = num_points;
IntersectionPoint &point = points[num_points ++];
- point.x = a->x;
- point.y = a->y;
+ point(0) = a(0);
+ point(1) = a(1);
point.point_id = a_id;
- } else if (b->z == slice_z) {
+ } else if (b(2) == slice_z) {
// Only point b alings with the cutting plane.
points_on_layer[num_points_on_layer ++] = num_points;
IntersectionPoint &point = points[num_points ++];
- point.x = b->x;
- point.y = b->y;
+ point(0) = b(0);
+ point(1) = b(1);
point.point_id = b_id;
- } else if ((a->z < slice_z && b->z > slice_z) || (b->z < slice_z && a->z > slice_z)) {
+ } else if ((a(2) < slice_z && b(2) > slice_z) || (b(2) < slice_z && a(2) > slice_z)) {
// A general case. The face edge intersects the cutting plane. Calculate the intersection point.
IntersectionPoint &point = points[num_points ++];
- point.x = b->x + (a->x - b->x) * (slice_z - b->z) / (a->z - b->z);
- point.y = b->y + (a->y - b->y) * (slice_z - b->z) / (a->z - b->z);
+ point(0) = b(0) + (a(0) - b(0)) * (slice_z - b(2)) / (a(2) - b(2));
+ point(1) = b(1) + (a(1) - b(1)) * (slice_z - b(2)) / (a(2) - b(2));
point.edge_id = edge_id;
}
}
@@ -1353,7 +1215,7 @@ void TriangleMeshSlicer::make_loops(std::vector<IntersectionLine> &lines, Polygo
// Orient the patched up polygons CCW. This heuristic may close some holes and cavities.
double area = 0.;
for (size_t i = 0, j = opl.points.size() - 1; i < opl.points.size(); j = i ++)
- area += double(opl.points[j].x + opl.points[i].x) * double(opl.points[i].y - opl.points[j].y);
+ area += double(opl.points[j](0) + opl.points[i](0)) * double(opl.points[i](1) - opl.points[j](1));
if (area < 0)
std::reverse(opl.points.begin(), opl.points.end());
loops->emplace_back(std::move(opl.points));
@@ -1380,9 +1242,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);
}
}
@@ -1473,8 +1335,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
@@ -1489,7 +1351,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.
@@ -1539,20 +1401,20 @@ void TriangleMeshSlicer::cut(float z, TriangleMesh* upper, TriangleMesh* lower)
stl_facet* facet = &this->mesh->stl.facet_start[facet_idx];
// find facet extents
- float min_z = std::min(facet->vertex[0].z, std::min(facet->vertex[1].z, facet->vertex[2].z));
- float max_z = std::max(facet->vertex[0].z, std::max(facet->vertex[1].z, facet->vertex[2].z));
+ float min_z = std::min(facet->vertex[0](2), std::min(facet->vertex[1](2), facet->vertex[2](2)));
+ float max_z = std::max(facet->vertex[0](2), std::max(facet->vertex[1](2), facet->vertex[2](2)));
// intersect facet with cutting plane
IntersectionLine line;
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);
}
}
@@ -1567,47 +1429,47 @@ void TriangleMeshSlicer::cut(float z, TriangleMesh* upper, TriangleMesh* lower)
// look for the vertex on whose side of the slicing plane there are no other vertices
int isolated_vertex;
- if ( (facet->vertex[0].z > z) == (facet->vertex[1].z > z) ) {
+ if ( (facet->vertex[0](2) > z) == (facet->vertex[1](2) > z) ) {
isolated_vertex = 2;
- } else if ( (facet->vertex[1].z > z) == (facet->vertex[2].z > z) ) {
+ } else if ( (facet->vertex[1](2) > z) == (facet->vertex[2](2) > z) ) {
isolated_vertex = 0;
} else {
isolated_vertex = 1;
}
// get vertices starting from the isolated one
- stl_vertex* v0 = &facet->vertex[isolated_vertex];
- stl_vertex* v1 = &facet->vertex[(isolated_vertex+1) % 3];
- stl_vertex* v2 = &facet->vertex[(isolated_vertex+2) % 3];
+ const stl_vertex &v0 = facet->vertex[isolated_vertex];
+ const stl_vertex &v1 = facet->vertex[(isolated_vertex+1) % 3];
+ const stl_vertex &v2 = facet->vertex[(isolated_vertex+2) % 3];
// intersect v0-v1 and v2-v0 with cutting plane and make new vertices
stl_vertex v0v1, v2v0;
- v0v1.x = v1->x + (v0->x - v1->x) * (z - v1->z) / (v0->z - v1->z);
- v0v1.y = v1->y + (v0->y - v1->y) * (z - v1->z) / (v0->z - v1->z);
- v0v1.z = z;
- v2v0.x = v2->x + (v0->x - v2->x) * (z - v2->z) / (v0->z - v2->z);
- v2v0.y = v2->y + (v0->y - v2->y) * (z - v2->z) / (v0->z - v2->z);
- v2v0.z = z;
+ v0v1(0) = v1(0) + (v0(0) - v1(0)) * (z - v1(2)) / (v0(2) - v1(2));
+ v0v1(1) = v1(1) + (v0(1) - v1(1)) * (z - v1(2)) / (v0(2) - v1(2));
+ v0v1(2) = z;
+ v2v0(0) = v2(0) + (v0(0) - v2(0)) * (z - v2(2)) / (v0(2) - v2(2));
+ v2v0(1) = v2(1) + (v0(1) - v2(1)) * (z - v2(2)) / (v0(2) - v2(2));
+ v2v0(2) = z;
// build the triangular facet
stl_facet triangle;
triangle.normal = facet->normal;
- triangle.vertex[0] = *v0;
+ triangle.vertex[0] = v0;
triangle.vertex[1] = v0v1;
triangle.vertex[2] = v2v0;
// build the facets forming a quadrilateral on the other side
stl_facet quadrilateral[2];
quadrilateral[0].normal = facet->normal;
- quadrilateral[0].vertex[0] = *v1;
- quadrilateral[0].vertex[1] = *v2;
+ quadrilateral[0].vertex[0] = v1;
+ quadrilateral[0].vertex[1] = v2;
quadrilateral[0].vertex[2] = v0v1;
quadrilateral[1].normal = facet->normal;
- quadrilateral[1].vertex[0] = *v2;
+ quadrilateral[1].vertex[0] = v2;
quadrilateral[1].vertex[1] = v2v0;
quadrilateral[1].vertex[2] = v0v1;
- if (v0->z > z) {
+ if (v0(2) > z) {
if (upper != NULL) stl_add_facet(&upper->stl, &triangle);
if (lower != NULL) {
stl_add_facet(&lower->stl, &quadrilateral[0]);
@@ -1639,13 +1501,11 @@ void TriangleMeshSlicer::cut(float z, TriangleMesh* upper, TriangleMesh* lower)
Polygon p = *polygon;
p.reverse();
stl_facet facet;
- facet.normal.x = 0;
- facet.normal.y = 0;
- facet.normal.z = -1;
+ facet.normal = stl_normal(0, 0, -1.f);
for (size_t i = 0; i <= 2; ++i) {
- facet.vertex[i].x = unscale(p.points[i].x);
- facet.vertex[i].y = unscale(p.points[i].y);
- facet.vertex[i].z = z;
+ facet.vertex[i](0) = unscale<float>(p.points[i](0));
+ facet.vertex[i](1) = unscale<float>(p.points[i](1));
+ facet.vertex[i](2) = z;
}
stl_add_facet(&upper->stl, &facet);
}
@@ -1665,13 +1525,11 @@ void TriangleMeshSlicer::cut(float z, TriangleMesh* upper, TriangleMesh* lower)
// convert triangles to facets and append them to mesh
for (Polygons::const_iterator polygon = triangles.begin(); polygon != triangles.end(); ++polygon) {
stl_facet facet;
- facet.normal.x = 0;
- facet.normal.y = 0;
- facet.normal.z = 1;
+ facet.normal = stl_normal(0, 0, 1.f);
for (size_t i = 0; i <= 2; ++i) {
- facet.vertex[i].x = unscale(polygon->points[i].x);
- facet.vertex[i].y = unscale(polygon->points[i].y);
- facet.vertex[i].z = z;
+ facet.vertex[i](0) = unscale<float>(polygon->points[i](0));
+ facet.vertex[i](1) = unscale<float>(polygon->points[i](1));
+ facet.vertex[i](2) = z;
}
stl_add_facet(&lower->stl, &facet);
}
@@ -1684,19 +1542,19 @@ void TriangleMeshSlicer::cut(float z, TriangleMesh* upper, TriangleMesh* lower)
// Generate the vertex list for a cube solid of arbitrary size in X/Y/Z.
TriangleMesh make_cube(double x, double y, double z) {
- Pointf3 pv[8] = {
- Pointf3(x, y, 0), Pointf3(x, 0, 0), Pointf3(0, 0, 0),
- Pointf3(0, y, 0), Pointf3(x, y, z), Pointf3(0, y, z),
- Pointf3(0, 0, z), Pointf3(x, 0, z)
+ Vec3d pv[8] = {
+ Vec3d(x, y, 0), Vec3d(x, 0, 0), Vec3d(0, 0, 0),
+ Vec3d(0, y, 0), Vec3d(x, y, z), Vec3d(0, y, z),
+ Vec3d(0, 0, z), Vec3d(x, 0, z)
};
- Point3 fv[12] = {
- Point3(0, 1, 2), Point3(0, 2, 3), Point3(4, 5, 6),
- Point3(4, 6, 7), Point3(0, 4, 7), Point3(0, 7, 1),
- Point3(1, 7, 6), Point3(1, 6, 2), Point3(2, 6, 5),
- Point3(2, 5, 3), Point3(4, 0, 3), Point3(4, 3, 5)
+ Vec3crd fv[12] = {
+ Vec3crd(0, 1, 2), Vec3crd(0, 2, 3), Vec3crd(4, 5, 6),
+ Vec3crd(4, 6, 7), Vec3crd(0, 4, 7), Vec3crd(0, 7, 1),
+ Vec3crd(1, 7, 6), Vec3crd(1, 6, 2), Vec3crd(2, 6, 5),
+ Vec3crd(2, 5, 3), Vec3crd(4, 0, 3), Vec3crd(4, 3, 5)
};
- std::vector<Point3> facets(&fv[0], &fv[0]+12);
+ std::vector<Vec3crd> facets(&fv[0], &fv[0]+12);
Pointf3s vertices(&pv[0], &pv[0]+8);
TriangleMesh mesh(vertices ,facets);
@@ -1708,11 +1566,11 @@ TriangleMesh make_cube(double x, double y, double z) {
// Default is 360 sides, angle fa is in radians.
TriangleMesh make_cylinder(double r, double h, double fa) {
Pointf3s vertices;
- std::vector<Point3> facets;
+ std::vector<Vec3crd> 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(Vec3d(0.0, 0.0, 0.0));
+ vertices.emplace_back(Vec3d(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));
@@ -1722,26 +1580,23 @@ 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(Vec3d(sin(0) * r , cos(0) * r, 0));
+ vertices.emplace_back(Vec3d(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);
+ Vec2d p = Eigen::Rotation2Dd(i) * Eigen::Vector2d(0, r);
+ vertices.emplace_back(Vec3d(p(0), p(1), 0.));
+ vertices.emplace_back(Vec3d(p(0), p(1), 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(Vec3crd( 0, id - 1, id - 3)); // top
+ facets.emplace_back(Vec3crd(id, 1, id - 2)); // bottom
+ facets.emplace_back(Vec3crd(id, id - 2, id - 3)); // upper-right of side
+ facets.emplace_back(Vec3crd(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(Vec3crd( 2, 0, id - 1));
+ facets.emplace_back(Vec3crd( 1, 3, id));
+ facets.emplace_back(Vec3crd(id, 3, 2));
+ facets.emplace_back(Vec3crd(id, 2, id - 1));
TriangleMesh mesh(vertices, facets);
return mesh;
@@ -1752,7 +1607,7 @@ TriangleMesh make_cylinder(double r, double h, double fa) {
// Default angle is 1 degree.
TriangleMesh make_sphere(double rho, double fa) {
Pointf3s vertices;
- std::vector<Point3> facets;
+ std::vector<Vec3crd> facets;
// Algorithm:
// Add points one-by-one to the sphere grid and form facets using relative coordinates.
@@ -1764,29 +1619,24 @@ 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(Vec3d(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++;
+ Vec2d b = Eigen::Rotation2Dd(ring[i]) * Eigen::Vector2d(0, r);
+ vertices.emplace_back(Vec3d(b(0), b(1), z));
+ facets.emplace_back((i == 0) ? Vec3crd(1, 0, ring.size()) : Vec3crd(id, 0, id - 1));
+ ++ id;
}
// General case: insert and form facets for each step, joining it to the ring below it.
@@ -1795,16 +1645,15 @@ 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);
+ Vec2d b = Eigen::Rotation2Dd(ring[i]) * Eigen::Vector2d(0, r);
+ vertices.emplace_back(Vec3d(b(0), b(1), 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(Vec3crd(id + ring.size() - 1 , id, id - 1));
+ facets.emplace_back(Vec3crd(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(Vec3crd(id , id - ring.size(), (id - 1) - ring.size()));
+ facets.emplace_back(Vec3crd(id, id - 1 - ring.size() , id - 1));
}
id++;
}
@@ -1813,13 +1662,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(Vec3d(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(Vec3crd(id, id - ring.size(), id - 1));
} else {
- facets.push_back(Point3(id, id - ring.size() + i, id - ring.size() + (i - 1)));
+ facets.emplace_back(Vec3crd(id, id - ring.size() + i, id - ring.size() + (i - 1)));
}
}
id++;
diff --git a/xs/src/libslic3r/TriangleMesh.hpp b/xs/src/libslic3r/TriangleMesh.hpp
index 72e541afc..c42a0934d 100644
--- a/xs/src/libslic3r/TriangleMesh.hpp
+++ b/xs/src/libslic3r/TriangleMesh.hpp
@@ -20,34 +20,34 @@ typedef std::vector<TriangleMesh*> TriangleMeshPtrs;
class TriangleMesh
{
public:
- TriangleMesh();
- TriangleMesh(const Pointf3s &points, const std::vector<Point3> &facets);
- TriangleMesh(const TriangleMesh &other);
- TriangleMesh(TriangleMesh &&other);
+ TriangleMesh() : repaired(false) { stl_initialize(&this->stl); }
+ TriangleMesh(const Pointf3s &points, const std::vector<Vec3crd> &facets);
+ TriangleMesh(const TriangleMesh &other) : repaired(false) { stl_initialize(&this->stl); *this = other; }
+ TriangleMesh(TriangleMesh &&other) : repaired(false) { stl_initialize(&this->stl); this->swap(other); }
+ ~TriangleMesh() { stl_close(&this->stl); }
TriangleMesh& operator=(const TriangleMesh &other);
- TriangleMesh& operator=(TriangleMesh &&other);
- void swap(TriangleMesh &other);
- ~TriangleMesh();
- void ReadSTLFile(const char* input_file);
- void write_ascii(const char* output_file);
- void write_binary(const char* output_file);
+ TriangleMesh& operator=(TriangleMesh &&other) { this->swap(other); return *this; }
+ void swap(TriangleMesh &other) { std::swap(this->stl, other.stl); std::swap(this->repaired, other.repaired); }
+ void ReadSTLFile(const char* input_file) { stl_open(&stl, input_file); }
+ void write_ascii(const char* output_file) { stl_write_ascii(&this->stl, output_file, ""); }
+ void write_binary(const char* output_file) { stl_write_binary(&this->stl, output_file, ""); }
void repair();
float volume();
void check_topology();
- bool is_manifold() const;
+ bool is_manifold() const { return this->stl.stats.connected_facets_3_edge == this->stl.stats.number_of_facets; }
void WriteOBJFile(char* output_file);
void scale(float factor);
- void scale(const Pointf3 &versor);
+ void scale(const Vec3d &versor);
void translate(float x, float y, float z);
void rotate(float angle, const Axis &axis);
- void rotate(float angle, Pointf3 axis);
- void rotate_x(float angle);
- void rotate_y(float angle);
- void rotate_z(float angle);
+ void rotate(float angle, const Vec3d& axis);
+ void rotate_x(float angle) { this->rotate(angle, X); }
+ void rotate_y(float angle) { this->rotate(angle, Y); }
+ void rotate_z(float angle) { this->rotate(angle, Z); }
void mirror(const Axis &axis);
- void mirror_x();
- void mirror_y();
- void mirror_z();
+ void mirror_x() { this->mirror(X); }
+ void mirror_y() { this->mirror(Y); }
+ void mirror_z() { this->mirror(Z); }
void transform(const float* matrix3x4);
void align_to_origin();
void rotate(double angle, Point* center);
@@ -57,13 +57,13 @@ public:
const float* first_vertex() const;
Polygon convex_hull();
BoundingBoxf3 bounding_box() const;
- // Returns the bbox of this TriangleMesh transformed by the given matrix
- BoundingBoxf3 transformed_bounding_box(const std::vector<float>& matrix) const;
+ // Returns the bbox of this TriangleMesh transformed by the given transformation
+ BoundingBoxf3 transformed_bounding_box(const Transform3d& t) const;
// Returns the convex hull of this TriangleMesh
TriangleMesh convex_hull_3d() const;
void reset_repair_stats();
bool needed_repair() const;
- size_t facets_count() const;
+ size_t facets_count() const { return this->stl.stats.number_of_facets; }
// Returns true, if there are two and more connected patches in the mesh.
// Returns false, if one or zero connected patch is in the mesh.
diff --git a/xs/src/libslic3r/libslic3r.h b/xs/src/libslic3r/libslic3r.h
index 6db60440b..58208d116 100644
--- a/xs/src/libslic3r/libslic3r.h
+++ b/xs/src/libslic3r/libslic3r.h
@@ -45,7 +45,6 @@ typedef double coordf_t;
//FIXME Better to use an inline function with an explicit return type.
//inline coord_t scale_(coordf_t v) { return coord_t(floor(v / SCALING_FACTOR + 0.5f)); }
#define scale_(val) ((val) / SCALING_FACTOR)
-#define unscale(val) ((val) * SCALING_FACTOR)
#define SCALED_EPSILON scale_(EPSILON)
/* Implementation of CONFESS("foo"): */
#ifdef _MSC_VER
@@ -102,6 +101,9 @@ inline std::string debug_out_path(const char *name, ...)
namespace Slic3r {
+template<typename T, typename Q>
+inline T unscale(Q v) { return T(v) * T(SCALING_FACTOR); }
+
enum Axis { X=0, Y, Z, E, F, NUM_AXES };
template <class T>
@@ -130,6 +132,17 @@ inline void append(std::vector<T>& dest, std::vector<T>&& src)
src.shrink_to_fit();
}
+// Casting an std::vector<> from one type to another type without warnings about a loss of accuracy.
+template<typename T_TO, typename T_FROM>
+std::vector<T_TO> cast(const std::vector<T_FROM> &src)
+{
+ std::vector<T_TO> dst;
+ dst.reserve(src.size());
+ for (const T_FROM &a : src)
+ dst.emplace_back((T_TO)a);
+ return dst;
+}
+
template <typename T>
inline void remove_nulls(std::vector<T*> &vec)
{