Merged with dev

This commit is contained in:
bubnikv
2018-09-12 11:59:02 +02:00
1491 changed files with 514153 additions and 29226 deletions

View File

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

View File

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

View File

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

View File

@@ -9,74 +9,117 @@
namespace Slic3r {
static inline Polyline make_wave_vertical(
double width, double height, double x0,
double segmentSize, double scaleFactor,
double z_cos, double z_sin, bool flip)
static inline double f(double x, double z_sin, double z_cos, bool vertical, bool flip)
{
Polyline polyline;
polyline.points.emplace_back(Point(coord_t(clamp(0., width, x0) * scaleFactor), 0));
double phase_offset_sin = (z_cos < 0 ? M_PI : 0) + M_PI;
double phase_offset_cos = (z_cos < 0 ? M_PI : 0) + M_PI + (flip ? M_PI : 0.);
for (double y = 0.; y < height + segmentSize; y += segmentSize) {
y = std::min(y, height);
double a = sin(y + phase_offset_sin);
if (vertical) {
double phase_offset = (z_cos < 0 ? M_PI : 0) + M_PI;
double a = sin(x + phase_offset);
double b = - z_cos;
double res = z_sin * cos(y + phase_offset_cos);
double res = z_sin * cos(x + phase_offset + (flip ? M_PI : 0.));
double r = sqrt(sqr(a) + sqr(b));
double x = clamp(0., width, asin(a/r) + asin(res/r) + M_PI + x0);
polyline.points.emplace_back(convert_to<Point>(Pointf(x, y) * scaleFactor));
return asin(a/r) + asin(res/r) + M_PI;
}
if (flip)
std::reverse(polyline.points.begin(), polyline.points.end());
return polyline;
}
static inline Polyline make_wave_horizontal(
double width, double height, double y0,
double segmentSize, double scaleFactor,
double z_cos, double z_sin, bool flip)
{
Polyline polyline;
polyline.points.emplace_back(Point(0, coord_t(clamp(0., height, y0) * scaleFactor)));
double phase_offset_sin = (z_sin < 0 ? M_PI : 0) + (flip ? 0 : M_PI);
double phase_offset_cos = z_sin < 0 ? M_PI : 0.;
for (double x=0.; x < width + segmentSize; x += segmentSize) {
x = std::min(x, width);
double a = cos(x + phase_offset_cos);
else {
double phase_offset = z_sin < 0 ? M_PI : 0.;
double a = cos(x + phase_offset);
double b = - z_sin;
double res = z_cos * sin(x + phase_offset_sin);
double res = z_cos * sin(x + phase_offset + (flip ? 0 : M_PI));
double r = sqrt(sqr(a) + sqr(b));
double y = clamp(0., height, asin(a/r) + asin(res/r) + 0.5 * M_PI + y0);
polyline.points.emplace_back(convert_to<Point>(Pointf(x, y) * scaleFactor));
return (asin(a/r) + asin(res/r) + 0.5 * M_PI);
}
if (flip)
std::reverse(polyline.points.begin(), polyline.points.end());
}
static inline Polyline make_wave(
const std::vector<Vec2d>& one_period, double width, double height, double offset, double scaleFactor,
double z_cos, double z_sin, bool vertical)
{
std::vector<Vec2d> points = one_period;
double period = points.back()(0);
points.pop_back();
int n = points.size();
do {
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(1) += offset;
point(1) = clamp(0., height, double(point(1)));
if (vertical)
std::swap(point(0), point(1));
polyline.points.emplace_back((point * scaleFactor).cast<coord_t>());
}
return polyline;
}
static Polylines make_gyroid_waves(double gridZ, double density, double layer_width, double width, double height)
static std::vector<Vec2d> make_one_period(double width, double scaleFactor, double z_cos, double z_sin, bool vertical, bool flip)
{
double scaleFactor = scale_(layer_width) / density;
double segmentSize = 0.5 * density;
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(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,
// we will add one more point on each side:
const double tolerance = .1;
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<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](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;
}
static Polylines make_gyroid_waves(double gridZ, double density_adjusted, double line_spacing, double width, double height)
{
const double scaleFactor = scale_(line_spacing) / density_adjusted;
//scale factor for 5% : 8 712 388
// 1z = 10^-6 mm ?
double z = gridZ / scaleFactor;
double z_sin = sin(z);
double z_cos = cos(z);
Polylines result;
if (abs(z_sin) <= abs(z_cos)) {
// Vertical wave
double x0 = M_PI * (int)((- 0.5 * M_PI) / M_PI - 1.);
bool flip = ((int)(x0 / M_PI + 1.) & 1) != 0;
for (; x0 < width - 0.5 * M_PI; x0 += M_PI, flip = ! flip)
result.emplace_back(make_wave_vertical(width, height, x0, segmentSize, scaleFactor, z_cos, z_sin, flip));
} else {
// Horizontal wave
bool flip = true;
for (double y0 = 0.; y0 < width; y0 += M_PI, flip = !flip)
result.emplace_back(make_wave_horizontal(width, height, y0, segmentSize, scaleFactor, z_cos, z_sin, flip));
const double z = gridZ / scaleFactor;
const double z_sin = sin(z);
const double z_cos = cos(z);
bool vertical = (std::abs(z_sin) <= std::abs(z_cos));
double lower_bound = 0.;
double upper_bound = height;
bool flip = true;
if (vertical) {
flip = false;
lower_bound = -M_PI;
upper_bound = width - M_PI_2;
std::swap(width,height);
}
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
result.emplace_back(make_wave(one_period, width, height, y0, scaleFactor, z_cos, z_sin, vertical));
flip = !flip; // even polylines are a bit shifted
one_period = make_one_period(width, scaleFactor, z_cos, z_sin, vertical, flip); // updates the one period sample
for (double y0 = lower_bound + M_PI; y0 < upper_bound+EPSILON; y0 += 2*M_PI) // creates even polylines
result.emplace_back(make_wave(one_period, width, height, y0, scaleFactor, z_cos, z_sin, vertical));
return result;
}
@@ -87,24 +130,27 @@ void FillGyroid::_fill_surface_single(
ExPolygon &expolygon,
Polylines &polylines_out)
{
// no rotation is supported for this infill pattern
// no rotation is supported for this infill pattern (yet)
BoundingBox bb = expolygon.contour.bounding_box();
coord_t distance = coord_t(scale_(this->spacing) / (params.density*this->scaling));
// Density adjusted to have a good %of weight.
double density_adjusted = std::max(0., params.density * 2.);
// Distance between the gyroid waves in scaled coordinates.
coord_t distance = coord_t(scale_(this->spacing) / density_adjusted);
// align bounding box to a multiple of our grid module
bb.merge(_align_to_grid(bb.min, Point(2*M_PI*distance, 2*M_PI*distance)));
bb.merge(_align_to_grid(bb.min, Point(2.*M_PI*distance, 2.*M_PI*distance)));
// generate pattern
Polylines polylines = make_gyroid_waves(
scale_(this->z),
params.density*this->scaling,
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);
@@ -133,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());

View File

@@ -17,10 +17,6 @@ public:
virtual bool use_bridge_flow() const { return true; }
protected:
// mult of density, to have a good %of weight for each density parameter
float scaling = 1.75;
virtual void _fill_surface_single(
const FillParams &params,
unsigned int thickness_layers,

View File

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

View File

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

View File

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

View File

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

View File

@@ -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,26 +462,26 @@ 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);
int ir = std::min<int>(int(out.segs.size()) - 1, (r - x0) / line_spacing);
// The previous tests were done with floating point arithmetics over an epsilon-extended interval.
// Now do the same tests with exact arithmetics over the exact interval.
while (il <= ir && Int128::orient(out.segs[il].pos, out.segs[il].pos + out.direction, *pl) < 0)
while (il <= ir && int128::orient(out.segs[il].pos, out.segs[il].pos + out.direction, *pl) < 0)
++ il;
while (il <= ir && Int128::orient(out.segs[ir].pos, out.segs[ir].pos + out.direction, *pr) > 0)
while (il <= ir && int128::orient(out.segs[ir].pos, out.segs[ir].pos + out.direction, *pr) > 0)
-- ir;
// Here it is ensured, that
// 1) out.seg is not parallel to (pl, pr)
// 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;
@@ -489,12 +489,12 @@ static bool prepare_infill_hatching_segments(
is.iSegment = iSegment;
// Test whether the calculated intersection point falls into the bounding box of the input segment.
// +-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(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()(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 */
@@ -527,7 +527,7 @@ static bool prepare_infill_hatching_segments(
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;
int dir = Int128::cross(contour[iSegment] - contour[iPrev], sil.dir);
int dir = int128::cross(contour[iSegment] - contour[iPrev], sil.dir);
bool low = dir > 0;
sil.intersections[i].type = poly_with_offset.is_contour_outer(iContour) ?
(low ? SegmentIntersection::OUTER_LOW : SegmentIntersection::OUTER_HIGH) :
@@ -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?