mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 20:21:12 -06:00 
			
		
		
		
	Try to deal with infinite bin.
This commit is contained in:
		
							parent
							
								
									87c5e9bbaa
								
							
						
					
					
						commit
						320f2ecefd
					
				
					 1 changed files with 280 additions and 252 deletions
				
			
		|  | @ -30,11 +30,11 @@ template<class Shape> struct ShapeTag { using Type = typename Shape::Tag; }; | |||
| template<class S> using Tag = typename ShapeTag<remove_cvref_t<S>>::Type; | ||||
| 
 | ||||
| /// Meta function to derive the contour type for a polygon which could be itself
 | ||||
| template<class RawShape> struct ContourType { using Type = RawShape; }; | ||||
| template<class S> struct ContourType { using Type = S; }; | ||||
| 
 | ||||
| /// TContour<RawShape> instead of `typename ContourType<RawShape>::type`
 | ||||
| template<class RawShape> | ||||
| using TContour = typename ContourType<remove_cvref_t<RawShape>>::Type; | ||||
| /// TContour<S> instead of `typename ContourType<S>::type`
 | ||||
| template<class S> | ||||
| using TContour = typename ContourType<remove_cvref_t<S>>::Type; | ||||
| 
 | ||||
| /// Getting the type of point structure used by a shape.
 | ||||
