diff --git a/src/libslic3r/EdgeGrid.cpp b/src/libslic3r/EdgeGrid.cpp index c34aca8f2..8b9264044 100644 --- a/src/libslic3r/EdgeGrid.cpp +++ b/src/libslic3r/EdgeGrid.cpp @@ -1258,9 +1258,9 @@ Polygons EdgeGrid::Grid::contours_simplified(coord_t offset, bool fill_holes) co // 1) Collect the lines. std::vector lines; EndPointMapType start_point_to_line_idx; - for (int r = 0; r <= int(m_rows); ++ r) { - for (int c = 0; c <= int(m_cols); ++ c) { - int addr = (r + 1) * cell_cols + c + 1; + for (coord_t r = 0; r <= coord_t(m_rows); ++ r) { + for (coord_t c = 0; c <= coord_t(m_cols); ++ c) { + size_t addr = (r + 1) * cell_cols + c + 1; bool left = cell_inside[addr - 1]; bool top = cell_inside[addr - cell_cols]; bool current = cell_inside[addr]; @@ -1364,9 +1364,9 @@ inline int segments_could_intersect( const Slic3r::Point &ip1, const Slic3r::Point &ip2, const Slic3r::Point &jp1, const Slic3r::Point &jp2) { - Vec2i64 iv = (ip2 - ip1).cast(); - Vec2i64 vij1 = (jp1 - ip1).cast(); - Vec2i64 vij2 = (jp2 - ip1).cast(); + Vec2crd iv = (ip2 - ip1); + Vec2crd vij1 = (jp1 - ip1); + Vec2crd vij2 = (jp2 - ip1); int64_t tij1 = cross2(iv, vij1); int64_t tij2 = cross2(iv, vij2); int sij1 = (tij1 > 0) ? 1 : ((tij1 < 0) ? -1 : 0); // signum diff --git a/src/libslic3r/Fill/FillRectilinear3.cpp b/src/libslic3r/Fill/FillRectilinear3.cpp index d682d0cdd..662aeabe3 100644 --- a/src/libslic3r/Fill/FillRectilinear3.cpp +++ b/src/libslic3r/Fill/FillRectilinear3.cpp @@ -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 (cross2(Vec2i64(this->line->dir.cast()), (seg_end_b - this->line->pos).cast()) == 0) + if (cross2(Vec2crd(this->line->dir), (seg_end_b - this->line->pos)) == 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 (cross2(Vec2i64(this->line->dir.cast()), (seg_start_a - this->line->pos).cast()) == 0) + if (cross2(Vec2crd(this->line->dir), (seg_start_a - this->line->pos)) == 0) return 0; } else { // General case. @@ -290,33 +290,33 @@ 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 Vec2i64 vec_b = (seg_end_b - seg_start_b).cast(); - int side_start = signum(cross2(vec_b, (seg_start_a - seg_start_b).cast())); - int side_end = signum(cross2(vec_b, (seg_end_a - seg_start_b).cast())); + const Vec2crd vec_b = (seg_end_b - seg_start_b); + int side_start = signum(cross2(vec_b, (seg_start_a - seg_start_b))); + int side_end = signum(cross2(vec_b, (seg_end_a - seg_start_b))); 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(cross2(vec_b, this->line->dir.cast())) * side_start; + return signum(cross2(vec_b, this->line->dir)) * side_start; - const Vec2i64 vec_a = (seg_end_a - seg_start_a).cast(); - int side_start2 = signum(cross2(vec_a, (seg_start_b - seg_start_a).cast())); - int side_end2 = signum(cross2(vec_a, (seg_end_b - seg_start_a).cast())); + const Vec2crd vec_a = (seg_end_a - seg_start_a); + int side_start2 = signum(cross2(vec_a, (seg_start_b - seg_start_a))); + int side_end2 = signum(cross2(vec_a, (seg_end_b - seg_start_a))); 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(cross2(this->line->dir.cast(), vec_a)) * side_start2; + return signum(cross2(this->line->dir, 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 = cross2(this->line->dir.cast(), vec_a); - int64_t denom2 = cross2(this->line->dir.cast(), vec_b); - Vec2i64 vx_a = (seg_start_a - this->line->pos).cast(); - Vec2i64 vx_b = (seg_start_b - this->line->pos).cast(); + int64_t denom1 = cross2(this->line->dir, vec_a); + int64_t denom2 = cross2(this->line->dir, vec_b); + Vec2crd vx_a = (seg_start_a - this->line->pos); + Vec2crd vx_b = (seg_start_b - this->line->pos); 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); @@ -330,7 +330,7 @@ bool SegmentIntersection::operator<(const SegmentIntersection &other) const #ifdef _DEBUG Point p1 = this->pos(); Point p2 = other.pos(); - int64_t d = this->line->dir.cast().dot((p2 - p1).cast()); + int64_t d = this->line->dir.dot((p2 - p1)); #endif /* _DEBUG */ int ordering = this->ordering_along_line(other); #ifdef _DEBUG @@ -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 = sil.dir.cast().dot((p2 - p1).cast()); + int64_t d = sil.dir.dot((p2 - p1)); assert(d >= - int64_t(SCALED_EPSILON)); } #endif /* _DEBUG */ diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index fe13c1a59..a6550aac2 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -1913,11 +1913,12 @@ static Points::iterator project_point_to_polygon_and_insert(Polygon &polygon, co const Point &p2 = polygon.points[j]; 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)); + //going into double because coord*coord can overflow. + const double l2_seg = double(v_seg(0)) * double(v_seg(0)) + double(v_seg(1)) * double(v_seg(1)); + double t_pt = double(v_seg(0)) * double(v_pt(0)) + double(v_seg(1)) * double(v_pt(1)); if (t_pt < 0) { // Closest to p1. - double dabs = sqrt(int64_t(v_pt(0)) * int64_t(v_pt(0)) + int64_t(v_pt(1)) * int64_t(v_pt(1))); + double dabs = sqrt(double(v_pt(0)) * double(v_pt(0)) + double(v_pt(1)) * double(v_pt(1))); if (dabs < d_min) { d_min = dabs; i_min = i; @@ -1930,7 +1931,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(1)) * int64_t(v_pt(0)) - int64_t(v_seg(0)) * int64_t(v_pt(1)); + double d_seg = double(v_seg(1)) * double(v_pt(0)) - double(v_seg(0)) * double(v_pt(1)); double d = double(d_seg) / sqrt(double(l2_seg)); double dabs = std::abs(d); if (dabs < d_min) { @@ -2010,9 +2011,9 @@ std::vector polygon_angles_at_vertices(const Polygon &polygon, const std: const Point &p2 = polygon.points[idx_next]; 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))); + double dot = double(v1(0))*double(v2(0)) + double(v1(1))*double(v2(1)); + double cross = double(v1(0))*double(v2(1)) - double(v1(1))*double(v2(0)); + float angle = float(atan2(cross, dot)); angles[idx_curr] = angle; } diff --git a/src/libslic3r/Geometry.hpp b/src/libslic3r/Geometry.hpp index 87d19d4a5..e08bcf063 100644 --- a/src/libslic3r/Geometry.hpp +++ b/src/libslic3r/Geometry.hpp @@ -25,14 +25,24 @@ enum Orientation // As the points are limited to 30 bits + signum, // the temporaries u, v, w are limited to 61 bits + signum, // and d is limited to 63 bits + signum and we are good. -static inline Orientation orient(const Point &a, const Point &b, const Point &c) -{ +//note: now coord_t is int64_t, so the algorithm is now adjusted to fallback to double is too big. +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(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); + // BOOST_STATIC_ASSERT(sizeof(coord_t) == sizeof(int64_t)); + if (a.x() <= 0xffffffff && b.x() <= 0xffffffff && c.x() <= 0xffffffff && + a.y() <= 0xffffffff && b.y() <= 0xffffffff && c.y() <= 0xffffffff) { + 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); + } else { + double u = double(b(0)) * double(c(1)) - double(b(1)) * double(c(0)); + double v = double(a(0)) * double(c(1)) - double(a(1)) * double(c(0)); + double w = double(a(0)) * double(b(1)) - double(a(1)) * double(b(0)); + double d = u - v + w; + return (d > 0) ? ORIENTATION_CCW : ((d == 0) ? ORIENTATION_COLINEAR : ORIENTATION_CW); + } } // Return orientation of the polygon by checking orientation of the left bottom corner of the polygon diff --git a/src/libslic3r/libslic3r.h b/src/libslic3r/libslic3r.h index 922a8a45f..1dbffbd26 100644 --- a/src/libslic3r/libslic3r.h +++ b/src/libslic3r/libslic3r.h @@ -20,7 +20,7 @@ #include "Technologies.hpp" -typedef int32_t coord_t; +typedef int64_t coord_t; typedef double coordf_t; //FIXME This epsilon value is used for many non-related purposes: