diff options
author | Paolo Angelelli <paolo.angelelli@qt.io> | 2016-12-16 14:01:36 +0100 |
---|---|---|
committer | Paolo Angelelli <paolo.angelelli@qt.io> | 2017-01-19 13:47:41 +0000 |
commit | 09364bf515283251cf8e4a43de4d2363b16c8551 (patch) | |
tree | 5c028099d8826a6ad2f74c7f8091e1e9ef78dca8 /src/3rdparty | |
parent | 5ecccc40942d95f2412ae6366957e3f34bc1f734 (diff) | |
download | qtlocation-09364bf515283251cf8e4a43de4d2363b16c8551.tar.gz |
Add clipping support to Clip2Tri
Clip2Tri is a Poly2Tri and Clipper wrapper to do robust triangulation.
It also catches exceptions, making Clipper safe to be used with Qt.
This patch adds wrappers to expose clipping functionalities through
Clip2Tri, in order to use Clipper from a layer that sanitizes the
exception and makes it possible to use in Qt.
Change-Id: I0cf18d55c87fee2584bcf34928f1a9cb1c3e287f
Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
Diffstat (limited to 'src/3rdparty')
-rw-r--r-- | src/3rdparty/clip2tri/clip2tri.cpp | 74 | ||||
-rw-r--r-- | src/3rdparty/clip2tri/clip2tri.h | 29 |
2 files changed, 103 insertions, 0 deletions
diff --git a/src/3rdparty/clip2tri/clip2tri.cpp b/src/3rdparty/clip2tri/clip2tri.cpp index 86870fc1..16b1b86b 100644 --- a/src/3rdparty/clip2tri/clip2tri.cpp +++ b/src/3rdparty/clip2tri/clip2tri.cpp @@ -41,6 +41,8 @@ namespace c2t static const F32 CLIPPER_SCALE_FACT = 1000.0f; static const F32 CLIPPER_SCALE_FACT_INVERSE = 0.001f; +static const F64 CLIPPER_SCALE_FACT_D = double(1<<31); +static const F64 CLIPPER_SCALE_FACT_INVERSE_D = 1.0 / double(1<<31); ///////////////////////////////// @@ -83,6 +85,78 @@ void clip2tri::triangulate(const vector<vector<Point> > &inputPolygons, vector<P triangulateComplex(outputTriangles, bounds, solution); } +IntPoint clip2tri::intPoint(double x, double y) +{ + return IntPoint(S64(x * CLIPPER_SCALE_FACT_D), S64(y * CLIPPER_SCALE_FACT_D)); +} + +PointD clip2tri::pointD(IntPoint p) +{ + return PointD(F64(p.X) * CLIPPER_SCALE_FACT_INVERSE_D, F64(p.Y) * CLIPPER_SCALE_FACT_INVERSE_D); +} + +void clip2tri::addClipPolygon(const std::vector<IntPoint> &path) +{ + try // prevent any exception to spill into Qt + { + if (path.front() != path.back()) + return; // Clip polygons must be closed. + clipper.AddPath(path, ptClip, true); + } + catch(...) + { + printf("addClipPolygon: clipper.AddPath, something went wrong\n"); + } +} + +void clip2tri::addSubjectPath(const std::vector<IntPoint> &path, bool closed) +{ + try // prevent any exception to spill into Qt + { + if (path.front() != path.back() && closed) + return; // Clip polygons must be closed. + clipper.AddPath(path, ptSubject, closed); + } + catch(...) + { + printf("addSubjectPath: clipper.AddPath, something went wrong\n"); + } +} + +void clip2tri::clearClipper() +{ + // clear doesn't throw + clipper.Clear(); +} + +Paths clip2tri::executeUnion(PolyFillType subjFillType, PolyFillType clipFillType) +{ + Paths solution; + try // prevent any exception to spill into Qt + { + clipper.Execute(ctUnion, solution, subjFillType, subjFillType); + } + catch(...) + { + printf("executeUnion: clipper.Execute, something went wrong\n"); + } + return solution; +} + +Paths clip2tri::executeIntersection(PolyFillType subjFillType, PolyFillType clipFillType) +{ + Paths solution; + try // prevent any exception to spill into Qt + { + clipper.Execute(ctIntersection, solution, subjFillType, subjFillType); + } + catch(...) + { + printf("executeIntersection: clipper.Execute, something went wrong\n"); + } + return solution; +} + Path clip2tri::upscaleClipperPoints(const vector<Point> &inputPolygon) { diff --git a/src/3rdparty/clip2tri/clip2tri.h b/src/3rdparty/clip2tri/clip2tri.h index 982c8049..a94bb6a1 100644 --- a/src/3rdparty/clip2tri/clip2tri.h +++ b/src/3rdparty/clip2tri/clip2tri.h @@ -57,6 +57,17 @@ struct Point Point(T in_x, U in_y) { x = static_cast<F32>(in_x); y = static_cast<F32>(in_y); } }; +struct PointD +{ + F64 x; + F64 y; + + PointD(); + PointD(const PointD &pt); + + template<class T, class U> + PointD(T in_x, U in_y) { x = static_cast<F64>(in_x); y = static_cast<F64>(in_y); } +}; class clip2tri { @@ -79,6 +90,24 @@ public: void triangulate(const vector<vector<Point> > &inputPolygons, vector<Point> &outputTriangles, const vector<Point> &boundingPolygon); + + inline static IntPoint intPoint(double x, double y); + inline static PointD pointD(IntPoint p); + + // Clip polygons MUST be closed. Meaning path[0] == path[path.size()-1] + void addClipPolygon(const std::vector<IntPoint> &path); + // Closed means the path has to be effectively closed. Meaning path[0] == path[path.size()-1] + void addSubjectPath(const std::vector<IntPoint> &path, bool closed); + + void clearClipper(); + + Paths executeUnion(PolyFillType subjFillType = pftEvenOdd, + PolyFillType clipFillType = pftEvenOdd); + + Paths executeIntersection(PolyFillType subjFillType = pftEvenOdd, + PolyFillType clipFillType = pftEvenOdd); + + Clipper clipper; }; } /* namespace c2t */ |