| template<class Sh> struct PointType {  | ||||
|  | @ -83,12 +83,12 @@ template<class I> struct ComputeType<I, true> { | |||
| template<class T> using TCompute = typename ComputeType<remove_cvref_t<T>>::Type; | ||||
| 
 | ||||
| /// A meta function to derive a container type for holes in a polygon
 | ||||
| template<class RawShape> | ||||
| struct HolesContainer { using Type = std::vector<TContour<RawShape>>;  }; | ||||
| template<class S> | ||||
| struct HolesContainer { using Type = std::vector<TContour<S>>;  }; | ||||
| 
 | ||||
| /// Shorthand for `typename HolesContainer<RawShape>::Type`
 | ||||
| template<class RawShape> | ||||
| using THolesContainer = typename HolesContainer<remove_cvref_t<RawShape>>::Type; | ||||
| /// Shorthand for `typename HolesContainer<S>::Type`
 | ||||
| template<class S> | ||||
| using THolesContainer = typename HolesContainer<remove_cvref_t<S>>::Type; | ||||
| 
 | ||||
| /*
 | ||||
|  * TContour, TPoint, TCoord and TCompute should be usable for any type for which | ||||
|  | @ -132,7 +132,7 @@ enum class Orientation { | |||
|     COUNTER_CLOCKWISE | ||||
| }; | ||||
| 
 | ||||
| template<class RawShape> | ||||
| template<class S> | ||||
| struct OrientationType { | ||||
| 
 | ||||
|     // Default Polygon orientation that the library expects
 | ||||
|  | @ -146,45 +146,46 @@ template<class T> inline /*constexpr*/ bool is_clockwise() { | |||
| 
 | ||||
| /**
 | ||||
|  * \brief A point pair base class for other point pairs (segment, box, ...). | ||||
|  * \tparam RawPoint The actual point type to use. | ||||
|  * \tparam P The actual point type to use. | ||||
|  */ | ||||
| template<class RawPoint> | ||||
| template<class P> | ||||
| struct PointPair { | ||||
|     RawPoint p1; | ||||
|     RawPoint p2; | ||||
|     P p1; | ||||
|     P p2; | ||||
| }; | ||||
| 
 | ||||
| /**
 | ||||
|  * \brief An abstraction of a box; | ||||
|  */ | ||||
| template<class RawPoint> | ||||
| class _Box: PointPair<RawPoint> { | ||||
|     using PointPair<RawPoint>::p1; | ||||
|     using PointPair<RawPoint>::p2; | ||||
| template<class P> | ||||
| class _Box: PointPair<P> { | ||||
|     using PointPair<P>::p1; | ||||
|     using PointPair<P>::p2; | ||||
| public: | ||||
| 
 | ||||
|     using Tag = BoxTag; | ||||
|     using PointType = RawPoint; | ||||
|     using PointType = P; | ||||
| 
 | ||||
|     inline _Box() = default; | ||||
|     inline _Box(const RawPoint& p, const RawPoint& pp): | ||||
|         PointPair<RawPoint>({p, pp}) {} | ||||
|     inline _Box(const P& p = {TCoord<P>(0), TCoord<P>(0)}); | ||||
|     inline _Box(const P& p, const P& pp): | ||||
|         PointPair<P>({p, pp}) {} | ||||
|      | ||||
|     inline _Box(TCoord<P> width, TCoord<P> height, | ||||
|                 const P& p = {TCoord<P>(0), TCoord<P>(0)});/*:
 | ||||
|         _Box(p, P{width, height}) {}*/ | ||||
| 
 | ||||
|     inline _Box(TCoord<RawPoint> width, TCoord<RawPoint> height): | ||||
|         _Box(RawPoint{0, 0}, RawPoint{width, height}) {} | ||||
|     inline const P& minCorner() const BP2D_NOEXCEPT { return p1; } | ||||
|     inline const P& maxCorner() const BP2D_NOEXCEPT { return p2; } | ||||
| 
 | ||||
|     inline const RawPoint& minCorner() const BP2D_NOEXCEPT { return p1; } | ||||
|     inline const RawPoint& maxCorner() const BP2D_NOEXCEPT { return p2; } | ||||
|     inline P& minCorner() BP2D_NOEXCEPT { return p1; } | ||||
|     inline P& maxCorner() BP2D_NOEXCEPT { return p2; } | ||||
| 
 | ||||
|     inline RawPoint& minCorner() BP2D_NOEXCEPT { return p1; } | ||||
|     inline RawPoint& maxCorner() BP2D_NOEXCEPT { return p2; } | ||||
|     inline TCoord<P> width() const BP2D_NOEXCEPT; | ||||
|     inline TCoord<P> height() const BP2D_NOEXCEPT; | ||||
| 
 | ||||
|     inline TCoord<RawPoint> width() const BP2D_NOEXCEPT; | ||||
|     inline TCoord<RawPoint> height() const BP2D_NOEXCEPT; | ||||
|     inline P center() const BP2D_NOEXCEPT; | ||||
| 
 | ||||
|     inline RawPoint center() const BP2D_NOEXCEPT; | ||||
| 
 | ||||
|     template<class Unit = TCompute<RawPoint>>  | ||||
|     template<class Unit = TCompute<P>>  | ||||
|     inline Unit area() const BP2D_NOEXCEPT { | ||||
|         return Unit(width())*height(); | ||||
|     } | ||||
|  | @ -194,20 +195,20 @@ template<class S> struct PointType<_Box<S>> { | |||
|     using Type = typename _Box<S>::PointType;  | ||||
| }; | ||||
| 
 | ||||
| template<class RawPoint> | ||||
| template<class P> | ||||
| class _Circle { | ||||
|     RawPoint center_; | ||||
|     P center_; | ||||
|     double radius_ = 0; | ||||
| public: | ||||
| 
 | ||||
|     using Tag = CircleTag; | ||||
|     using PointType = RawPoint; | ||||
|     using PointType = P; | ||||
| 
 | ||||
|     _Circle() = default; | ||||
|     _Circle(const RawPoint& center, double r): center_(center), radius_(r) {} | ||||
|     _Circle(const P& center, double r): center_(center), radius_(r) {} | ||||
| 
 | ||||
|     inline const RawPoint& center() const BP2D_NOEXCEPT { return center_; } | ||||
|     inline void center(const RawPoint& c) { center_ = c; } | ||||
|     inline const P& center() const BP2D_NOEXCEPT { return center_; } | ||||
|     inline void center(const P& c) { center_ = c; } | ||||
| 
 | ||||
|     inline double radius() const BP2D_NOEXCEPT { return radius_; } | ||||
|     inline void radius(double r) { radius_ = r; } | ||||
|  | @ -224,38 +225,38 @@ template<class S> struct PointType<_Circle<S>> { | |||
| /**
 | ||||
|  * \brief An abstraction of a directed line segment with two points. | ||||
|  */ | ||||
| template<class RawPoint> | ||||
| class _Segment: PointPair<RawPoint> { | ||||
|     using PointPair<RawPoint>::p1; | ||||
|     using PointPair<RawPoint>::p2; | ||||
| template<class P> | ||||
| class _Segment: PointPair<P> { | ||||
|     using PointPair<P>::p1; | ||||
|     using PointPair<P>::p2; | ||||
|     mutable Radians angletox_ = std::nan(""); | ||||
| public: | ||||
| 
 | ||||
|     using PointType = RawPoint; | ||||
|     using PointType = P; | ||||
| 
 | ||||
|     inline _Segment() = default; | ||||
| 
 | ||||
|     inline _Segment(const RawPoint& p, const RawPoint& pp): | ||||
|         PointPair<RawPoint>({p, pp}) {} | ||||
|     inline _Segment(const P& p, const P& pp): | ||||
|         PointPair<P>({p, pp}) {} | ||||
| 
 | ||||
|     /**
 | ||||
|      * @brief Get the first point. | ||||
|      * @return Returns the starting point. | ||||
|      */ | ||||
|     inline const RawPoint& first() const BP2D_NOEXCEPT { return p1; } | ||||
|     inline const P& first() const BP2D_NOEXCEPT { return p1; } | ||||
| 
 | ||||
|     /**
 | ||||
|      * @brief The end point. | ||||
|      * @return Returns the end point of the segment. | ||||
|      */ | ||||
|     inline const RawPoint& second() const BP2D_NOEXCEPT { return p2; } | ||||
|     inline const P& second() const BP2D_NOEXCEPT { return p2; } | ||||
| 
 | ||||
|     inline void first(const RawPoint& p) BP2D_NOEXCEPT | ||||
|     inline void first(const P& p) BP2D_NOEXCEPT | ||||
|     { | ||||
|         angletox_ = std::nan(""); p1 = p; | ||||
|     } | ||||
| 
 | ||||
|     inline void second(const RawPoint& p) BP2D_NOEXCEPT { | ||||
|     inline void second(const P& p) BP2D_NOEXCEPT { | ||||
|         angletox_ = std::nan(""); p2 = p; | ||||
|     } | ||||
| 
 | ||||
|  | @ -263,7 +264,7 @@ public: | |||
|     inline Radians angleToXaxis() const; | ||||
| 
 | ||||
|     /// The length of the segment in the measure of the coordinate system.
 | ||||
|     template<class Unit = TCompute<RawPoint>> inline Unit sqlength() const; | ||||
|     template<class Unit = TCompute<P>> inline Unit sqlength() const; | ||||
|      | ||||
| }; | ||||
| 
 | ||||
|  | @ -275,42 +276,42 @@ template<class S> struct PointType<_Segment<S>> { | |||
| // used in friend declarations.
 | ||||
| namespace pointlike { | ||||
| 
 | ||||
| template<class RawPoint> | ||||
| inline TCoord<RawPoint> x(const RawPoint& p) | ||||
| template<class P> | ||||
| inline TCoord<P> x(const P& p) | ||||
| { | ||||
|     return p.x(); | ||||
| } | ||||
| 
 | ||||
| template<class RawPoint> | ||||
| inline TCoord<RawPoint> y(const RawPoint& p) | ||||
| template<class P> | ||||
| inline TCoord<P> y(const P& p) | ||||
| { | ||||
|     return p.y(); | ||||
| } | ||||
| 
 | ||||
| template<class RawPoint> | ||||
| inline TCoord<RawPoint>& x(RawPoint& p) | ||||
| template<class P> | ||||
| inline TCoord<P>& x(P& p) | ||||
| { | ||||
|     return p.x(); | ||||
| } | ||||
| 
 | ||||
| template<class RawPoint> | ||||
| inline TCoord<RawPoint>& y(RawPoint& p) | ||||
| template<class P> | ||||
| inline TCoord<P>& y(P& p) | ||||
| { | ||||
|     return p.y(); | ||||
| } | ||||
| 
 | ||||
| template<class RawPoint, class Unit = TCompute<RawPoint>> | ||||
| inline Unit squaredDistance(const RawPoint& p1, const RawPoint& p2) | ||||
| template<class P, class Unit = TCompute<P>> | ||||
| inline Unit squaredDistance(const P& p1, const P& p2) | ||||
| { | ||||
|     auto x1 = Unit(x(p1)), y1 = Unit(y(p1)), x2 = Unit(x(p2)), y2 = Unit(y(p2)); | ||||
|     Unit a = (x2 - x1), b = (y2 - y1); | ||||
|     return a * a + b * b; | ||||
| } | ||||
| 
 | ||||
| template<class RawPoint> | ||||
| inline double distance(const RawPoint& p1, const RawPoint& p2) | ||||
| template<class P> | ||||
| inline double distance(const P& p1, const P& p2) | ||||
| { | ||||
|     return std::sqrt(squaredDistance<RawPoint, double>(p1, p2)); | ||||
|     return std::sqrt(squaredDistance<P, double>(p1, p2)); | ||||
| } | ||||
| 
 | ||||
| // create perpendicular vector
 | ||||
|  | @ -339,9 +340,9 @@ inline Unit magnsq(const Pt& p) | |||
|     return  Unit(x(p)) * x(p) + Unit(y(p)) * y(p); | ||||
| } | ||||
| 
 | ||||
| template<class RawPoint, class Unit = TCompute<RawPoint>> | ||||
| template<class P, class Unit = TCompute<P>> | ||||
| inline std::pair<Unit, bool> horizontalDistance( | ||||
|         const RawPoint& p, const _Segment<RawPoint>& s) | ||||
|         const P& p, const _Segment<P>& s) | ||||
| { | ||||
|     namespace pl = pointlike; | ||||
|     auto x = Unit(pl::x(p)), y = Unit(pl::y(p)); | ||||
|  | @ -364,9 +365,9 @@ inline std::pair<Unit, bool> horizontalDistance( | |||
|     return {ret, true}; | ||||
| } | ||||
| 
 | ||||
| template<class RawPoint, class Unit = TCompute<RawPoint>> | ||||
| template<class P, class Unit = TCompute<P>> | ||||
| inline std::pair<Unit, bool> verticalDistance( | ||||
|         const RawPoint& p, const _Segment<RawPoint>& s) | ||||
|         const P& p, const _Segment<P>& s) | ||||
| { | ||||
|     namespace pl = pointlike; | ||||
|     auto x = Unit(pl::x(p)), y = Unit(pl::y(p)); | ||||
|  | @ -390,42 +391,42 @@ inline std::pair<Unit, bool> verticalDistance( | |||
| } | ||||
| } | ||||
| 
 | ||||
| template<class RawPoint> | ||||
| TCoord<RawPoint> _Box<RawPoint>::width() const BP2D_NOEXCEPT | ||||
| template<class P> | ||||
| TCoord<P> _Box<P>::width() const BP2D_NOEXCEPT | ||||
| { | ||||
|     return pointlike::x(maxCorner()) - pointlike::x(minCorner()); | ||||
| } | ||||
| 
 | ||||
| template<class RawPoint> | ||||
| TCoord<RawPoint> _Box<RawPoint>::height() const BP2D_NOEXCEPT | ||||
| template<class P> | ||||
| TCoord<P> _Box<P>::height() const BP2D_NOEXCEPT | ||||
| { | ||||
|     return pointlike::y(maxCorner()) - pointlike::y(minCorner()); | ||||
| } | ||||
| 
 | ||||
| template<class RawPoint> | ||||
| TCoord<RawPoint> getX(const RawPoint& p) { return pointlike::x<RawPoint>(p); } | ||||
| template<class P> | ||||
| TCoord<P> getX(const P& p) { return pointlike::x<P>(p); } | ||||
| 
 | ||||
| template<class RawPoint> | ||||
| TCoord<RawPoint> getY(const RawPoint& p) { return pointlike::y<RawPoint>(p); } | ||||
| template<class P> | ||||
| TCoord<P> getY(const P& p) { return pointlike::y<P>(p); } | ||||
| 
 | ||||
| template<class RawPoint> | ||||
| void setX(RawPoint& p, const TCoord<RawPoint>& val) | ||||
| template<class P> | ||||
| void setX(P& p, const TCoord<P>& val) | ||||
| { | ||||
|     pointlike::x<RawPoint>(p) = val; | ||||
|     pointlike::x<P>(p) = val; | ||||
| } | ||||
| 
 | ||||
| template<class RawPoint> | ||||
| void setY(RawPoint& p, const TCoord<RawPoint>& val) | ||||
| template<class P> | ||||
| void setY(P& p, const TCoord<P>& val) | ||||
| { | ||||
|     pointlike::y<RawPoint>(p) = val; | ||||
|     pointlike::y<P>(p) = val; | ||||
| } | ||||
| 
 | ||||
| template<class RawPoint> | ||||
| inline Radians _Segment<RawPoint>::angleToXaxis() const | ||||
| template<class P> | ||||
| inline Radians _Segment<P>::angleToXaxis() const | ||||
| { | ||||
|     if(std::isnan(static_cast<double>(angletox_))) { | ||||
|         TCoord<RawPoint> dx = getX(second()) - getX(first()); | ||||
|         TCoord<RawPoint> dy = getY(second()) - getY(first()); | ||||
|         TCoord<P> dx = getX(second()) - getX(first()); | ||||
|         TCoord<P> dy = getY(second()) - getY(first()); | ||||
| 
 | ||||
|         double a = std::atan2(dy, dx); | ||||
|         auto s = std::signbit(a); | ||||
|  | @ -436,21 +437,48 @@ inline Radians _Segment<RawPoint>::angleToXaxis() const | |||
|     return angletox_; | ||||
| } | ||||
| 
 | ||||
| template<class RawPoint> | ||||
| template<class P> | ||||
| template<class Unit> | ||||
| inline Unit _Segment<RawPoint>::sqlength() const | ||||
| inline Unit _Segment<P>::sqlength() const | ||||
| { | ||||
|     return pointlike::squaredDistance<RawPoint, Unit>(first(), second()); | ||||
|     return pointlike::squaredDistance<P, Unit>(first(), second()); | ||||
| } | ||||
| 
 | ||||
| template<class RawPoint> | ||||
| inline RawPoint _Box<RawPoint>::center() const BP2D_NOEXCEPT { | ||||
| template<class T> | ||||
| enable_if_t<std::is_floating_point<T>::value, T> modulo(const T &v, const T &m) | ||||
| { | ||||
|     return 0; | ||||
| } | ||||
| template<class T> | ||||
| enable_if_t<std::is_integral<T>::value, T> modulo(const T &v, const T &m) | ||||
| { | ||||
|     return v % m; | ||||
| } | ||||
| 
 | ||||
| template<class P> | ||||
| inline _Box<P>::_Box(TCoord<P> width, TCoord<P> height, const P & center) : | ||||
|     PointPair<P>({center - P{width / 2, height / 2}, | ||||
|                   center + P{width / 2, height / 2} + | ||||
|                       P{modulo(width, TCoord<P>(2)), | ||||
|                         modulo(height, TCoord<P>(2))}}) {} | ||||
| 
 | ||||
| template<class P> | ||||
| inline _Box<P>::_Box(const P& center) { | ||||
|     using C = TCoord<P>; | ||||
|     TCoord<P> M = std::max(getX(center), getY(center)) - | ||||
|                   std::numeric_limits<C>::lowest(); | ||||
|     maxCorner() = center + P{M, M}; | ||||
|     minCorner() = center - P{M, M};  | ||||
| } | ||||
| 
 | ||||
| template<class P> | ||||
| inline P _Box<P>::center() const BP2D_NOEXCEPT { | ||||
|     auto& minc = minCorner(); | ||||
|     auto& maxc = maxCorner(); | ||||
| 
 | ||||
|     using Coord = TCoord<RawPoint>; | ||||
|     using Coord = TCoord<P>; | ||||
| 
 | ||||
|     RawPoint ret =  { // No rounding here, we dont know if these are int coords
 | ||||
|     P ret =  { // No rounding here, we dont know if these are int coords
 | ||||
|         Coord( (getX(minc) + getX(maxc)) / Coord(2) ), | ||||
|         Coord( (getY(minc) + getY(maxc)) / Coord(2) ) | ||||
|     }; | ||||
|  | @ -467,76 +495,76 @@ enum class Formats { | |||
| // used in friend declarations and can be aliased at class scope.
 | ||||
| namespace shapelike { | ||||
| 
 | ||||
| template<class RawShape> | ||||
| inline RawShape create(const TContour<RawShape>& contour, | ||||
|                        const THolesContainer<RawShape>& holes) | ||||
| template<class S> | ||||
| inline S create(const TContour<S>& contour, | ||||
|                        const THolesContainer<S>& holes) | ||||
| { | ||||
|     return RawShape(contour, holes); | ||||
|     return S(contour, holes); | ||||
| } | ||||
| 
 | ||||
| template<class RawShape> | ||||
| inline RawShape create(TContour<RawShape>&& contour, | ||||
|                        THolesContainer<RawShape>&& holes) | ||||
| template<class S> | ||||
| inline S create(TContour<S>&& contour, | ||||
|                        THolesContainer<S>&& holes) | ||||
| { | ||||
|     return RawShape(contour, holes); | ||||
|     return S(contour, holes); | ||||
| } | ||||
| 
 | ||||
| template<class RawShape> | ||||
| inline RawShape create(const TContour<RawShape>& contour) | ||||
| template<class S> | ||||
| inline S create(const TContour<S>& contour) | ||||
| { | ||||
|     return create<RawShape>(contour, {}); | ||||
|     return create<S>(contour, {}); | ||||
| } | ||||
| 
 | ||||
| template<class RawShape> | ||||
| inline RawShape create(TContour<RawShape>&& contour) | ||||
| template<class S> | ||||
| inline S create(TContour<S>&& contour) | ||||
| { | ||||
|     return create<RawShape>(contour, {}); | ||||
|     return create<S>(contour, {}); | ||||
| } | ||||
| 
 | ||||
| template<class RawShape> | ||||
| inline THolesContainer<RawShape>& holes(RawShape& /*sh*/) | ||||
| template<class S> | ||||
| inline THolesContainer<S>& holes(S& /*sh*/) | ||||
| { | ||||
|     static THolesContainer<RawShape> empty; | ||||
|     static THolesContainer<S> empty; | ||||
|     return empty; | ||||
| } | ||||
| 
 | ||||
| template<class RawShape> | ||||
| inline const THolesContainer<RawShape>& holes(const RawShape& /*sh*/) | ||||
| template<class S> | ||||
| inline const THolesContainer<S>& holes(const S& /*sh*/) | ||||
| { | ||||
|     static THolesContainer<RawShape> empty; | ||||
|     static THolesContainer<S> empty; | ||||
|     return empty; | ||||
| } | ||||
| 
 | ||||
| template<class RawShape> | ||||
| inline TContour<RawShape>& hole(RawShape& sh, unsigned long idx) | ||||
| template<class S> | ||||
| inline TContour<S>& hole(S& sh, unsigned long idx) | ||||
| { | ||||
|     return holes(sh)[idx]; | ||||
| } | ||||
| 
 | ||||
| template<class RawShape> | ||||
| inline const TContour<RawShape>& hole(const RawShape& sh, unsigned long idx) | ||||
| template<class S> | ||||
| inline const TContour<S>& hole(const S& sh, unsigned long idx) | ||||
| { | ||||
|     return holes(sh)[idx]; | ||||
| } | ||||
| 
 | ||||
| template<class RawShape> | ||||
| inline size_t holeCount(const RawShape& sh) | ||||
| template<class S> | ||||
| inline size_t holeCount(const S& sh) | ||||
| { | ||||
|     return holes(sh).size(); | ||||
| } | ||||
| 
 | ||||
| template<class RawShape> | ||||
| inline TContour<RawShape>& contour(RawShape& sh) | ||||
| template<class S> | ||||
| inline TContour<S>& contour(S& sh) | ||||
| { | ||||
|     static_assert(always_false<RawShape>::value, | ||||
|     static_assert(always_false<S>::value, | ||||
|                   "shapelike::contour() unimplemented!"); | ||||
|     return sh; | ||||
| } | ||||
| 
 | ||||
| template<class RawShape> | ||||
| inline const TContour<RawShape>& contour(const RawShape& sh) | ||||
| template<class S> | ||||
| inline const TContour<S>& contour(const S& sh) | ||||
| { | ||||
|     static_assert(always_false<RawShape>::value, | ||||
|     static_assert(always_false<S>::value, | ||||
|                   "shapelike::contour() unimplemented!"); | ||||
|     return sh; | ||||
| } | ||||
|  | @ -548,71 +576,71 @@ inline void reserve(RawPath& p, size_t vertex_capacity, const PathTag&) | |||
|     p.reserve(vertex_capacity); | ||||
| } | ||||
| 
 | ||||
| template<class RawShape, class...Args> | ||||
| inline void addVertex(RawShape& sh, const PathTag&, Args...args) | ||||
| template<class S, class...Args> | ||||
| inline void addVertex(S& sh, const PathTag&, Args...args) | ||||
| { | ||||
|     sh.emplace_back(std::forward<Args>(args)...); | ||||
| } | ||||
| 
 | ||||
| template<class RawShape, class Fn> | ||||
| inline void foreachVertex(RawShape& sh, Fn fn, const PathTag&) { | ||||
| template<class S, class Fn> | ||||
| inline void foreachVertex(S& sh, Fn fn, const PathTag&) { | ||||
|     std::for_each(sh.begin(), sh.end(), fn); | ||||
| } | ||||
| 
 | ||||
| template<class RawShape> | ||||
| inline typename RawShape::iterator begin(RawShape& sh, const PathTag&) | ||||
| template<class S> | ||||
| inline typename S::iterator begin(S& sh, const PathTag&) | ||||
| { | ||||
|     return sh.begin(); | ||||
| } | ||||
| 
 | ||||
| template<class RawShape> | ||||
| inline typename RawShape::iterator end(RawShape& sh, const PathTag&) | ||||
| template<class S> | ||||
| inline typename S::iterator end(S& sh, const PathTag&) | ||||
| { | ||||
|     return sh.end(); | ||||
| } | ||||
| 
 | ||||
| template<class RawShape> | ||||
| inline typename RawShape::const_iterator | ||||
| cbegin(const RawShape& sh, const PathTag&) | ||||
| template<class S> | ||||
| inline typename S::const_iterator | ||||
| cbegin(const S& sh, const PathTag&) | ||||
| { | ||||
|     return sh.cbegin(); | ||||
| } | ||||
| 
 | ||||
| template<class RawShape> | ||||
| inline typename RawShape::const_iterator | ||||
| cend(const RawShape& sh, const PathTag&) | ||||
| template<class S> | ||||
| inline typename S::const_iterator | ||||
| cend(const S& sh, const PathTag&) | ||||
| { | ||||
|     return sh.cend(); | ||||
| } | ||||
| 
 | ||||
| template<class RawShape> | ||||
| inline std::string toString(const RawShape& /*sh*/) | ||||
| template<class S> | ||||
| inline std::string toString(const S& /*sh*/) | ||||
| { | ||||
|     return ""; | ||||
| } | ||||
| 
 | ||||
| template<Formats, class RawShape> | ||||
| inline std::string serialize(const RawShape& /*sh*/, double /*scale*/=1) | ||||
| template<Formats, class S> | ||||
| inline std::string serialize(const S& /*sh*/, double /*scale*/=1) | ||||
| { | ||||
|     static_assert(always_false<RawShape>::value, | ||||
|     static_assert(always_false<S>::value, | ||||
|                   "shapelike::serialize() unimplemented!"); | ||||
|     return ""; | ||||
| } | ||||
| 
 | ||||
| template<Formats, class RawShape> | ||||
| inline void unserialize(RawShape& /*sh*/, const std::string& /*str*/) | ||||
| template<Formats, class S> | ||||
| inline void unserialize(S& /*sh*/, const std::string& /*str*/) | ||||
| { | ||||
|     static_assert(always_false<RawShape>::value, | ||||
|     static_assert(always_false<S>::value, | ||||
|                   "shapelike::unserialize() unimplemented!"); | ||||
| } | ||||
| 
 | ||||
| template<class Cntr, class Unit = double> | ||||
| inline Unit area(const Cntr& poly, const PathTag& ); | ||||
| 
 | ||||
| template<class RawShape> | ||||
| inline bool intersects(const RawShape& /*sh*/, const RawShape& /*sh*/) | ||||
| template<class S> | ||||
| inline bool intersects(const S& /*sh*/, const S& /*sh*/) | ||||
| { | ||||
|     static_assert(always_false<RawShape>::value, | ||||
|     static_assert(always_false<S>::value, | ||||
|                   "shapelike::intersects() unimplemented!"); | ||||
|     return false; | ||||
| } | ||||
|  | @ -633,29 +661,29 @@ inline bool isInside(const TGuest&, const THost&, | |||
|     return false; | ||||
| } | ||||
| 
 | ||||
| template<class RawShape> | ||||
| inline bool touches( const RawShape& /*shape*/, | ||||
|                      const RawShape& /*shape*/) | ||||
| template<class S> | ||||
| inline bool touches( const S& /*shape*/, | ||||
|                      const S& /*shape*/) | ||||
| { | ||||
|     static_assert(always_false<RawShape>::value, | ||||
|     static_assert(always_false<S>::value, | ||||
|                   "shapelike::touches(shape, shape) unimplemented!"); | ||||
|     return false; | ||||
| } | ||||
| 
 | ||||
| template<class RawShape> | ||||
| inline bool touches( const TPoint<RawShape>& /*point*/, | ||||
|                      const RawShape& /*shape*/) | ||||
| template<class S> | ||||
| inline bool touches( const TPoint<S>& /*point*/, | ||||
|                      const S& /*shape*/) | ||||
| { | ||||
|     static_assert(always_false<RawShape>::value, | ||||
|     static_assert(always_false<S>::value, | ||||
|                   "shapelike::touches(point, shape) unimplemented!"); | ||||
|     return false; | ||||
| } | ||||
| 
 | ||||
| template<class RawShape> | ||||
| inline _Box<TPoint<RawShape>> boundingBox(const RawShape& /*sh*/, | ||||
| template<class S> | ||||
| inline _Box<TPoint<S>> boundingBox(const S& /*sh*/, | ||||
|                                           const PathTag&) | ||||
| { | ||||
|     static_assert(always_false<RawShape>::value, | ||||
|     static_assert(always_false<S>::value, | ||||
|                   "shapelike::boundingBox(shape) unimplemented!"); | ||||
| } | ||||
| 
 | ||||
|  | @ -667,34 +695,34 @@ boundingBox(const RawShapes& /*sh*/, const MultiPolygonTag&) | |||
|                   "shapelike::boundingBox(shapes) unimplemented!"); | ||||
| } | ||||
| 
 | ||||
| template<class RawShape> | ||||
| inline RawShape convexHull(const RawShape& sh, const PathTag&); | ||||
| template<class S> | ||||
| inline S convexHull(const S& sh, const PathTag&); | ||||
| 
 | ||||
| template<class RawShapes, class S = typename RawShapes::value_type> | ||||
| inline S convexHull(const RawShapes& sh, const MultiPolygonTag&); | ||||
| 
 | ||||
| template<class RawShape> | ||||
| inline void rotate(RawShape& /*sh*/, const Radians& /*rads*/) | ||||
| template<class S> | ||||
| inline void rotate(S& /*sh*/, const Radians& /*rads*/) | ||||
| { | ||||
|     static_assert(always_false<RawShape>::value, | ||||
|     static_assert(always_false<S>::value, | ||||
|                   "shapelike::rotate() unimplemented!"); | ||||
| } | ||||
| 
 | ||||
| template<class RawShape, class RawPoint> | ||||
| inline void translate(RawShape& /*sh*/, const RawPoint& /*offs*/) | ||||
| template<class S, class P> | ||||
| inline void translate(S& /*sh*/, const P& /*offs*/) | ||||
| { | ||||
|     static_assert(always_false<RawShape>::value, | ||||
|     static_assert(always_false<S>::value, | ||||
|                   "shapelike::translate() unimplemented!"); | ||||
| } | ||||
| 
 | ||||
| template<class RawShape> | ||||
| inline void offset(RawShape& /*sh*/, TCoord<TPoint<RawShape>> /*distance*/) | ||||
| template<class S> | ||||
| inline void offset(S& /*sh*/, TCoord<TPoint<S>> /*distance*/) | ||||
| { | ||||
|     dout() << "The current geometry backend does not support offsetting!\n"; | ||||
| } | ||||
| 
 | ||||
| template<class RawShape> | ||||
| inline std::pair<bool, std::string> isValid(const RawShape& /*sh*/) | ||||
| template<class S> | ||||
| inline std::pair<bool, std::string> isValid(const S& /*sh*/) | ||||
| { | ||||
|     return {false, "shapelike::isValid() unimplemented!"}; | ||||
| } | ||||
|  | @ -735,56 +763,56 @@ template<class RawPath> inline bool isConvex(const RawPath& sh, const PathTag&) | |||
| // No need to implement these
 | ||||
| // *****************************************************************************
 | ||||
| 
 | ||||
| template<class RawShape> | ||||
| inline typename TContour<RawShape>::iterator | ||||
| begin(RawShape& sh, const PolygonTag&) | ||||
| template<class S> | ||||
| inline typename TContour<S>::iterator | ||||
| begin(S& sh, const PolygonTag&) | ||||
| { | ||||
|     return begin(contour(sh), PathTag()); | ||||
| } | ||||
| 
 | ||||
| template<class RawShape> // Tag dispatcher
 | ||||
| inline auto begin(RawShape& sh) -> decltype(begin(sh, Tag<RawShape>())) | ||||
| template<class S> // Tag dispatcher
 | ||||
| inline auto begin(S& sh) -> decltype(begin(sh, Tag<S>())) | ||||
| { | ||||
|     return begin(sh, Tag<RawShape>()); | ||||
|     return begin(sh, Tag<S>()); | ||||
| } | ||||
| 
 | ||||
| template<class RawShape> | ||||
| inline typename TContour<RawShape>::const_iterator | ||||
| cbegin(const RawShape& sh, const PolygonTag&) | ||||
| template<class S> | ||||
| inline typename TContour<S>::const_iterator | ||||
| cbegin(const S& sh, const PolygonTag&) | ||||
| { | ||||
|     return cbegin(contour(sh), PathTag()); | ||||
| } | ||||
| 
 | ||||
| template<class RawShape> // Tag dispatcher
 | ||||
| inline auto cbegin(const RawShape& sh) -> decltype(cbegin(sh, Tag<RawShape>())) | ||||
| template<class S> // Tag dispatcher
 | ||||
| inline auto cbegin(const S& sh) -> decltype(cbegin(sh, Tag<S>())) | ||||
| { | ||||
|     return cbegin(sh, Tag<RawShape>()); | ||||
|     return cbegin(sh, Tag<S>()); | ||||
| } | ||||
| 
 | ||||
| template<class RawShape> | ||||
| inline typename TContour<RawShape>::iterator | ||||
| end(RawShape& sh, const PolygonTag&) | ||||
| template<class S> | ||||
| inline typename TContour<S>::iterator | ||||
| end(S& sh, const PolygonTag&) | ||||
| { | ||||
|     return end(contour(sh), PathTag()); | ||||
| } | ||||
| 
 | ||||
| template<class RawShape> // Tag dispatcher
 | ||||
| inline auto end(RawShape& sh) -> decltype(begin(sh, Tag<RawShape>())) | ||||
| template<class S> // Tag dispatcher
 | ||||
| inline auto end(S& sh) -> decltype(begin(sh, Tag<S>())) | ||||
| { | ||||
|     return end(sh, Tag<RawShape>()); | ||||
|     return end(sh, Tag<S>()); | ||||
| } | ||||
| 
 | ||||
| template<class RawShape> | ||||
| inline typename TContour<RawShape>::const_iterator | ||||
| cend(const RawShape& sh, const PolygonTag&) | ||||
| template<class S> | ||||
| inline typename TContour<S>::const_iterator | ||||
| cend(const S& sh, const PolygonTag&) | ||||
| { | ||||
|     return cend(contour(sh), PathTag()); | ||||
| } | ||||
| 
 | ||||
| template<class RawShape> // Tag dispatcher
 | ||||
| inline auto cend(const RawShape& sh) -> decltype(cend(sh, Tag<RawShape>())) | ||||
| template<class S> // Tag dispatcher
 | ||||
| inline auto cend(const S& sh) -> decltype(cend(sh, Tag<S>())) | ||||
| { | ||||
|     return cend(sh, Tag<RawShape>()); | ||||
|     return cend(sh, Tag<S>()); | ||||
| } | ||||
| 
 | ||||
| template<class It> std::reverse_iterator<It> _backward(It iter) { | ||||
|  | @ -817,8 +845,8 @@ template<class P> TPoint<P> back (const P& p) { | |||
| } | ||||
| 
 | ||||
| // Optional, does nothing by default
 | ||||
| template<class RawShape> | ||||
| inline void reserve(RawShape& sh, size_t vertex_capacity, const PolygonTag&) | ||||
| template<class S> | ||||
| inline void reserve(S& sh, size_t vertex_capacity, const PolygonTag&) | ||||
| { | ||||
|     reserve(contour(sh), vertex_capacity, PathTag()); | ||||
| } | ||||
|  | @ -828,20 +856,20 @@ inline void reserve(T& sh, size_t vertex_capacity) { | |||
|     reserve(sh, vertex_capacity, Tag<T>()); | ||||
| } | ||||
| 
 | ||||
| template<class RawShape, class...Args> | ||||
| inline void addVertex(RawShape& sh, const PolygonTag&, Args...args) | ||||
| template<class S, class...Args> | ||||
| inline void addVertex(S& sh, const PolygonTag&, Args...args) | ||||
| { | ||||
|     addVertex(contour(sh), PathTag(), std::forward<Args>(args)...); | ||||
| } | ||||
| 
 | ||||
| template<class RawShape, class...Args> // Tag dispatcher
 | ||||
| inline void addVertex(RawShape& sh, Args...args) | ||||
| template<class S, class...Args> // Tag dispatcher
 | ||||
| inline void addVertex(S& sh, Args...args) | ||||
| { | ||||
|     addVertex(sh, Tag<RawShape>(), std::forward<Args>(args)...); | ||||
|     addVertex(sh, Tag<S>(), std::forward<Args>(args)...); | ||||
| } | ||||
| 
 | ||||
| template<class RawShape> | ||||
| inline _Box<TPoint<RawShape>> boundingBox(const RawShape& poly, const PolygonTag&) | ||||
| template<class S> | ||||
| inline _Box<TPoint<S>> boundingBox(const S& poly, const PolygonTag&) | ||||
| { | ||||
|     return boundingBox(contour(poly), PathTag()); | ||||
| } | ||||
|  | @ -938,40 +966,40 @@ template<class S> inline double area(const S& poly, const PolygonTag& ) | |||
|     }); | ||||
| } | ||||
| 
 | ||||
| template<class RawShape> // Dispatching function
 | ||||
| inline double area(const RawShape& sh) | ||||
| template<class S> // Dispatching function
 | ||||
| inline double area(const S& sh) | ||||
| { | ||||
|     return area(sh, Tag<RawShape>()); | ||||
|     return area(sh, Tag<S>()); | ||||
| } | ||||
| 
 | ||||
| template<class RawShapes> | ||||
| inline double area(const RawShapes& shapes, const MultiPolygonTag&) | ||||
| { | ||||
|     using RawShape = typename RawShapes::value_type; | ||||
|     using S = typename RawShapes::value_type; | ||||
|     return std::accumulate(shapes.begin(), shapes.end(), 0.0, | ||||
|                     [](double a, const RawShape& b) { | ||||
|                     [](double a, const S& b) { | ||||
|         return a += area(b); | ||||
|     }); | ||||
| } | ||||
| 
 | ||||
| template<class RawShape> | ||||
| inline RawShape convexHull(const RawShape& sh, const PolygonTag&) | ||||
| template<class S> | ||||
| inline S convexHull(const S& sh, const PolygonTag&) | ||||
| { | ||||
|     return create<RawShape>(convexHull(contour(sh), PathTag())); | ||||
|     return create<S>(convexHull(contour(sh), PathTag())); | ||||
| } | ||||
| 
 | ||||
| template<class RawShape> | ||||
| inline auto convexHull(const RawShape& sh) | ||||
|     -> decltype(convexHull(sh, Tag<RawShape>())) // TODO: C++14 could deduce
 | ||||
| template<class S> | ||||
| inline auto convexHull(const S& sh) | ||||
|     -> decltype(convexHull(sh, Tag<S>())) // TODO: C++14 could deduce
 | ||||
| { | ||||
|     return convexHull(sh, Tag<RawShape>()); | ||||
|     return convexHull(sh, Tag<S>()); | ||||
| } | ||||
| 
 | ||||
| template<class RawShape> | ||||
| inline RawShape convexHull(const RawShape& sh, const PathTag&) | ||||
| template<class S> | ||||
| inline S convexHull(const S& sh, const PathTag&) | ||||
| { | ||||
|     using Unit = TCompute<RawShape>; | ||||
|     using Point = TPoint<RawShape>; | ||||
|     using Unit = TCompute<S>; | ||||
|     using Point = TPoint<S>; | ||||
|     namespace sl = shapelike; | ||||
|      | ||||
|     size_t edges = sl::cend(sh) - sl::cbegin(sh); | ||||
|  | @ -1016,8 +1044,8 @@ inline RawShape convexHull(const RawShape& sh, const PathTag&) | |||
|         ++ik; | ||||
|     } | ||||
|      | ||||
|     RawShape ret; reserve(ret, U.size() + L.size()); | ||||
|     if(is_clockwise<RawShape>()) { | ||||
|     S ret; reserve(ret, U.size() + L.size()); | ||||
|     if(is_clockwise<S>()) { | ||||
|         for(auto it = U.begin(); it != std::prev(U.end()); ++it)  | ||||
|             addVertex(ret, *it);   | ||||
|         for(auto it = L.rbegin(); it != std::prev(L.rend()); ++it)  | ||||
|  | @ -1068,11 +1096,11 @@ inline bool isInside(const TP& point, const TB& box, | |||
|     return px > minx && px < maxx && py > miny && py < maxy; | ||||
| } | ||||
| 
 | ||||
| template<class RawShape, class TC> | ||||
| inline bool isInside(const RawShape& sh, const TC& circ, | ||||
| template<class S, class TC> | ||||
| inline bool isInside(const S& sh, const TC& circ, | ||||
|                      const PolygonTag&, const CircleTag&) | ||||
| { | ||||
|     return std::all_of(cbegin(sh), cend(sh), [&circ](const TPoint<RawShape>& p) | ||||
|     return std::all_of(cbegin(sh), cend(sh), [&circ](const TPoint<S>& p) | ||||
|     { | ||||
|         return isInside(p, circ, PointTag(), CircleTag()); | ||||
|     }); | ||||
|  | @ -1103,8 +1131,8 @@ inline bool isInside(const TBGuest& ibb, const TBHost& box, | |||
|     return iminX > minX && imaxX < maxX && iminY > minY && imaxY < maxY; | ||||
| } | ||||
| 
 | ||||
| template<class RawShape, class TB> | ||||
| inline bool isInside(const RawShape& poly, const TB& box, | ||||
| template<class S, class TB> | ||||
| inline bool isInside(const S& poly, const TB& box, | ||||
|                      const PolygonTag&, const BoxTag&) | ||||
| { | ||||
|     return isInside(boundingBox(poly), box, BoxTag(), BoxTag()); | ||||
|  | @ -1115,36 +1143,36 @@ inline bool isInside(const TGuest& guest, const THost& host) { | |||
|     return isInside(guest, host, Tag<TGuest>(), Tag<THost>()); | ||||
| } | ||||
| 
 | ||||
| template<class RawShape> // Potential O(1) implementation may exist
 | ||||
| inline TPoint<RawShape>& vertex(RawShape& sh, unsigned long idx, | ||||
| template<class S> // Potential O(1) implementation may exist
 | ||||
| inline TPoint<S>& vertex(S& sh, unsigned long idx, | ||||
|                                 const PolygonTag&) | ||||
| { | ||||
|     return *(shapelike::begin(contour(sh)) + idx); | ||||
| } | ||||
| 
 | ||||
| template<class RawShape> // Potential O(1) implementation may exist
 | ||||
| inline TPoint<RawShape>& vertex(RawShape& sh, unsigned long idx, | ||||
| template<class S> // Potential O(1) implementation may exist
 | ||||
| inline TPoint<S>& vertex(S& sh, unsigned long idx, | ||||
|                                 const PathTag&) | ||||
| { | ||||
|     return *(shapelike::begin(sh) + idx); | ||||
| } | ||||
| 
 | ||||
| template<class RawShape> // Potential O(1) implementation may exist
 | ||||
| inline TPoint<RawShape>& vertex(RawShape& sh, unsigned long idx) | ||||
| template<class S> // Potential O(1) implementation may exist
 | ||||
| inline TPoint<S>& vertex(S& sh, unsigned long idx) | ||||
| { | ||||
|     return vertex(sh, idx, Tag<RawShape>()); | ||||
|     return vertex(sh, idx, Tag<S>()); | ||||
| } | ||||
| 
 | ||||
| template<class RawShape> // Potential O(1) implementation may exist
 | ||||
| inline const TPoint<RawShape>& vertex(const RawShape& sh, | ||||
| template<class S> // Potential O(1) implementation may exist
 | ||||
| inline const TPoint<S>& vertex(const S& sh, | ||||
|                                       unsigned long idx, | ||||
|                                       const PolygonTag&) | ||||
| { | ||||
|     return *(shapelike::cbegin(contour(sh)) + idx); | ||||
| } | ||||
| 
 | ||||
| template<class RawShape> // Potential O(1) implementation may exist
 | ||||
| inline const TPoint<RawShape>& vertex(const RawShape& sh, | ||||
| template<class S> // Potential O(1) implementation may exist
 | ||||
| inline const TPoint<S>& vertex(const S& sh, | ||||
|                                       unsigned long idx, | ||||
|                                       const PathTag&) | ||||
| { | ||||
|  | @ -1152,28 +1180,28 @@ inline const TPoint<RawShape>& vertex(const RawShape& sh, | |||
| } | ||||
| 
 | ||||
| 
 | ||||
| template<class RawShape> // Potential O(1) implementation may exist
 | ||||
| inline const TPoint<RawShape>& vertex(const RawShape& sh, | ||||
| template<class S> // Potential O(1) implementation may exist
 | ||||
| inline const TPoint<S>& vertex(const S& sh, | ||||
|                                       unsigned long idx) | ||||
| { | ||||
|     return vertex(sh, idx, Tag<RawShape>()); | ||||
|     return vertex(sh, idx, Tag<S>()); | ||||
| } | ||||
| 
 | ||||
| template<class RawShape> | ||||
| inline size_t contourVertexCount(const RawShape& sh) | ||||
| template<class S> | ||||
| inline size_t contourVertexCount(const S& sh) | ||||
| { | ||||
|     return shapelike::cend(sh) - shapelike::cbegin(sh); | ||||
| } | ||||
| 
 | ||||
| template<class RawShape, class Fn> | ||||
| inline void foreachVertex(RawShape& sh, Fn fn, const PolygonTag&) { | ||||
| template<class S, class Fn> | ||||
| inline void foreachVertex(S& sh, Fn fn, const PolygonTag&) { | ||||
|     foreachVertex(contour(sh), fn, PathTag()); | ||||
|     for(auto& h : holes(sh)) foreachVertex(h, fn, PathTag()); | ||||
| } | ||||
| 
 | ||||
| template<class RawShape, class Fn> | ||||
| inline void foreachVertex(RawShape& sh, Fn fn) { | ||||
|     foreachVertex(sh, fn, Tag<RawShape>()); | ||||
| template<class S, class Fn> | ||||
| inline void foreachVertex(S& sh, Fn fn) { | ||||
|     foreachVertex(sh, fn, Tag<S>()); | ||||
| } | ||||
| 
 | ||||
| template<class Poly> inline bool isConvex(const Poly& sh, const PolygonTag&) | ||||
|  | @ -1184,9 +1212,9 @@ template<class Poly> inline bool isConvex(const Poly& sh, const PolygonTag&) | |||
|     return convex; | ||||
| } | ||||
| 
 | ||||
| template<class RawShape> inline bool isConvex(const RawShape& sh) // dispatch
 | ||||
| template<class S> inline bool isConvex(const S& sh) // dispatch
 | ||||
| { | ||||
|     return isConvex(sh, Tag<RawShape>()); | ||||
|     return isConvex(sh, Tag<S>()); | ||||
| } | ||||
| 
 | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 tamasmeszaros
						tamasmeszaros