source: trunk/src/opengl/gl2paintengineex/qtriangulator.cpp

Last change on this file was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 106.7 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation (qt-info@nokia.com)
6**
7** This file is part of the QtOpenGL module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at qt-info@nokia.com.
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qtriangulator_p.h"
43
44#include <QtGui/qdialog.h>
45#include <QtGui/qevent.h>
46#include <QtGui/qpainter.h>
47#include <QtGui/qpainterpath.h>
48#include <QtGui/private/qbezier_p.h>
49#include <QtGui/private/qdatabuffer_p.h>
50#include <QtCore/qbitarray.h>
51#include <QtCore/qvarlengtharray.h>
52#include <QtCore/qqueue.h>
53#include <QtCore/qglobal.h>
54#include <QtCore/qpoint.h>
55#include <QtCore/qalgorithms.h>
56#include <QtDebug>
57
58#include <math.h>
59
60#include <private/qgl_p.h>
61
62QT_BEGIN_NAMESPACE
63
64//#define Q_TRIANGULATOR_DEBUG
65
66#define Q_FIXED_POINT_SCALE 32
67
68// Quick sort.
69template <class T, class LessThan>
70#ifdef Q_CC_RVCT // RVCT 2.2 doesn't see recursive _static_ template function
71void sort(T *array, int count, LessThan lessThan)
72#else
73static void sort(T *array, int count, LessThan lessThan)
74#endif
75{
76 // If the number of elements fall below some threshold, use insertion sort.
77 const int INSERTION_SORT_LIMIT = 7; // About 7 is fastest on my computer...
78 if (count <= INSERTION_SORT_LIMIT) {
79 for (int i = 1; i < count; ++i) {
80 T temp = array[i];
81 int j = i;
82 while (j > 0 && lessThan(temp, array[j - 1])) {
83 array[j] = array[j - 1];
84 --j;
85 }
86 array[j] = temp;
87 }
88 return;
89 }
90
91 int high = count - 1;
92 int low = 0;
93 int mid = high / 2;
94 if (lessThan(array[mid], array[low]))
95 qSwap(array[mid], array[low]);
96 if (lessThan(array[high], array[mid]))
97 qSwap(array[high], array[mid]);
98 if (lessThan(array[mid], array[low]))
99 qSwap(array[mid], array[low]);
100
101 --high;
102 ++low;
103 qSwap(array[mid], array[high]);
104 int pivot = high;
105 --high;
106
107 while (low <= high) {
108 while (!lessThan(array[pivot], array[low])) {
109 ++low;
110 if (low > high)
111 goto sort_loop_end;
112 }
113 while (!lessThan(array[high], array[pivot])) {
114 --high;
115 if (low > high)
116 goto sort_loop_end;
117 }
118 qSwap(array[low], array[high]);
119 ++low;
120 --high;
121 }
122sort_loop_end:
123 if (low != pivot)
124 qSwap(array[pivot], array[low]);
125 sort(array, low, lessThan);
126 sort(array + low + 1, count - low - 1, lessThan);
127}
128
129// Quick sort.
130template <class T>
131#ifdef Q_CC_RVCT
132void sort(T *array, int count) // RVCT 2.2 doesn't see recursive _static_ template function
133#else
134static void sort(T *array, int count)
135#endif
136{
137 // If the number of elements fall below some threshold, use insertion sort.
138 const int INSERTION_SORT_LIMIT = 25; // About 25 is fastest on my computer...
139 if (count <= INSERTION_SORT_LIMIT) {
140 for (int i = 1; i < count; ++i) {
141 T temp = array[i];
142 int j = i;
143 while (j > 0 && (temp < array[j - 1])) {
144 array[j] = array[j - 1];
145 --j;
146 }
147 array[j] = temp;
148 }
149 return;
150 }
151
152 int high = count - 1;
153 int low = 0;
154 int mid = high / 2;
155 if ((array[mid] < array[low]))
156 qSwap(array[mid], array[low]);
157 if ((array[high] < array[mid]))
158 qSwap(array[high], array[mid]);
159 if ((array[mid] < array[low]))
160 qSwap(array[mid], array[low]);
161
162 --high;
163 ++low;
164 qSwap(array[mid], array[high]);
165 int pivot = high;
166 --high;
167
168 while (low <= high) {
169 while (!(array[pivot] < array[low])) {
170 ++low;
171 if (low > high)
172 goto sort_loop_end;
173 }
174 while (!(array[high] < array[pivot])) {
175 --high;
176 if (low > high)
177 goto sort_loop_end;
178 }
179 qSwap(array[low], array[high]);
180 ++low;
181 --high;
182 }
183sort_loop_end:
184 if (low != pivot)
185 qSwap(array[pivot], array[low]);
186 sort(array, low);
187 sort(array + low + 1, count - low - 1);
188}
189
190template<typename T>
191struct QVertexSet
192{
193 inline QVertexSet() { }
194 inline QVertexSet(const QVertexSet<T> &other) : vertices(other.vertices), indices(other.indices) { }
195 QVertexSet<T> &operator = (const QVertexSet<T> &other) {vertices = other.vertices; indices = other.indices; return *this;}
196
197 // The vertices of a triangle are given by: (x[i[n]], y[i[n]]), (x[j[n]], y[j[n]]), (x[k[n]], y[k[n]]), n = 0, 1, ...
198 QVector<qreal> vertices; // [x[0], y[0], x[1], y[1], x[2], ...]
199 QVector<T> indices; // [i[0], j[0], k[0], i[1], j[1], k[1], i[2], ...]
200};
201
202//============================================================================//
203// QFraction //
204//============================================================================//
205
206// Fraction must be in the range [0, 1)
207struct QFraction
208{
209 // Comparison operators must not be called on invalid fractions.
210 inline bool operator < (const QFraction &other) const;
211 inline bool operator == (const QFraction &other) const;
212 inline bool operator != (const QFraction &other) const {return !(*this == other);}
213 inline bool operator > (const QFraction &other) const {return other < *this;}
214 inline bool operator >= (const QFraction &other) const {return !(*this < other);}
215 inline bool operator <= (const QFraction &other) const {return !(*this > other);}
216
217 inline bool isValid() const {return denominator != 0;}
218
219 // numerator and denominator must not have common denominators.
220 quint64 numerator, denominator;
221};
222
223static inline quint64 gcd(quint64 x, quint64 y)
224{
225 while (y != 0) {
226 quint64 z = y;
227 y = x % y;
228 x = z;
229 }
230 return x;
231}
232
233static inline int compare(quint64 a, quint64 b)
234{
235 return (a > b) - (a < b);
236}
237
238// Compare a/b with c/d.
239// Return negative if less, 0 if equal, positive if greater.
240// a < b, c < d
241static int qCompareFractions(quint64 a, quint64 b, quint64 c, quint64 d)
242{
243 const quint64 LIMIT = Q_UINT64_C(0x100000000);
244 for (;;) {
245 // If the products 'ad' and 'bc' fit into 64 bits, they can be directly compared.
246 if (b < LIMIT && d < LIMIT)
247 return compare(a * d, b * c);
248
249 if (a == 0 || c == 0)
250 return compare(a, c);
251
252 // a/b < c/d <=> d/c < b/a
253 quint64 b_div_a = b / a;
254 quint64 d_div_c = d / c;
255 if (b_div_a != d_div_c)
256 return compare(d_div_c, b_div_a);
257
258 // floor(d/c) == floor(b/a)
259 // frac(d/c) < frac(b/a) ?
260 // frac(x/y) = (x%y)/y
261 d -= d_div_c * c; //d %= c;
262 b -= b_div_a * a; //b %= a;
263 qSwap(a, d);
264 qSwap(b, c);
265 }
266}
267
268// Fraction must be in the range [0, 1)
269// Assume input is valid.
270static QFraction qFraction(quint64 n, quint64 d) {
271 QFraction result;
272 if (n == 0) {
273 result.numerator = 0;
274 result.denominator = 1;
275 } else {
276 quint64 g = gcd(n, d);
277 result.numerator = n / g;
278 result.denominator = d / g;
279 }
280 return result;
281}
282
283inline bool QFraction::operator < (const QFraction &other) const
284{
285 return qCompareFractions(numerator, denominator, other.numerator, other.denominator) < 0;
286}
287
288inline bool QFraction::operator == (const QFraction &other) const
289{
290 return numerator == other.numerator && denominator == other.denominator;
291}
292
293//============================================================================//
294// QPodPoint //
295//============================================================================//
296
297struct QPodPoint
298{
299 inline bool operator < (const QPodPoint &other) const
300 {
301 if (y != other.y)
302 return y < other.y;
303 return x < other.x;
304 }
305
306 inline bool operator > (const QPodPoint &other) const {return other < *this;}
307 inline bool operator <= (const QPodPoint &other) const {return !(*this > other);}
308 inline bool operator >= (const QPodPoint &other) const {return !(*this < other);}
309 inline bool operator == (const QPodPoint &other) const {return x == other.x && y == other.y;}
310 inline bool operator != (const QPodPoint &other) const {return x != other.x || y != other.y;}
311
312 inline QPodPoint &operator += (const QPodPoint &other) {x += other.x; y += other.y; return *this;}
313 inline QPodPoint &operator -= (const QPodPoint &other) {x -= other.x; y -= other.y; return *this;}
314 inline QPodPoint operator + (const QPodPoint &other) const {QPodPoint result = {x + other.x, y + other.y}; return result;}
315 inline QPodPoint operator - (const QPodPoint &other) const {QPodPoint result = {x - other.x, y - other.y}; return result;}
316
317 int x;
318 int y;
319};
320
321static inline qint64 qCross(const QPodPoint &u, const QPodPoint &v)
322{
323 return qint64(u.x) * qint64(v.y) - qint64(u.y) * qint64(v.x);
324}
325
326static inline qint64 qDot(const QPodPoint &u, const QPodPoint &v)
327{
328 return qint64(u.x) * qint64(v.x) + qint64(u.y) * qint64(v.y);
329}
330
331// Return positive value if 'p' is to the right of the line 'v1'->'v2', negative if left of the
332// line and zero if exactly on the line.
333// The returned value is the z-component of the qCross product between 'v2-v1' and 'p-v1',
334// which is twice the signed area of the triangle 'p'->'v1'->'v2' (positive for CW order).
335static inline qint64 qPointDistanceFromLine(const QPodPoint &p, const QPodPoint &v1, const QPodPoint &v2)
336{
337 return qCross(v2 - v1, p - v1);
338}
339
340static inline bool qPointIsLeftOfLine(const QPodPoint &p, const QPodPoint &v1, const QPodPoint &v2)
341{
342 return QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(p, v1, v2) < 0;
343}
344
345// Return:
346// -1 if u < v
347// 0 if u == v
348// 1 if u > v
349static int comparePoints(const QPodPoint &u, const QPodPoint &v)
350{
351 if (u.y < v.y)
352 return -1;
353 if (u.y > v.y)
354 return 1;
355 if (u.x < v.x)
356 return -1;
357 if (u.x > v.x)
358 return 1;
359 return 0;
360}
361
362//============================================================================//
363// QIntersectionPoint //
364//============================================================================//
365
366struct QIntersectionPoint
367{
368 inline bool isValid() const {return xOffset.isValid() && yOffset.isValid();}
369 QPodPoint round() const;
370 inline bool isAccurate() const {return xOffset.numerator == 0 && yOffset.numerator == 0;}
371 bool operator < (const QIntersectionPoint &other) const;
372 bool operator == (const QIntersectionPoint &other) const;
373 inline bool operator != (const QIntersectionPoint &other) const {return !(*this == other);}
374 inline bool operator > (const QIntersectionPoint &other) const {return other < *this;}
375 inline bool operator >= (const QIntersectionPoint &other) const {return !(*this < other);}
376 inline bool operator <= (const QIntersectionPoint &other) const {return !(*this > other);}
377 bool isOnLine(const QPodPoint &u, const QPodPoint &v) const;
378
379 QPodPoint upperLeft;
380 QFraction xOffset;
381 QFraction yOffset;
382};
383
384static inline QIntersectionPoint qIntersectionPoint(const QPodPoint &point)
385{
386 // upperLeft = point, xOffset = 0/1, yOffset = 0/1.
387 QIntersectionPoint p = {{point.x, point.y}, {0, 1}, {0, 1}};
388 return p;
389}
390
391static inline QIntersectionPoint qIntersectionPoint(int x, int y)
392{
393 // upperLeft = (x, y), xOffset = 0/1, yOffset = 0/1.
394 QIntersectionPoint p = {{x, y}, {0, 1}, {0, 1}};
395 return p;
396}
397
398static QIntersectionPoint qIntersectionPoint(const QPodPoint &u1, const QPodPoint &u2, const QPodPoint &v1, const QPodPoint &v2)
399{
400 QIntersectionPoint result = {{0, 0}, {0, 0}, {0, 0}};
401
402 QPodPoint u = u2 - u1;
403 QPodPoint v = v2 - v1;
404 qint64 d1 = qCross(u, v1 - u1);
405 qint64 d2 = qCross(u, v2 - u1);
406 qint64 det = d2 - d1;
407 qint64 d3 = qCross(v, u1 - v1);
408 qint64 d4 = d3 - det; //qCross(v, u2 - v1);
409
410 // Check that the math is correct.
411 Q_ASSERT(d4 == qCross(v, u2 - v1));
412
413 // The intersection point can be expressed as:
414 // v1 - v * d1/det
415 // v2 - v * d2/det
416 // u1 + u * d3/det
417 // u2 + u * d4/det
418
419 // I'm only interested in lines that are crossing, so ignore parallel lines even if they overlap.
420 if (det == 0)
421 return result;
422
423 if (det < 0) {
424 det = -det;
425 d1 = -d1;
426 d2 = -d2;
427 d3 = -d3;
428 d4 = -d4;
429 }
430
431 // I'm only interested in lines intersecting at their interior, not at their end points.
432 // The lines intersect at their interior if and only if 'd1 < 0', 'd2 > 0', 'd3 < 0' and 'd4 > 0'.
433 if (d1 >= 0 || d2 <= 0 || d3 <= 0 || d4 >= 0)
434 return result;
435
436 // Calculate the intersection point as follows:
437 // v1 - v * d1/det | v1 <= v2 (component-wise)
438 // v2 - v * d2/det | v2 < v1 (component-wise)
439
440 // Assuming 21 bits per vector component.
441 // TODO: Make code path for 31 bits per vector component.
442 if (v.x >= 0) {
443 result.upperLeft.x = v1.x + (-v.x * d1) / det;
444 result.xOffset = qFraction(quint64(-v.x * d1) % quint64(det), quint64(det));
445 } else {
446 result.upperLeft.x = v2.x + (-v.x * d2) / det;
447 result.xOffset = qFraction(quint64(-v.x * d2) % quint64(det), quint64(det));
448 }
449
450 if (v.y >= 0) {
451 result.upperLeft.y = v1.y + (-v.y * d1) / det;
452 result.yOffset = qFraction(quint64(-v.y * d1) % quint64(det), quint64(det));
453 } else {
454 result.upperLeft.y = v2.y + (-v.y * d2) / det;
455 result.yOffset = qFraction(quint64(-v.y * d2) % quint64(det), quint64(det));
456 }
457
458 Q_ASSERT(result.xOffset.isValid());
459 Q_ASSERT(result.yOffset.isValid());
460 return result;
461}
462
463QPodPoint QIntersectionPoint::round() const
464{
465 QPodPoint result = upperLeft;
466 if (2 * xOffset.numerator >= xOffset.denominator)
467 ++result.x;
468 if (2 * yOffset.numerator >= yOffset.denominator)
469 ++result.y;
470 return result;
471}
472
473bool QIntersectionPoint::operator < (const QIntersectionPoint &other) const
474{
475 if (upperLeft.y != other.upperLeft.y)
476 return upperLeft.y < other.upperLeft.y;
477 if (yOffset != other.yOffset)
478 return yOffset < other.yOffset;
479 if (upperLeft.x != other.upperLeft.x)
480 return upperLeft.x < other.upperLeft.x;
481 return xOffset < other.xOffset;
482}
483
484bool QIntersectionPoint::operator == (const QIntersectionPoint &other) const
485{
486 return upperLeft == other.upperLeft && xOffset == other.xOffset && yOffset == other.yOffset;
487}
488
489// Returns true if this point is on the infinite line passing through 'u' and 'v'.
490bool QIntersectionPoint::isOnLine(const QPodPoint &u, const QPodPoint &v) const
491{
492 // TODO: Make code path for coordinates with more than 21 bits.
493 const QPodPoint p = upperLeft - u;
494 const QPodPoint q = v - u;
495 bool isHorizontal = p.y == 0 && yOffset.numerator == 0;
496 bool isVertical = p.x == 0 && xOffset.numerator == 0;
497 if (isHorizontal && isVertical)
498 return true;
499 if (isHorizontal)
500 return q.y == 0;
501 if (q.y == 0)
502 return false;
503 if (isVertical)
504 return q.x == 0;
505 if (q.x == 0)
506 return false;
507
508 // At this point, 'p+offset' and 'q' cannot lie on the x or y axis.
509
510 if (((q.x < 0) == (q.y < 0)) != ((p.x < 0) == (p.y < 0)))
511 return false; // 'p + offset' and 'q' pass through different quadrants.
512
513 // Move all coordinates into the first quadrant.
514 quint64 nx, ny;
515 if (p.x < 0)
516 nx = quint64(-p.x) * xOffset.denominator - xOffset.numerator;
517 else
518 nx = quint64(p.x) * xOffset.denominator + xOffset.numerator;
519 if (p.y < 0)
520 ny = quint64(-p.y) * yOffset.denominator - yOffset.numerator;
521 else
522 ny = quint64(p.y) * yOffset.denominator + yOffset.numerator;
523
524 return qFraction(quint64(qAbs(q.x)) * xOffset.denominator, quint64(qAbs(q.y)) * yOffset.denominator) == qFraction(nx, ny);
525}
526
527//============================================================================//
528// QMaxHeap //
529//============================================================================//
530
531template <class T>
532class QMaxHeap
533{
534public:
535 QMaxHeap() : m_data(0) {}
536 inline int size() const {return m_data.size();}
537 inline bool empty() const {return m_data.isEmpty();}
538 inline bool isEmpty() const {return m_data.isEmpty();}
539 void push(const T &x);
540 T pop();
541 inline const T &top() const {return m_data.first();}
542private:
543 static inline int parent(int i) {return (i - 1) / 2;}
544 static inline int left(int i) {return 2 * i + 1;}
545 static inline int right(int i) {return 2 * i + 2;}
546
547 QDataBuffer<T> m_data;
548};
549
550template <class T>
551void QMaxHeap<T>::push(const T &x)
552{
553 int current = m_data.size();
554 int parent = QMaxHeap::parent(current);
555 m_data.add(x);
556 while (current != 0 && m_data.at(parent) < x) {
557 m_data.at(current) = m_data.at(parent);
558 current = parent;
559 parent = QMaxHeap::parent(current);
560 }
561 m_data.at(current) = x;
562}
563
564template <class T>
565T QMaxHeap<T>::pop()
566{
567 T result = m_data.first();
568 T back = m_data.last();
569 m_data.pop_back();
570 if (!m_data.isEmpty()) {
571 int current = 0;
572 for (;;) {
573 int left = QMaxHeap::left(current);
574 int right = QMaxHeap::right(current);
575 if (left >= m_data.size())
576 break;
577 int greater = left;
578 if (right < m_data.size() && m_data.at(left) < m_data.at(right))
579 greater = right;
580 if (m_data.at(greater) < back)
581 break;
582 m_data.at(current) = m_data.at(greater);
583 current = greater;
584 }
585 m_data.at(current) = back;
586 }
587 return result;
588}
589
590//============================================================================//
591// QRBTree //
592//============================================================================//
593
594template <class T>
595struct QRBTree
596{
597 struct Node
598 {
599 inline Node() : parent(0), left(0), right(0), red(true) { }
600 inline ~Node() {if (left) delete left; if (right) delete right;}
601 T data;
602 Node *parent;
603 Node *left;
604 Node *right;
605 bool red;
606 };
607
608 inline QRBTree() : root(0), freeList(0) { }
609 inline ~QRBTree();
610
611 inline void clear();
612
613 void attachBefore(Node *parent, Node *child);
614 void attachAfter(Node *parent, Node *child);
615
616 inline Node *front(Node *node) const;
617 inline Node *back(Node *node) const;
618 Node *next(Node *node) const;
619 Node *previous(Node *node) const;
620
621 inline void deleteNode(Node *&node);
622 inline Node *newNode();
623
624 // Return 1 if 'left' comes after 'right', 0 if equal, and -1 otherwise.
625 // 'left' and 'right' cannot be null.
626 int order(Node *left, Node *right);
627 inline bool validate() const;
628
629private:
630 void rotateLeft(Node *node);
631 void rotateRight(Node *node);
632 void update(Node *node);
633
634 inline void attachLeft(Node *parent, Node *child);
635 inline void attachRight(Node *parent, Node *child);
636
637 int blackDepth(Node *top) const;
638 bool checkRedBlackProperty(Node *top) const;
639
640 void swapNodes(Node *n1, Node *n2);
641 void detach(Node *node);
642
643 // 'node' must be black. rebalance will reduce the depth of black nodes by one in the sibling tree.
644 void rebalance(Node *node);
645
646public:
647 Node *root;
648private:
649 Node *freeList;
650};
651
652template <class T>
653inline QRBTree<T>::~QRBTree()
654{
655 clear();
656 while (freeList) {
657 // Avoid recursively calling the destructor, as this list may become large.
658 Node *next = freeList->right;
659 freeList->right = 0;
660 delete freeList;
661 freeList = next;
662 }
663}
664
665template <class T>
666inline void QRBTree<T>::clear()
667{
668 if (root)
669 delete root;
670 root = 0;
671}
672
673template <class T>
674void QRBTree<T>::rotateLeft(Node *node)
675{
676 // | | //
677 // N B //
678 // / \ / \ //
679 // A B ---> N D //
680 // / \ / \ //
681 // C D A C //
682
683 Node *&ref = (node->parent ? (node == node->parent->left ? node->parent->left : node->parent->right) : root);
684 ref = node->right;
685 node->right->parent = node->parent;
686
687 // : //
688 // N //
689 // / :| //
690 // A B //
691 // / \ //
692 // C D //
693
694 node->right = ref->left;
695 if (ref->left)
696 ref->left->parent = node;
697
698 // : | //
699 // N B //
700 // / \ : \ //
701 // A C D //
702
703 ref->left = node;
704 node->parent = ref;
705
706 // | //
707 // B //
708 // / \ //
709 // N D //
710 // / \ //
711 // A C //
712}
713
714template <class T>
715void QRBTree<T>::rotateRight(Node *node)
716{
717 // | | //
718 // N A //
719 // / \ / \ //
720 // A B ---> C N //
721 // / \ / \ //
722 // C D D B //
723
724 Node *&ref = (node->parent ? (node == node->parent->left ? node->parent->left : node->parent->right) : root);
725 ref = node->left;
726 node->left->parent = node->parent;
727
728 node->left = ref->right;
729 if (ref->right)
730 ref->right->parent = node;
731
732 ref->right = node;
733 node->parent = ref;
734}
735
736template <class T>
737void QRBTree<T>::update(Node *node) // call this after inserting a node
738{
739 for (;;) {
740 Node *parent = node->parent;
741
742 // if the node is the root, color it black
743 if (!parent) {
744 node->red = false;
745 return;
746 }
747
748 // if the parent is black, the node can be left red
749 if (!parent->red)
750 return;
751
752 // at this point, the parent is red and cannot be the root
753 Node *grandpa = parent->parent;
754 Q_ASSERT(grandpa);
755
756 Node *uncle = (parent == grandpa->left ? grandpa->right : grandpa->left);
757 if (uncle && uncle->red) {
758 // grandpa's black, parent and uncle are red.
759 // let parent and uncle be black, grandpa red and recursively update grandpa.
760 Q_ASSERT(!grandpa->red);
761 parent->red = false;
762 uncle->red = false;
763 grandpa->red = true;
764 node = grandpa;
765 continue;
766 }
767
768 // at this point, uncle is black
769 if (node == parent->right && parent == grandpa->left)
770 rotateLeft(node = parent);
771 else if (node == parent->left && parent == grandpa->right)
772 rotateRight(node = parent);
773 parent = node->parent;
774
775 if (parent == grandpa->left) {
776 rotateRight(grandpa);
777 parent->red = false;
778 grandpa->red = true;
779 } else {
780 rotateLeft(grandpa);
781 parent->red = false;
782 grandpa->red = true;
783 }
784 return;
785 }
786}
787
788template <class T>
789inline void QRBTree<T>::attachLeft(Node *parent, Node *child)
790{
791 Q_ASSERT(!parent->left);
792 parent->left = child;
793 child->parent = parent;
794 update(child);
795}
796
797template <class T>
798inline void QRBTree<T>::attachRight(Node *parent, Node *child)
799{
800 Q_ASSERT(!parent->right);
801 parent->right = child;
802 child->parent = parent;
803 update(child);
804}
805
806template <class T>
807void QRBTree<T>::attachBefore(Node *parent, Node *child)
808{
809 if (!root)
810 update(root = child);
811 else if (!parent)
812 attachRight(back(root), child);
813 else if (parent->left)
814 attachRight(back(parent->left), child);
815 else
816 attachLeft(parent, child);
817}
818
819template <class T>
820void QRBTree<T>::attachAfter(Node *parent, Node *child)
821{
822 if (!root)
823 update(root = child);
824 else if (!parent)
825 attachLeft(front(root), child);
826 else if (parent->right)
827 attachLeft(front(parent->right), child);
828 else
829 attachRight(parent, child);
830}
831
832template <class T>
833void QRBTree<T>::swapNodes(Node *n1, Node *n2)
834{
835 // Since iterators must not be invalidated, it is not sufficient to only swap the data.
836 if (n1->parent == n2) {
837 n1->parent = n2->parent;
838 n2->parent = n1;
839 } else if (n2->parent == n1) {
840 n2->parent = n1->parent;
841 n1->parent = n2;
842 } else {
843 qSwap(n1->parent, n2->parent);
844 }
845
846 qSwap(n1->left, n2->left);
847 qSwap(n1->right, n2->right);
848 qSwap(n1->red, n2->red);
849
850 if (n1->parent) {
851 if (n1->parent->left == n2)
852 n1->parent->left = n1;
853 else
854 n1->parent->right = n1;
855 } else {
856 root = n1;
857 }
858
859 if (n2->parent) {
860 if (n2->parent->left == n1)
861 n2->parent->left = n2;
862 else
863 n2->parent->right = n2;
864 } else {
865 root = n2;
866 }
867
868 if (n1->left)
869 n1->left->parent = n1;
870 if (n1->right)
871 n1->right->parent = n1;
872
873 if (n2->left)
874 n2->left->parent = n2;
875 if (n2->right)
876 n2->right->parent = n2;
877}
878
879template <class T>
880void QRBTree<T>::detach(Node *node) // call this before removing a node.
881{
882 if (node->right)
883 swapNodes(node, front(node->right));
884
885 Node *child = (node->left ? node->left : node->right);
886
887 if (!node->red) {
888 if (child && child->red)
889 child->red = false;
890 else
891 rebalance(node);
892 }
893
894 Node *&ref = (node->parent ? (node == node->parent->left ? node->parent->left : node->parent->right) : root);
895 ref = child;
896 if (child)
897 child->parent = node->parent;
898 node->left = node->right = node->parent = 0;
899}
900
901// 'node' must be black. rebalance will reduce the depth of black nodes by one in the sibling tree.
902template <class T>
903void QRBTree<T>::rebalance(Node *node)
904{
905 Q_ASSERT(!node->red);
906 for (;;) {
907 if (!node->parent)
908 return;
909
910 // at this point, node is not a parent, it is black, thus it must have a sibling.
911 Node *sibling = (node == node->parent->left ? node->parent->right : node->parent->left);
912 Q_ASSERT(sibling);
913
914 if (sibling->red) {
915 sibling->red = false;
916 node->parent->red = true;
917 if (node == node->parent->left)
918 rotateLeft(node->parent);
919 else
920 rotateRight(node->parent);
921 sibling = (node == node->parent->left ? node->parent->right : node->parent->left);
922 Q_ASSERT(sibling);
923 }
924
925 // at this point, the sibling is black.
926 Q_ASSERT(!sibling->red);
927
928 if ((!sibling->left || !sibling->left->red) && (!sibling->right || !sibling->right->red)) {
929 bool parentWasRed = node->parent->red;
930 sibling->red = true;
931 node->parent->red = false;
932 if (parentWasRed)
933 return;
934 node = node->parent;
935 continue;
936 }
937
938 // at this point, at least one of the sibling's children is red.
939
940 if (node == node->parent->left) {
941 if (!sibling->right || !sibling->right->red) {
942 Q_ASSERT(sibling->left);
943 sibling->red = true;
944 sibling->left->red = false;
945 rotateRight(sibling);
946
947 sibling = sibling->parent;
948 Q_ASSERT(sibling);
949 }
950 sibling->red = node->parent->red;
951 node->parent->red = false;
952
953 Q_ASSERT(sibling->right->red);
954 sibling->right->red = false;
955 rotateLeft(node->parent);
956 } else {
957 if (!sibling->left || !sibling->left->red) {
958 Q_ASSERT(sibling->right);
959 sibling->red = true;
960 sibling->right->red = false;
961 rotateLeft(sibling);
962
963 sibling = sibling->parent;
964 Q_ASSERT(sibling);
965 }
966 sibling->red = node->parent->red;
967 node->parent->red = false;
968
969 Q_ASSERT(sibling->left->red);
970 sibling->left->red = false;
971 rotateRight(node->parent);
972 }
973 return;
974 }
975}
976
977template <class T>
978inline typename QRBTree<T>::Node *QRBTree<T>::front(Node *node) const
979{
980 while (node->left)
981 node = node->left;
982 return node;
983}
984
985template <class T>
986inline typename QRBTree<T>::Node *QRBTree<T>::back(Node *node) const
987{
988 while (node->right)
989 node = node->right;
990 return node;
991}
992
993template <class T>
994typename QRBTree<T>::Node *QRBTree<T>::next(Node *node) const
995{
996 if (node->right)
997 return front(node->right);
998 while (node->parent && node == node->parent->right)
999 node = node->parent;
1000 return node->parent;
1001}
1002
1003template <class T>
1004typename QRBTree<T>::Node *QRBTree<T>::previous(Node *node) const
1005{
1006 if (node->left)
1007 return back(node->left);
1008 while (node->parent && node == node->parent->left)
1009 node = node->parent;
1010 return node->parent;
1011}
1012
1013template <class T>
1014int QRBTree<T>::blackDepth(Node *top) const
1015{
1016 if (!top)
1017 return 0;
1018 int leftDepth = blackDepth(top->left);
1019 int rightDepth = blackDepth(top->right);
1020 if (leftDepth != rightDepth)
1021 return -1;
1022 if (!top->red)
1023 ++leftDepth;
1024 return leftDepth;
1025}
1026
1027template <class T>
1028bool QRBTree<T>::checkRedBlackProperty(Node *top) const
1029{
1030 if (!top)
1031 return true;
1032 if (top->left && !checkRedBlackProperty(top->left))
1033 return false;
1034 if (top->right && !checkRedBlackProperty(top->right))
1035 return false;
1036 return !(top->red && ((top->left && top->left->red) || (top->right && top->right->red)));
1037}
1038
1039template <class T>
1040inline bool QRBTree<T>::validate() const
1041{
1042 return checkRedBlackProperty(root) && blackDepth(root) != -1;
1043}
1044
1045template <class T>
1046inline void QRBTree<T>::deleteNode(Node *&node)
1047{
1048 Q_ASSERT(node);
1049 detach(node);
1050 node->right = freeList;
1051 freeList = node;
1052 node = 0;
1053}
1054
1055template <class T>
1056inline typename QRBTree<T>::Node *QRBTree<T>::newNode()
1057{
1058 if (freeList) {
1059 Node *node = freeList;
1060 freeList = freeList->right;
1061 node->parent = node->left = node->right = 0;
1062 node->red = true;
1063 return node;
1064 }
1065 return new Node;
1066}
1067
1068// Return 1 if 'left' comes after 'right', 0 if equal, and -1 otherwise.
1069// 'left' and 'right' cannot be null.
1070template <class T>
1071int QRBTree<T>::order(Node *left, Node *right)
1072{
1073 Q_ASSERT(left && right);
1074 if (left == right)
1075 return 0;
1076
1077 QVector<Node *> leftAncestors;
1078 QVector<Node *> rightAncestors;
1079 while (left) {
1080 leftAncestors.push_back(left);
1081 left = left->parent;
1082 }
1083 while (right) {
1084 rightAncestors.push_back(right);
1085 right = right->parent;
1086 }
1087 Q_ASSERT(leftAncestors.back() == root && rightAncestors.back() == root);
1088
1089 while (!leftAncestors.empty() && !rightAncestors.empty() && leftAncestors.back() == rightAncestors.back()) {
1090 leftAncestors.pop_back();
1091 rightAncestors.pop_back();
1092 }
1093
1094 if (!leftAncestors.empty())
1095 return (leftAncestors.back() == leftAncestors.back()->parent->left ? -1 : 1);
1096
1097 if (!rightAncestors.empty())
1098 return (rightAncestors.back() == rightAncestors.back()->parent->right ? -1 : 1);
1099
1100 // The code should never reach this point.
1101 Q_ASSERT(!leftAncestors.empty() || !rightAncestors.empty());
1102 return 0;
1103}
1104
1105//============================================================================//
1106// QInt64Hash //
1107//============================================================================//
1108
1109// Copied from qhash.cpp
1110static const uchar prime_deltas[] = {
1111 0, 0, 1, 3, 1, 5, 3, 3, 1, 9, 7, 5, 3, 9, 25, 3,
1112 1, 21, 3, 21, 7, 15, 9, 5, 3, 29, 15, 0, 0, 0, 0, 0
1113};
1114
1115// Copied from qhash.cpp
1116static inline int primeForNumBits(int numBits)
1117{
1118 return (1 << numBits) + prime_deltas[numBits];
1119}
1120
1121static inline int primeForCount(int count)
1122{
1123 int low = 0;
1124 int high = 32;
1125 for (int i = 0; i < 5; ++i) {
1126 int mid = (high + low) / 2;
1127 if (count >= 1 << mid)
1128 low = mid;
1129 else
1130 high = mid;
1131 }
1132 return primeForNumBits(high);
1133}
1134
1135// Hash set of quint64s. Elements cannot be removed without clearing the
1136// entire set. A value of -1 is used to mark unused entries.
1137class QInt64Set
1138{
1139public:
1140 inline QInt64Set(int capacity = 64);
1141 inline ~QInt64Set() {if (m_array) delete[] m_array;}
1142 inline bool isValid() const {return m_array;}
1143 void insert(quint64 key);
1144 bool contains(quint64 key) const;
1145 inline void clear();
1146private:
1147 bool rehash(int capacity);
1148
1149 static const quint64 UNUSED;
1150
1151 quint64 *m_array;
1152 int m_capacity;
1153 int m_count;
1154};
1155
1156const quint64 QInt64Set::UNUSED = quint64(-1);
1157
1158inline QInt64Set::QInt64Set(int capacity)
1159{
1160 m_capacity = primeForCount(capacity);
1161 m_array = new quint64[m_capacity];
1162 if (m_array)
1163 clear();
1164 else
1165 m_capacity = 0;
1166}
1167
1168bool QInt64Set::rehash(int capacity)
1169{
1170 quint64 *oldArray = m_array;
1171 int oldCapacity = m_capacity;
1172
1173 m_capacity = capacity;
1174 m_array = new quint64[m_capacity];
1175 if (m_array) {
1176 clear();
1177 if (oldArray) {
1178 for (int i = 0; i < oldCapacity; ++i) {
1179 if (oldArray[i] != UNUSED)
1180 insert(oldArray[i]);
1181 }
1182 delete[] oldArray;
1183 }
1184 return true;
1185 } else {
1186 m_capacity = oldCapacity;
1187 m_array = oldArray;
1188 return false;
1189 }
1190}
1191
1192void QInt64Set::insert(quint64 key)
1193{
1194 if (m_count > 3 * m_capacity / 4)
1195 rehash(primeForCount(2 * m_capacity));
1196 Q_ASSERT_X(m_array, "QInt64Hash<T>::insert", "Hash set not allocated.");
1197 int index = int(key % m_capacity);
1198 for (int i = 0; i < m_capacity; ++i) {
1199 index += i;
1200 if (index >= m_capacity)
1201 index -= m_capacity;
1202 if (m_array[index] == key)
1203 return;
1204 if (m_array[index] == UNUSED) {
1205 ++m_count;
1206 m_array[index] = key;
1207 return;
1208 }
1209 }
1210 Q_ASSERT_X(0, "QInt64Hash<T>::insert", "Hash set full.");
1211}
1212
1213bool QInt64Set::contains(quint64 key) const
1214{
1215 Q_ASSERT_X(m_array, "QInt64Hash<T>::contains", "Hash set not allocated.");
1216 int index = int(key % m_capacity);
1217 for (int i = 0; i < m_capacity; ++i) {
1218 index += i;
1219 if (index >= m_capacity)
1220 index -= m_capacity;
1221 if (m_array[index] == key)
1222 return true;
1223 if (m_array[index] == UNUSED)
1224 return false;
1225 }
1226 return false;
1227}
1228
1229inline void QInt64Set::clear()
1230{
1231 Q_ASSERT_X(m_array, "QInt64Hash<T>::clear", "Hash set not allocated.");
1232 for (int i = 0; i < m_capacity; ++i)
1233 m_array[i] = UNUSED;
1234 m_count = 0;
1235}
1236
1237//============================================================================//
1238// QRingBuffer //
1239//============================================================================//
1240
1241// T must be POD.
1242template <class T>
1243class QRingBuffer
1244{
1245public:
1246 inline QRingBuffer() : m_array(0), m_head(0), m_size(0), m_capacity(0) { }
1247 inline ~QRingBuffer() {if (m_array) delete[] m_array;}
1248 bool reallocate(int capacity);
1249 inline const T &head() const {Q_ASSERT(m_size > 0); return m_array[m_head];}
1250 inline const T &dequeue();
1251 inline void enqueue(const T &x);
1252 inline bool isEmpty() const {return m_size == 0;}
1253private:
1254 T *m_array;
1255 int m_head;
1256 int m_size;
1257 int m_capacity;
1258};
1259
1260template <class T>
1261bool QRingBuffer<T>::reallocate(int capacity)
1262{
1263 T *oldArray = m_array;
1264 m_array = new T[capacity];
1265 if (m_array) {
1266 if (oldArray) {
1267 if (m_head + m_size > m_capacity) {
1268 memcpy(m_array, oldArray + m_head, (m_capacity - m_head) * sizeof(T));
1269 memcpy(m_array + (m_capacity - m_head), oldArray, (m_head + m_size - m_capacity) * sizeof(T));
1270 } else {
1271 memcpy(m_array, oldArray + m_head, m_size * sizeof(T));
1272 }
1273 delete[] oldArray;
1274 }
1275 m_capacity = capacity;
1276 m_head = 0;
1277 return true;
1278 } else {
1279 m_array = oldArray;
1280 return false;
1281 }
1282}
1283
1284template <class T>
1285inline const T &QRingBuffer<T>::dequeue()
1286{
1287 Q_ASSERT(m_size > 0);
1288 Q_ASSERT(m_array);
1289 Q_ASSERT(m_capacity >= m_size);
1290 int index = m_head;
1291 if (++m_head >= m_capacity)
1292 m_head -= m_capacity;
1293 --m_size;
1294 return m_array[index];
1295}
1296
1297template <class T>
1298inline void QRingBuffer<T>::enqueue(const T &x)
1299{
1300 if (m_size == m_capacity)
1301 reallocate(qMax(2 * m_capacity, 64));
1302 int index = m_head + m_size;
1303 if (index >= m_capacity)
1304 index -= m_capacity;
1305 m_array[index] = x;
1306 ++m_size;
1307}
1308
1309//============================================================================//
1310// QTriangulator //
1311//============================================================================//
1312template<typename T>
1313class QTriangulator
1314{
1315public:
1316 typedef QVarLengthArray<int, 6> ShortArray;
1317
1318 //================================//
1319 // QTriangulator::ComplexToSimple //
1320 //================================//
1321 friend class ComplexToSimple;
1322 class ComplexToSimple
1323 {
1324 public:
1325 inline ComplexToSimple(QTriangulator<T> *parent) : m_parent(parent),
1326 m_edges(0), m_events(0), m_splits(0) { }
1327 void decompose();
1328 private:
1329 struct Edge
1330 {
1331 inline int &upper() {return pointingUp ? to : from;}
1332 inline int &lower() {return pointingUp ? from : to;}
1333 inline int upper() const {return pointingUp ? to : from;}
1334 inline int lower() const {return pointingUp ? from : to;}
1335
1336 QRBTree<int>::Node *node;
1337 int from, to; // vertex
1338 int next, previous; // edge
1339 int winding;
1340 bool mayIntersect;
1341 bool pointingUp, originallyPointingUp;
1342 };
1343
1344 friend class CompareEdges;
1345 class CompareEdges
1346 {
1347 public:
1348 inline CompareEdges(ComplexToSimple *parent) : m_parent(parent) { }
1349 bool operator () (int i, int j) const;
1350 private:
1351 ComplexToSimple *m_parent;
1352 };
1353
1354 struct Intersection
1355 {
1356 bool operator < (const Intersection &other) const {return other.intersectionPoint < intersectionPoint;}
1357
1358 QIntersectionPoint intersectionPoint;
1359 int vertex;
1360 int leftEdge;
1361 int rightEdge;
1362 };
1363
1364 struct Split
1365 {
1366 int vertex;
1367 int edge;
1368 bool accurate;
1369 };
1370
1371 struct Event
1372 {
1373 enum Type {Upper, Lower};
1374 inline bool operator < (const Event &other) const;
1375
1376 QPodPoint point;
1377 Type type;
1378 int edge;
1379 };
1380
1381#ifdef Q_TRIANGULATOR_DEBUG
1382 friend class DebugDialog;
1383 friend class QTriangulator;
1384 class DebugDialog : public QDialog
1385 {
1386 public:
1387 DebugDialog(ComplexToSimple *parent, int currentVertex);
1388 protected:
1389 void paintEvent(QPaintEvent *);
1390 void wheelEvent(QWheelEvent *);
1391 void mouseMoveEvent(QMouseEvent *);
1392 void mousePressEvent(QMouseEvent *);
1393 private:
1394 ComplexToSimple *m_parent;
1395 QRectF m_window;
1396 QPoint m_lastMousePos;
1397 int m_vertex;
1398 };
1399#endif
1400
1401 void initEdges();
1402 bool calculateIntersection(int left, int right);
1403 bool edgeIsLeftOfEdge(int leftEdgeIndex, int rightEdgeIndex) const;
1404 QRBTree<int>::Node *searchEdgeLeftOf(int edgeIndex) const;
1405 QRBTree<int>::Node *searchEdgeLeftOf(int edgeIndex, QRBTree<int>::Node *after) const;
1406 QPair<QRBTree<int>::Node *, QRBTree<int>::Node *> bounds(const QPodPoint &point) const;
1407 QPair<QRBTree<int>::Node *, QRBTree<int>::Node *> outerBounds(const QPodPoint &point) const;
1408 void splitEdgeListRange(QRBTree<int>::Node *leftmost, QRBTree<int>::Node *rightmost, int vertex, const QIntersectionPoint &intersectionPoint);
1409 void reorderEdgeListRange(QRBTree<int>::Node *leftmost, QRBTree<int>::Node *rightmost);
1410 void sortEdgeList(const QPodPoint eventPoint);
1411 void fillPriorityQueue();
1412 void calculateIntersections();
1413 int splitEdge(int splitIndex);
1414 bool splitEdgesAtIntersections();
1415 void insertEdgeIntoVectorIfWanted(ShortArray &orderedEdges, int i);
1416 void removeUnwantedEdgesAndConnect();
1417 void removeUnusedPoints();
1418
1419 QTriangulator *m_parent;
1420 QDataBuffer<Edge> m_edges;
1421 QRBTree<int> m_edgeList;
1422 QDataBuffer<Event> m_events;
1423 QDataBuffer<Split> m_splits;
1424 QMaxHeap<Intersection> m_topIntersection;
1425 QInt64Set m_processedEdgePairs;
1426 int m_initialPointCount;
1427 };
1428#ifdef Q_TRIANGULATOR_DEBUG
1429 friend class ComplexToSimple::DebugDialog;
1430#endif
1431
1432 //=================================//
1433 // QTriangulator::SimpleToMonotone //
1434 //=================================//
1435 friend class SimpleToMonotone;
1436 class SimpleToMonotone
1437 {
1438 public:
1439 inline SimpleToMonotone(QTriangulator<T> *parent) : m_parent(parent), m_edges(0), m_upperVertex(0) { }
1440 void decompose();
1441 private:
1442 enum VertexType {MergeVertex, EndVertex, RegularVertex, StartVertex, SplitVertex};
1443
1444 struct Edge
1445 {
1446 QRBTree<int>::Node *node;
1447 int helper, twin, next, previous;
1448 T from, to;
1449 VertexType type;
1450 bool pointingUp;
1451 int upper() const {return (pointingUp ? to : from);}
1452 int lower() const {return (pointingUp ? from : to);}
1453 };
1454
1455 friend class CompareVertices;
1456 class CompareVertices
1457 {
1458 public:
1459 CompareVertices(SimpleToMonotone *parent) : m_parent(parent) { }
1460 bool operator () (int i, int j) const;
1461 private:
1462 SimpleToMonotone *m_parent;
1463 };
1464
1465 void setupDataStructures();
1466 void removeZeroLengthEdges();
1467 void fillPriorityQueue();
1468 bool edgeIsLeftOfEdge(int leftEdgeIndex, int rightEdgeIndex) const;
1469 // Returns the rightmost edge not to the right of the given edge.
1470 QRBTree<int>::Node *searchEdgeLeftOfEdge(int edgeIndex) const;
1471 // Returns the rightmost edge left of the given point.
1472 QRBTree<int>::Node *searchEdgeLeftOfPoint(int pointIndex) const;
1473 void classifyVertex(int i);
1474 void classifyVertices();
1475 bool pointIsInSector(const QPodPoint &p, const QPodPoint &v1, const QPodPoint &v2, const QPodPoint &v3);
1476 bool pointIsInSector(int vertex, int sector);
1477 int findSector(int edge, int vertex);
1478 void createDiagonal(int lower, int upper);
1479 void monotoneDecomposition();
1480
1481 QTriangulator *m_parent;
1482 QRBTree<int> m_edgeList;
1483 QDataBuffer<Edge> m_edges;
1484 QDataBuffer<int> m_upperVertex;
1485 bool m_clockwiseOrder;
1486 };
1487
1488 //====================================//
1489 // QTriangulator::MonotoneToTriangles //
1490 //====================================//
1491 friend class MonotoneToTriangles;
1492 class MonotoneToTriangles
1493 {
1494 public:
1495 inline MonotoneToTriangles(QTriangulator<T> *parent) : m_parent(parent) { }
1496 void decompose();
1497 private:
1498 inline T indices(int index) const {return m_parent->m_indices.at(index + m_first);}
1499 inline int next(int index) const {return (index + 1) % m_length;}
1500 inline int previous(int index) const {return (index + m_length - 1) % m_length;}
1501 inline bool less(int i, int j) const {return m_parent->m_vertices.at((qint32)indices(i)) < m_parent->m_vertices.at(indices(j));}
1502 inline bool leftOfEdge(int i, int j, int k) const
1503 {
1504 return qPointIsLeftOfLine(m_parent->m_vertices.at((qint32)indices(i)),
1505 m_parent->m_vertices.at((qint32)indices(j)), m_parent->m_vertices.at((qint32)indices(k)));
1506 }
1507
1508 QTriangulator<T> *m_parent;
1509 int m_first;
1510 int m_length;
1511 };
1512
1513 inline QTriangulator() : m_vertices(0) { }
1514
1515 // Call this only once.
1516 void initialize(const qreal *polygon, int count, uint hint, const QTransform &matrix);
1517 // Call this only once.
1518 void initialize(const QVectorPath &path, const QTransform &matrix, qreal lod);
1519 // Call this only once.
1520 void initialize(const QPainterPath &path, const QTransform &matrix, qreal lod);
1521 // Call either triangulate() or polyline() only once.
1522 QVertexSet<T> triangulate();
1523 QVertexSet<T> polyline();
1524private:
1525 QDataBuffer<QPodPoint> m_vertices;
1526 QVector<T> m_indices;
1527 uint m_hint;
1528};
1529
1530//============================================================================//
1531// QTriangulator //
1532//============================================================================//
1533
1534template <typename T>
1535QVertexSet<T> QTriangulator<T>::triangulate()
1536{
1537 for (int i = 0; i < m_vertices.size(); ++i) {
1538 Q_ASSERT(qAbs(m_vertices.at(i).x) < (1 << 21));
1539 Q_ASSERT(qAbs(m_vertices.at(i).y) < (1 << 21));
1540 }
1541
1542 if (!(m_hint & (QVectorPath::OddEvenFill | QVectorPath::WindingFill)))
1543 m_hint |= QVectorPath::OddEvenFill;
1544
1545 if (m_hint & QVectorPath::NonConvexShapeMask) {
1546 ComplexToSimple c2s(this);
1547 c2s.decompose();
1548 SimpleToMonotone s2m(this);
1549 s2m.decompose();
1550 }
1551 MonotoneToTriangles m2t(this);
1552 m2t.decompose();
1553
1554 QVertexSet<T> result;
1555 result.indices = m_indices;
1556 result.vertices.resize(2 * m_vertices.size());
1557 for (int i = 0; i < m_vertices.size(); ++i) {
1558 result.vertices[2 * i + 0] = qreal(m_vertices.at(i).x) / Q_FIXED_POINT_SCALE;
1559 result.vertices[2 * i + 1] = qreal(m_vertices.at(i).y) / Q_FIXED_POINT_SCALE;
1560 }
1561 return result;
1562}
1563
1564template <typename T>
1565QVertexSet<T> QTriangulator<T>::polyline()
1566{
1567 QVertexSet<T> result;
1568 result.indices = m_indices;
1569 result.vertices.resize(2 * m_vertices.size());
1570 for (int i = 0; i < m_vertices.size(); ++i) {
1571 result.vertices[2 * i + 0] = qreal(m_vertices.at(i).x) / Q_FIXED_POINT_SCALE;
1572 result.vertices[2 * i + 1] = qreal(m_vertices.at(i).y) / Q_FIXED_POINT_SCALE;
1573 }
1574 return result;
1575}
1576
1577template <typename T>
1578void QTriangulator<T>::initialize(const qreal *polygon, int count, uint hint, const QTransform &matrix)
1579{
1580 m_hint = hint;
1581 m_vertices.resize(count);
1582 m_indices.resize(count + 1);
1583 for (int i = 0; i < count; ++i) {
1584 qreal x, y;
1585 matrix.map(polygon[2 * i + 0], polygon[2 * i + 1], &x, &y);
1586 m_vertices.at(i).x = qRound(x * Q_FIXED_POINT_SCALE);
1587 m_vertices.at(i).y = qRound(y * Q_FIXED_POINT_SCALE);
1588 m_indices[i] = i;
1589 }
1590 m_indices[count] = T(-1); //Q_TRIANGULATE_END_OF_POLYGON
1591}
1592
1593template <typename T>
1594void QTriangulator<T>::initialize(const QVectorPath &path, const QTransform &matrix, qreal lod)
1595{
1596 m_hint = path.hints();
1597 // Curved paths will be converted to complex polygons.
1598 m_hint &= ~QVectorPath::CurvedShapeMask;
1599
1600 const qreal *p = path.points();
1601 const QPainterPath::ElementType *e = path.elements();
1602 if (e) {
1603 for (int i = 0; i < path.elementCount(); ++i, ++e, p += 2) {
1604 switch (*e) {
1605 case QPainterPath::MoveToElement:
1606 if (!m_indices.isEmpty())
1607 m_indices.push_back(T(-1)); // Q_TRIANGULATE_END_OF_POLYGON
1608 // Fall through.
1609 case QPainterPath::LineToElement:
1610 m_indices.push_back(T(m_vertices.size()));
1611 m_vertices.resize(m_vertices.size() + 1);
1612 qreal x, y;
1613 matrix.map(p[0], p[1], &x, &y);
1614 m_vertices.last().x = qRound(x * Q_FIXED_POINT_SCALE);
1615 m_vertices.last().y = qRound(y * Q_FIXED_POINT_SCALE);
1616 break;
1617 case QPainterPath::CurveToElement:
1618 {
1619 qreal pts[8];
1620 for (int i = 0; i < 4; ++i)
1621 matrix.map(p[2 * i - 2], p[2 * i - 1], &pts[2 * i + 0], &pts[2 * i + 1]);
1622 for (int i = 0; i < 8; ++i)
1623 pts[i] *= lod;
1624 QBezier bezier = QBezier::fromPoints(QPointF(pts[0], pts[1]), QPointF(pts[2], pts[3]), QPointF(pts[4], pts[5]), QPointF(pts[6], pts[7]));
1625 QPolygonF poly = bezier.toPolygon();
1626 // Skip first point, it already exists in 'm_vertices'.
1627 for (int j = 1; j < poly.size(); ++j) {
1628 m_indices.push_back(T(m_vertices.size()));
1629 m_vertices.resize(m_vertices.size() + 1);
1630 m_vertices.last().x = qRound(poly.at(j).x() * Q_FIXED_POINT_SCALE / lod);
1631 m_vertices.last().y = qRound(poly.at(j).y() * Q_FIXED_POINT_SCALE / lod);
1632 }
1633 }
1634 i += 2;
1635 e += 2;
1636 p += 4;
1637 break;
1638 default:
1639 Q_ASSERT_X(0, "QTriangulator::triangulate", "Unexpected element type.");
1640 break;
1641 }
1642 }
1643 } else {
1644 for (int i = 0; i < path.elementCount(); ++i, p += 2) {
1645 m_indices.push_back(T(m_vertices.size()));
1646 m_vertices.resize(m_vertices.size() + 1);
1647 qreal x, y;
1648 matrix.map(p[0], p[1], &x, &y);
1649 m_vertices.last().x = qRound(x * Q_FIXED_POINT_SCALE);
1650 m_vertices.last().y = qRound(y * Q_FIXED_POINT_SCALE);
1651 }
1652 }
1653 m_indices.push_back(T(-1)); // Q_TRIANGULATE_END_OF_POLYGON
1654}
1655
1656template <typename T>
1657void QTriangulator<T>::initialize(const QPainterPath &path, const QTransform &matrix, qreal lod)
1658{
1659 initialize(qtVectorPathForPath(path), matrix, lod);
1660}
1661
1662//============================================================================//
1663// QTriangulator::ComplexToSimple //
1664//============================================================================//
1665template <typename T>
1666void QTriangulator<T>::ComplexToSimple::decompose()
1667{
1668 m_initialPointCount = m_parent->m_vertices.size();
1669 initEdges();
1670 do {
1671 calculateIntersections();
1672 } while (splitEdgesAtIntersections());
1673
1674 removeUnwantedEdgesAndConnect();
1675 removeUnusedPoints();
1676
1677 m_parent->m_indices.clear();
1678 QBitArray processed(m_edges.size(), false);
1679 for (int first = 0; first < m_edges.size(); ++first) {
1680 // If already processed, or if unused path, skip.
1681 if (processed.at(first) || m_edges.at(first).next == -1)
1682 continue;
1683
1684 int i = first;
1685 do {
1686 Q_ASSERT(!processed.at(i));
1687 Q_ASSERT(m_edges.at(m_edges.at(i).next).previous == i);
1688 m_parent->m_indices.push_back(m_edges.at(i).from);
1689 processed.setBit(i);
1690 i = m_edges.at(i).next; // CCW order
1691 } while (i != first);
1692 m_parent->m_indices.push_back(T(-1)); // Q_TRIANGULATE_END_OF_POLYGON
1693 }
1694}
1695
1696template <typename T>
1697void QTriangulator<T>::ComplexToSimple::initEdges()
1698{
1699 // Initialize edge structure.
1700 // 'next' and 'previous' are not being initialized at this point.
1701 int first = 0;
1702 for (int i = 0; i < m_parent->m_indices.size(); ++i) {
1703 if (m_parent->m_indices.at(i) == T(-1)) { // Q_TRIANGULATE_END_OF_POLYGON
1704 if (m_edges.size() != first)
1705 m_edges.last().to = m_edges.at(first).from;
1706 first = m_edges.size();
1707 } else {
1708 Q_ASSERT(i + 1 < m_parent->m_indices.size());
1709 // {node, from, to, next, previous, winding, mayIntersect, pointingUp, originallyPointingUp}
1710 Edge edge = {0, m_parent->m_indices.at(i), m_parent->m_indices.at(i + 1), -1, -1, 0, true, false, false};
1711 m_edges.add(edge);
1712 }
1713 }
1714 if (first != m_edges.size())
1715 m_edges.last().to = m_edges.at(first).from;
1716 for (int i = 0; i < m_edges.size(); ++i) {
1717 m_edges.at(i).originallyPointingUp = m_edges.at(i).pointingUp =
1718 m_parent->m_vertices.at(m_edges.at(i).to) < m_parent->m_vertices.at(m_edges.at(i).from);
1719 }
1720}
1721
1722// Return true if new intersection was found
1723template <typename T>
1724bool QTriangulator<T>::ComplexToSimple::calculateIntersection(int left, int right)
1725{
1726 const Edge &e1 = m_edges.at(left);
1727 const Edge &e2 = m_edges.at(right);
1728
1729 const QPodPoint &u1 = m_parent->m_vertices.at((qint32)e1.from);
1730 const QPodPoint &u2 = m_parent->m_vertices.at((qint32)e1.to);
1731 const QPodPoint &v1 = m_parent->m_vertices.at((qint32)e2.from);
1732 const QPodPoint &v2 = m_parent->m_vertices.at((qint32)e2.to);
1733 if (qMax(u1.x, u2.x) <= qMin(v1.x, v2.x))
1734 return false;
1735
1736 quint64 key = (left > right ? (quint64(right) << 32) | quint64(left) : (quint64(left) << 32) | quint64(right));
1737 if (m_processedEdgePairs.contains(key))
1738 return false;
1739 m_processedEdgePairs.insert(key);
1740
1741 Intersection intersection;
1742 intersection.leftEdge = left;
1743 intersection.rightEdge = right;
1744 intersection.intersectionPoint = QT_PREPEND_NAMESPACE(qIntersectionPoint)(u1, u2, v1, v2);
1745
1746 if (!intersection.intersectionPoint.isValid())
1747 return false;
1748
1749 Q_ASSERT(intersection.intersectionPoint.isOnLine(u1, u2));
1750 Q_ASSERT(intersection.intersectionPoint.isOnLine(v1, v2));
1751
1752 intersection.vertex = m_parent->m_vertices.size();
1753 m_topIntersection.push(intersection);
1754 m_parent->m_vertices.add(intersection.intersectionPoint.round());
1755 return true;
1756}
1757
1758template <typename T>
1759bool QTriangulator<T>::ComplexToSimple::edgeIsLeftOfEdge(int leftEdgeIndex, int rightEdgeIndex) const
1760{
1761 const Edge &leftEdge = m_edges.at(leftEdgeIndex);
1762 const Edge &rightEdge = m_edges.at(rightEdgeIndex);
1763 const QPodPoint &u = m_parent->m_vertices.at(rightEdge.upper());
1764 const QPodPoint &l = m_parent->m_vertices.at(rightEdge.lower());
1765 const QPodPoint &upper = m_parent->m_vertices.at(leftEdge.upper());
1766 if (upper.x < qMin(l.x, u.x))
1767 return true;
1768 if (upper.x > qMax(l.x, u.x))
1769 return false;
1770 qint64 d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(upper, l, u);
1771 // d < 0: left, d > 0: right, d == 0: on top
1772 if (d == 0)
1773 d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(m_parent->m_vertices.at(leftEdge.lower()), l, u);
1774 return d < 0;
1775}
1776
1777template <typename T>
1778QRBTree<int>::Node *QTriangulator<T>::ComplexToSimple::searchEdgeLeftOf(int edgeIndex) const
1779{
1780 QRBTree<int>::Node *current = m_edgeList.root;
1781 QRBTree<int>::Node *result = 0;
1782 while (current) {
1783 if (edgeIsLeftOfEdge(edgeIndex, current->data)) {
1784 current = current->left;
1785 } else {
1786 result = current;
1787 current = current->right;
1788 }
1789 }
1790 return result;
1791}
1792
1793template <typename T>
1794QRBTree<int>::Node *QTriangulator<T>::ComplexToSimple::searchEdgeLeftOf(int edgeIndex, QRBTree<int>::Node *after) const
1795{
1796 if (!m_edgeList.root)
1797 return after;
1798 QRBTree<int>::Node *result = after;
1799 QRBTree<int>::Node *current = (after ? m_edgeList.next(after) : m_edgeList.front(m_edgeList.root));
1800 while (current) {
1801 if (edgeIsLeftOfEdge(edgeIndex, current->data))
1802 return result;
1803 result = current;
1804 current = m_edgeList.next(current);
1805 }
1806 return result;
1807}
1808
1809template <typename T>
1810QPair<QRBTree<int>::Node *, QRBTree<int>::Node *> QTriangulator<T>::ComplexToSimple::bounds(const QPodPoint &point) const
1811{
1812 QRBTree<int>::Node *current = m_edgeList.root;
1813 QPair<QRBTree<int>::Node *, QRBTree<int>::Node *> result(0, 0);
1814 while (current) {
1815 const QPodPoint &v1 = m_parent->m_vertices.at(m_edges.at(current->data).lower());
1816 const QPodPoint &v2 = m_parent->m_vertices.at(m_edges.at(current->data).upper());
1817 qint64 d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(point, v1, v2);
1818 if (d == 0) {
1819 result.first = result.second = current;
1820 break;
1821 }
1822 current = (d < 0 ? current->left : current->right);
1823 }
1824 if (current == 0)
1825 return result;
1826
1827 current = result.first->left;
1828 while (current) {
1829 const QPodPoint &v1 = m_parent->m_vertices.at(m_edges.at(current->data).lower());
1830 const QPodPoint &v2 = m_parent->m_vertices.at(m_edges.at(current->data).upper());
1831 qint64 d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(point, v1, v2);
1832 Q_ASSERT(d >= 0);
1833 if (d == 0) {
1834 result.first = current;
1835 current = current->left;
1836 } else {
1837 current = current->right;
1838 }
1839 }
1840
1841 current = result.second->right;
1842 while (current) {
1843 const QPodPoint &v1 = m_parent->m_vertices.at(m_edges.at(current->data).lower());
1844 const QPodPoint &v2 = m_parent->m_vertices.at(m_edges.at(current->data).upper());
1845 qint64 d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(point, v1, v2);
1846 Q_ASSERT(d <= 0);
1847 if (d == 0) {
1848 result.second = current;
1849 current = current->right;
1850 } else {
1851 current = current->left;
1852 }
1853 }
1854
1855 return result;
1856}
1857
1858template <typename T>
1859QPair<QRBTree<int>::Node *, QRBTree<int>::Node *> QTriangulator<T>::ComplexToSimple::outerBounds(const QPodPoint &point) const
1860{
1861 QRBTree<int>::Node *current = m_edgeList.root;
1862 QPair<QRBTree<int>::Node *, QRBTree<int>::Node *> result(0, 0);
1863
1864 while (current) {
1865 const QPodPoint &v1 = m_parent->m_vertices.at(m_edges.at(current->data).lower());
1866 const QPodPoint &v2 = m_parent->m_vertices.at(m_edges.at(current->data).upper());
1867 qint64 d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(point, v1, v2);
1868 if (d == 0)
1869 break;
1870 if (d < 0) {
1871 result.second = current;
1872 current = current->left;
1873 } else {
1874 result.first = current;
1875 current = current->right;
1876 }
1877 }
1878
1879 if (!current)
1880 return result;
1881
1882 QRBTree<int>::Node *mid = current;
1883
1884 current = mid->left;
1885 while (current) {
1886 const QPodPoint &v1 = m_parent->m_vertices.at(m_edges.at(current->data).lower());
1887 const QPodPoint &v2 = m_parent->m_vertices.at(m_edges.at(current->data).upper());
1888 qint64 d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(point, v1, v2);
1889 Q_ASSERT(d >= 0);
1890 if (d == 0) {
1891 current = current->left;
1892 } else {
1893 result.first = current;
1894 current = current->right;
1895 }
1896 }
1897
1898 current = mid->right;
1899 while (current) {
1900 const QPodPoint &v1 = m_parent->m_vertices.at(m_edges.at(current->data).lower());
1901 const QPodPoint &v2 = m_parent->m_vertices.at(m_edges.at(current->data).upper());
1902 qint64 d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(point, v1, v2);
1903 Q_ASSERT(d <= 0);
1904 if (d == 0) {
1905 current = current->right;
1906 } else {
1907 result.second = current;
1908 current = current->left;
1909 }
1910 }
1911
1912 return result;
1913}
1914
1915template <typename T>
1916void QTriangulator<T>::ComplexToSimple::splitEdgeListRange(QRBTree<int>::Node *leftmost, QRBTree<int>::Node *rightmost, int vertex, const QIntersectionPoint &intersectionPoint)
1917{
1918 Q_ASSERT(leftmost && rightmost);
1919
1920 // Split.
1921 for (;;) {
1922 const QPodPoint &u = m_parent->m_vertices.at(m_edges.at(leftmost->data).from);
1923 const QPodPoint &v = m_parent->m_vertices.at(m_edges.at(leftmost->data).to);
1924 Q_ASSERT(intersectionPoint.isOnLine(u, v));
1925 const Split split = {vertex, leftmost->data, intersectionPoint.isAccurate()};
1926 if (intersectionPoint.xOffset.numerator != 0 || intersectionPoint.yOffset.numerator != 0 || (intersectionPoint.upperLeft != u && intersectionPoint.upperLeft != v))
1927 m_splits.add(split);
1928 if (leftmost == rightmost)
1929 break;
1930 leftmost = m_edgeList.next(leftmost);
1931 }
1932}
1933
1934template <typename T>
1935void QTriangulator<T>::ComplexToSimple::reorderEdgeListRange(QRBTree<int>::Node *leftmost, QRBTree<int>::Node *rightmost)
1936{
1937 Q_ASSERT(leftmost && rightmost);
1938
1939 QRBTree<int>::Node *storeLeftmost = leftmost;
1940 QRBTree<int>::Node *storeRightmost = rightmost;
1941
1942 // Reorder.
1943 while (leftmost != rightmost) {
1944 Edge &left = m_edges.at(leftmost->data);
1945 Edge &right = m_edges.at(rightmost->data);
1946 qSwap(left.node, right.node);
1947 qSwap(leftmost->data, rightmost->data);
1948 leftmost = m_edgeList.next(leftmost);
1949 if (leftmost == rightmost)
1950 break;
1951 rightmost = m_edgeList.previous(rightmost);
1952 }
1953
1954 rightmost = m_edgeList.next(storeRightmost);
1955 leftmost = m_edgeList.previous(storeLeftmost);
1956 if (leftmost)
1957 calculateIntersection(leftmost->data, storeLeftmost->data);
1958 if (rightmost)
1959 calculateIntersection(storeRightmost->data, rightmost->data);
1960}
1961
1962template <typename T>
1963void QTriangulator<T>::ComplexToSimple::sortEdgeList(const QPodPoint eventPoint)
1964{
1965 QIntersectionPoint eventPoint2 = QT_PREPEND_NAMESPACE(qIntersectionPoint)(eventPoint);
1966 while (!m_topIntersection.isEmpty() && m_topIntersection.top().intersectionPoint < eventPoint2) {
1967 Intersection intersection = m_topIntersection.pop();
1968
1969 QIntersectionPoint currentIntersectionPoint = intersection.intersectionPoint;
1970 int currentVertex = intersection.vertex;
1971
1972 QRBTree<int>::Node *leftmost = m_edges.at(intersection.leftEdge).node;
1973 QRBTree<int>::Node *rightmost = m_edges.at(intersection.rightEdge).node;
1974
1975 for (;;) {
1976 QRBTree<int>::Node *previous = m_edgeList.previous(leftmost);
1977 if (!previous)
1978 break;
1979 const Edge &edge = m_edges.at(previous->data);
1980 const QPodPoint &u = m_parent->m_vertices.at((qint32)edge.from);
1981 const QPodPoint &v = m_parent->m_vertices.at((qint32)edge.to);
1982 if (!currentIntersectionPoint.isOnLine(u, v)) {
1983 Q_ASSERT(!currentIntersectionPoint.isAccurate() || qCross(currentIntersectionPoint.upperLeft - u, v - u) != 0);
1984 break;
1985 }
1986 leftmost = previous;
1987 }
1988
1989 for (;;) {
1990 QRBTree<int>::Node *next = m_edgeList.next(rightmost);
1991 if (!next)
1992 break;
1993 const Edge &edge = m_edges.at(next->data);
1994 const QPodPoint &u = m_parent->m_vertices.at((qint32)edge.from);
1995 const QPodPoint &v = m_parent->m_vertices.at((qint32)edge.to);
1996 if (!currentIntersectionPoint.isOnLine(u, v)) {
1997 Q_ASSERT(!currentIntersectionPoint.isAccurate() || qCross(currentIntersectionPoint.upperLeft - u, v - u) != 0);
1998 break;
1999 }
2000 rightmost = next;
2001 }
2002
2003 Q_ASSERT(leftmost && rightmost);
2004 splitEdgeListRange(leftmost, rightmost, currentVertex, currentIntersectionPoint);
2005 reorderEdgeListRange(leftmost, rightmost);
2006
2007 while (!m_topIntersection.isEmpty() && m_topIntersection.top().intersectionPoint <= currentIntersectionPoint)
2008 m_topIntersection.pop();
2009
2010#ifdef Q_TRIANGULATOR_DEBUG
2011 DebugDialog dialog(this, intersection.vertex);
2012 dialog.exec();
2013#endif
2014
2015 }
2016}
2017
2018template <typename T>
2019void QTriangulator<T>::ComplexToSimple::fillPriorityQueue()
2020{
2021 m_events.reset();
2022 m_events.reserve(m_edges.size() * 2);
2023 for (int i = 0; i < m_edges.size(); ++i) {
2024 Q_ASSERT(m_edges.at(i).previous == -1 && m_edges.at(i).next == -1);
2025 Q_ASSERT(m_edges.at(i).node == 0);
2026 Q_ASSERT(m_edges.at(i).pointingUp == m_edges.at(i).originallyPointingUp);
2027 Q_ASSERT(m_edges.at(i).pointingUp == (m_parent->m_vertices.at(m_edges.at(i).to) < m_parent->m_vertices.at(m_edges.at(i).from)));
2028 // Ignore zero-length edges.
2029 if (m_parent->m_vertices.at(m_edges.at(i).to) != m_parent->m_vertices.at(m_edges.at(i).from)) {
2030 QPodPoint upper = m_parent->m_vertices.at(m_edges.at(i).upper());
2031 QPodPoint lower = m_parent->m_vertices.at(m_edges.at(i).lower());
2032 Event upperEvent = {{upper.x, upper.y}, Event::Upper, i};
2033 Event lowerEvent = {{lower.x, lower.y}, Event::Lower, i};
2034 m_events.add(upperEvent);
2035 m_events.add(lowerEvent);
2036 }
2037 }
2038 //qSort(m_events.data(), m_events.data() + m_events.size());
2039 sort(m_events.data(), m_events.size());
2040}
2041
2042template <typename T>
2043void QTriangulator<T>::ComplexToSimple::calculateIntersections()
2044{
2045 fillPriorityQueue();
2046
2047 Q_ASSERT(m_topIntersection.empty());
2048 Q_ASSERT(m_edgeList.root == 0);
2049
2050 // Find all intersection points.
2051 while (!m_events.isEmpty()) {
2052 Event event = m_events.last();
2053 sortEdgeList(event.point);
2054
2055 // Find all edges in the edge list that contain the current vertex and mark them to be split later.
2056 QPair<QRBTree<int>::Node *, QRBTree<int>::Node *> range = bounds(event.point);
2057 QRBTree<int>::Node *leftNode = range.first ? m_edgeList.previous(range.first) : 0;
2058 int vertex = (event.type == Event::Upper ? m_edges.at(event.edge).upper() : m_edges.at(event.edge).lower());
2059 QIntersectionPoint eventPoint = QT_PREPEND_NAMESPACE(qIntersectionPoint)(event.point);
2060
2061 if (range.first != 0) {
2062 splitEdgeListRange(range.first, range.second, vertex, eventPoint);
2063 reorderEdgeListRange(range.first, range.second);
2064 }
2065
2066 // Handle the edges with start or end point in the current vertex.
2067 while (!m_events.isEmpty() && m_events.last().point == event.point) {
2068 event = m_events.last();
2069 m_events.pop_back();
2070 int i = event.edge;
2071
2072 if (m_edges.at(i).node) {
2073 // Remove edge from edge list.
2074 Q_ASSERT(event.type == Event::Lower);
2075 QRBTree<int>::Node *left = m_edgeList.previous(m_edges.at(i).node);
2076 QRBTree<int>::Node *right = m_edgeList.next(m_edges.at(i).node);
2077 m_edgeList.deleteNode(m_edges.at(i).node);
2078 if (!left || !right)
2079 continue;
2080 calculateIntersection(left->data, right->data);
2081 } else {
2082 // Insert edge into edge list.
2083 Q_ASSERT(event.type == Event::Upper);
2084 QRBTree<int>::Node *left = searchEdgeLeftOf(i, leftNode);
2085 m_edgeList.attachAfter(left, m_edges.at(i).node = m_edgeList.newNode());
2086 m_edges.at(i).node->data = i;
2087 QRBTree<int>::Node *right = m_edgeList.next(m_edges.at(i).node);
2088 if (left)
2089 calculateIntersection(left->data, i);
2090 if (right)
2091 calculateIntersection(i, right->data);
2092 }
2093 }
2094 while (!m_topIntersection.isEmpty() && m_topIntersection.top().intersectionPoint <= eventPoint)
2095 m_topIntersection.pop();
2096#ifdef Q_TRIANGULATOR_DEBUG
2097 DebugDialog dialog(this, vertex);
2098 dialog.exec();
2099#endif
2100 }
2101 m_processedEdgePairs.clear();
2102}
2103
2104// Split an edge into two pieces at the given point.
2105// The upper piece is pushed to the end of the 'm_edges' vector.
2106// The lower piece replaces the old edge.
2107// Return the edge whose 'from' is 'pointIndex'.
2108template <typename T>
2109int QTriangulator<T>::ComplexToSimple::splitEdge(int splitIndex)
2110{
2111 const Split &split = m_splits.at(splitIndex);
2112 Edge &lowerEdge = m_edges.at(split.edge);
2113 Q_ASSERT(lowerEdge.node == 0);
2114 Q_ASSERT(lowerEdge.previous == -1 && lowerEdge.next == -1);
2115
2116 if (lowerEdge.from == split.vertex)
2117 return split.edge;
2118 if (lowerEdge.to == split.vertex)
2119 return lowerEdge.next;
2120
2121 // Check that angle >= 90 degrees.
2122 //Q_ASSERT(qDot(m_points.at(m_edges.at(edgeIndex).from) - m_points.at(pointIndex),
2123 // m_points.at(m_edges.at(edgeIndex).to) - m_points.at(pointIndex)) <= 0);
2124
2125 Edge upperEdge = lowerEdge;
2126 upperEdge.mayIntersect |= !split.accurate; // The edge may have been split before at an inaccurate split point.
2127 lowerEdge.mayIntersect = !split.accurate;
2128 if (lowerEdge.pointingUp) {
2129 lowerEdge.to = upperEdge.from = split.vertex;
2130 m_edges.add(upperEdge);
2131 return m_edges.size() - 1;
2132 } else {
2133 lowerEdge.from = upperEdge.to = split.vertex;
2134 m_edges.add(upperEdge);
2135 return split.edge;
2136 }
2137}
2138
2139template <typename T>
2140bool QTriangulator<T>::ComplexToSimple::splitEdgesAtIntersections()
2141{
2142 for (int i = 0; i < m_edges.size(); ++i)
2143 m_edges.at(i).mayIntersect = false;
2144 bool checkForNewIntersections = false;
2145 for (int i = 0; i < m_splits.size(); ++i) {
2146 splitEdge(i);
2147 checkForNewIntersections |= !m_splits.at(i).accurate;
2148 }
2149 for (int i = 0; i < m_edges.size(); ++i) {
2150 m_edges.at(i).originallyPointingUp = m_edges.at(i).pointingUp =
2151 m_parent->m_vertices.at(m_edges.at(i).to) < m_parent->m_vertices.at(m_edges.at(i).from);
2152 }
2153 m_splits.reset();
2154 return checkForNewIntersections;
2155}
2156
2157template <typename T>
2158void QTriangulator<T>::ComplexToSimple::insertEdgeIntoVectorIfWanted(ShortArray &orderedEdges, int i)
2159{
2160 // Edges with zero length should not reach this part.
2161 Q_ASSERT(m_parent->m_vertices.at(m_edges.at(i).from) != m_parent->m_vertices.at(m_edges.at(i).to));
2162
2163 // Skip edges with unwanted winding number.
2164 int windingNumber = m_edges.at(i).winding;
2165 if (m_edges.at(i).originallyPointingUp)
2166 ++windingNumber;
2167
2168 // Make sure exactly one fill rule is specified.
2169 Q_ASSERT(((m_parent->m_hint & QVectorPath::WindingFill) != 0) != ((m_parent->m_hint & QVectorPath::OddEvenFill) != 0));
2170
2171 if ((m_parent->m_hint & QVectorPath::WindingFill) && windingNumber != 0 && windingNumber != 1)
2172 return;
2173
2174 // Skip cancelling edges.
2175 if (!orderedEdges.isEmpty()) {
2176 int j = orderedEdges[orderedEdges.size() - 1];
2177 // If the last edge is already connected in one end, it should not be cancelled.
2178 if (m_edges.at(j).next == -1 && m_edges.at(j).previous == -1
2179 && (m_parent->m_vertices.at(m_edges.at(i).from) == m_parent->m_vertices.at(m_edges.at(j).to))
2180 && (m_parent->m_vertices.at(m_edges.at(i).to) == m_parent->m_vertices.at(m_edges.at(j).from))) {
2181 orderedEdges.removeLast();
2182 return;
2183 }
2184 }
2185 orderedEdges.append(i);
2186}
2187
2188template <typename T>
2189void QTriangulator<T>::ComplexToSimple::removeUnwantedEdgesAndConnect()
2190{
2191 Q_ASSERT(m_edgeList.root == 0);
2192 // Initialize priority queue.
2193 fillPriorityQueue();
2194
2195 ShortArray orderedEdges;
2196
2197 while (!m_events.isEmpty()) {
2198 Event event = m_events.last();
2199 int edgeIndex = event.edge;
2200
2201 // Check that all the edges in the list crosses the current scanline
2202 //if (m_edgeList.root) {
2203 // for (QRBTree<int>::Node *node = m_edgeList.front(m_edgeList.root); node; node = m_edgeList.next(node)) {
2204 // Q_ASSERT(event.point <= m_points.at(m_edges.at(node->data).lower()));
2205 // }
2206 //}
2207
2208 orderedEdges.clear();
2209 QPair<QRBTree<int>::Node *, QRBTree<int>::Node *> b = outerBounds(event.point);
2210 if (m_edgeList.root) {
2211 QRBTree<int>::Node *current = (b.first ? m_edgeList.next(b.first) : m_edgeList.front(m_edgeList.root));
2212 // Process edges that are going to be removed from the edge list at the current event point.
2213 while (current != b.second) {
2214 Q_ASSERT(current);
2215 Q_ASSERT(m_edges.at(current->data).node == current);
2216 Q_ASSERT(QT_PREPEND_NAMESPACE(qIntersectionPoint)(event.point).isOnLine(m_parent->m_vertices.at(m_edges.at(current->data).from), m_parent->m_vertices.at(m_edges.at(current->data).to)));
2217 Q_ASSERT(m_parent->m_vertices.at(m_edges.at(current->data).from) == event.point || m_parent->m_vertices.at(m_edges.at(current->data).to) == event.point);
2218 insertEdgeIntoVectorIfWanted(orderedEdges, current->data);
2219 current = m_edgeList.next(current);
2220 }
2221 }
2222
2223 // Remove edges above the event point, insert edges below the event point.
2224 do {
2225 event = m_events.last();
2226 m_events.pop_back();
2227 edgeIndex = event.edge;
2228
2229 // Edges with zero length should not reach this part.
2230 Q_ASSERT(m_parent->m_vertices.at(m_edges.at(edgeIndex).from) != m_parent->m_vertices.at(m_edges.at(edgeIndex).to));
2231
2232 if (m_edges.at(edgeIndex).node) {
2233 Q_ASSERT(event.type == Event::Lower);
2234 Q_ASSERT(event.point == m_parent->m_vertices.at(m_edges.at(event.edge).lower()));
2235 m_edgeList.deleteNode(m_edges.at(edgeIndex).node);
2236 } else {
2237 Q_ASSERT(event.type == Event::Upper);
2238 Q_ASSERT(event.point == m_parent->m_vertices.at(m_edges.at(event.edge).upper()));
2239 QRBTree<int>::Node *left = searchEdgeLeftOf(edgeIndex, b.first);
2240 m_edgeList.attachAfter(left, m_edges.at(edgeIndex).node = m_edgeList.newNode());
2241 m_edges.at(edgeIndex).node->data = edgeIndex;
2242 }
2243 } while (!m_events.isEmpty() && m_events.last().point == event.point);
2244
2245 if (m_edgeList.root) {
2246 QRBTree<int>::Node *current = (b.first ? m_edgeList.next(b.first) : m_edgeList.front(m_edgeList.root));
2247
2248 // Calculate winding number and turn counter-clockwise.
2249 int currentWindingNumber = (b.first ? m_edges.at(b.first->data).winding : 0);
2250 while (current != b.second) {
2251 Q_ASSERT(current);
2252 //Q_ASSERT(b.second == 0 || m_edgeList.order(current, b.second) < 0);
2253 int i = current->data;
2254 Q_ASSERT(m_edges.at(i).node == current);
2255
2256 // Winding number.
2257 int ccwWindingNumber = m_edges.at(i).winding = currentWindingNumber;
2258 if (m_edges.at(i).originallyPointingUp) {
2259 --m_edges.at(i).winding;
2260 } else {
2261 ++m_edges.at(i).winding;
2262 ++ccwWindingNumber;
2263 }
2264 currentWindingNumber = m_edges.at(i).winding;
2265
2266 // Turn counter-clockwise.
2267 if ((ccwWindingNumber & 1) == 0) {
2268 Q_ASSERT(m_edges.at(i).previous == -1 && m_edges.at(i).next == -1);
2269 qSwap(m_edges.at(i).from, m_edges.at(i).to);
2270 m_edges.at(i).pointingUp = !m_edges.at(i).pointingUp;
2271 }
2272
2273 current = m_edgeList.next(current);
2274 }
2275
2276 // Process edges that were inserted into the edge list at the current event point.
2277 current = (b.second ? m_edgeList.previous(b.second) : m_edgeList.back(m_edgeList.root));
2278 while (current != b.first) {
2279 Q_ASSERT(current);
2280 Q_ASSERT(m_edges.at(current->data).node == current);
2281 insertEdgeIntoVectorIfWanted(orderedEdges, current->data);
2282 current = m_edgeList.previous(current);
2283 }
2284 }
2285 if (orderedEdges.isEmpty())
2286 continue;
2287
2288 Q_ASSERT((orderedEdges.size() & 1) == 0);
2289
2290 // Connect edges.
2291 // First make sure the first edge point towards the current point.
2292 int i;
2293 if (m_parent->m_vertices.at(m_edges.at(orderedEdges[0]).from) == event.point) {
2294 i = 1;
2295 int copy = orderedEdges[0]; // Make copy in case the append() will cause a reallocation.
2296 orderedEdges.append(copy);
2297 } else {
2298 Q_ASSERT(m_parent->m_vertices.at(m_edges.at(orderedEdges[0]).to) == event.point);
2299 i = 0;
2300 }
2301
2302 // Remove references to duplicate points. First find the point with lowest index.
2303 int pointIndex = INT_MAX;
2304 for (int j = i; j < orderedEdges.size(); j += 2) {
2305 Q_ASSERT(j + 1 < orderedEdges.size());
2306 Q_ASSERT(m_parent->m_vertices.at(m_edges.at(orderedEdges[j]).to) == event.point);
2307 Q_ASSERT(m_parent->m_vertices.at(m_edges.at(orderedEdges[j + 1]).from) == event.point);
2308 if (m_edges.at(orderedEdges[j]).to < pointIndex)
2309 pointIndex = m_edges.at(orderedEdges[j]).to;
2310 if (m_edges.at(orderedEdges[j + 1]).from < pointIndex)
2311 pointIndex = m_edges.at(orderedEdges[j + 1]).from;
2312 }
2313
2314 for (; i < orderedEdges.size(); i += 2) {
2315 // Remove references to duplicate points by making all edges reference one common point.
2316 m_edges.at(orderedEdges[i]).to = m_edges.at(orderedEdges[i + 1]).from = pointIndex;
2317
2318 Q_ASSERT(m_edges.at(orderedEdges[i]).pointingUp || m_edges.at(orderedEdges[i]).previous != -1);
2319 Q_ASSERT(!m_edges.at(orderedEdges[i + 1]).pointingUp || m_edges.at(orderedEdges[i + 1]).next != -1);
2320
2321 m_edges.at(orderedEdges[i]).next = orderedEdges[i + 1];
2322 m_edges.at(orderedEdges[i + 1]).previous = orderedEdges[i];
2323 }
2324 } // end while
2325}
2326
2327template <typename T>
2328void QTriangulator<T>::ComplexToSimple::removeUnusedPoints() {
2329 QBitArray used(m_parent->m_vertices.size(), false);
2330 for (int i = 0; i < m_edges.size(); ++i) {
2331 Q_ASSERT((m_edges.at(i).previous == -1) == (m_edges.at(i).next == -1));
2332 if (m_edges.at(i).next != -1)
2333 used.setBit(m_edges.at(i).from);
2334 }
2335 QDataBuffer<quint32> newMapping(m_parent->m_vertices.size());
2336 newMapping.resize(m_parent->m_vertices.size());
2337 int count = 0;
2338 for (int i = 0; i < m_parent->m_vertices.size(); ++i) {
2339 if (used.at(i)) {
2340 m_parent->m_vertices.at(count) = m_parent->m_vertices.at(i);
2341 newMapping.at(i) = count;
2342 ++count;
2343 }
2344 }
2345 m_parent->m_vertices.resize(count);
2346 for (int i = 0; i < m_edges.size(); ++i) {
2347 m_edges.at(i).from = newMapping.at(m_edges.at(i).from);
2348 m_edges.at(i).to = newMapping.at(m_edges.at(i).to);
2349 }
2350}
2351
2352template <typename T>
2353bool QTriangulator<T>::ComplexToSimple::CompareEdges::operator () (int i, int j) const
2354{
2355 int cmp = comparePoints(m_parent->m_parent->m_vertices.at(m_parent->m_edges.at(i).from),
2356 m_parent->m_parent->m_vertices.at(m_parent->m_edges.at(j).from));
2357 if (cmp == 0) {
2358 cmp = comparePoints(m_parent->m_parent->m_vertices.at(m_parent->m_edges.at(i).to),
2359 m_parent->m_parent->m_vertices.at(m_parent->m_edges.at(j).to));
2360 }
2361 return cmp > 0;
2362}
2363
2364template <typename T>
2365inline bool QTriangulator<T>::ComplexToSimple::Event::operator < (const Event &other) const
2366{
2367 if (point == other.point)
2368 return type < other.type; // 'Lower' has higher priority than 'Upper'.
2369 return other.point < point;
2370}
2371
2372//============================================================================//
2373// QTriangulator::ComplexToSimple::DebugDialog //
2374//============================================================================//
2375
2376#ifdef Q_TRIANGULATOR_DEBUG
2377template <typename T>
2378QTriangulator<T>::ComplexToSimple::DebugDialog::DebugDialog(ComplexToSimple *parent, int currentVertex)
2379 : m_parent(parent), m_vertex(currentVertex)
2380{
2381 QDataBuffer<QPodPoint> &vertices = m_parent->m_parent->m_vertices;
2382 if (vertices.isEmpty())
2383 return;
2384
2385 int minX, maxX, minY, maxY;
2386 minX = maxX = vertices.at(0).x;
2387 minY = maxY = vertices.at(0).y;
2388 for (int i = 1; i < vertices.size(); ++i) {
2389 minX = qMin(minX, vertices.at(i).x);
2390 maxX = qMax(maxX, vertices.at(i).x);
2391 minY = qMin(minY, vertices.at(i).y);
2392 maxY = qMax(maxY, vertices.at(i).y);
2393 }
2394 int w = maxX - minX;
2395 int h = maxY - minY;
2396 qreal border = qMin(w, h) / 10.0;
2397 m_window = QRectF(minX - border, minY - border, (maxX - minX + 2 * border), (maxY - minY + 2 * border));
2398}
2399
2400template <typename T>
2401void QTriangulator<T>::ComplexToSimple::DebugDialog::paintEvent(QPaintEvent *)
2402{
2403 QPainter p(this);
2404 p.setRenderHint(QPainter::Antialiasing, true);
2405 p.fillRect(rect(), Qt::black);
2406 QDataBuffer<QPodPoint> &vertices = m_parent->m_parent->m_vertices;
2407 if (vertices.isEmpty())
2408 return;
2409
2410 qreal halfPointSize = qMin(m_window.width(), m_window.height()) / 300.0;
2411 p.setWindow(m_window.toRect());
2412
2413 p.setPen(Qt::white);
2414
2415 QDataBuffer<Edge> &edges = m_parent->m_edges;
2416 for (int i = 0; i < edges.size(); ++i) {
2417 QPodPoint u = vertices.at(edges.at(i).from);
2418 QPodPoint v = vertices.at(edges.at(i).to);
2419 p.drawLine(u.x, u.y, v.x, v.y);
2420 }
2421
2422 for (int i = 0; i < vertices.size(); ++i) {
2423 QPodPoint q = vertices.at(i);
2424 p.fillRect(QRectF(q.x - halfPointSize, q.y - halfPointSize, 2 * halfPointSize, 2 * halfPointSize), Qt::red);
2425 }
2426
2427 Qt::GlobalColor colors[6] = {Qt::red, Qt::green, Qt::blue, Qt::cyan, Qt::magenta, Qt::yellow};
2428 p.setOpacity(0.5);
2429 int count = 0;
2430 if (m_parent->m_edgeList.root) {
2431 QRBTree<int>::Node *current = m_parent->m_edgeList.front(m_parent->m_edgeList.root);
2432 while (current) {
2433 p.setPen(colors[count++ % 6]);
2434 QPodPoint u = vertices.at(edges.at(current->data).from);
2435 QPodPoint v = vertices.at(edges.at(current->data).to);
2436 p.drawLine(u.x, u.y, v.x, v.y);
2437 current = m_parent->m_edgeList.next(current);
2438 }
2439 }
2440
2441 p.setOpacity(1.0);
2442 QPodPoint q = vertices.at(m_vertex);
2443 p.fillRect(QRectF(q.x - halfPointSize, q.y - halfPointSize, 2 * halfPointSize, 2 * halfPointSize), Qt::green);
2444
2445 p.setPen(Qt::gray);
2446 QDataBuffer<Split> &splits = m_parent->m_splits;
2447 for (int i = 0; i < splits.size(); ++i) {
2448 QPodPoint q = vertices.at(splits.at(i).vertex);
2449 QPodPoint u = vertices.at(edges.at(splits.at(i).edge).from) - q;
2450 QPodPoint v = vertices.at(edges.at(splits.at(i).edge).to) - q;
2451 qreal uLen = sqrt(qreal(qDot(u, u)));
2452 qreal vLen = sqrt(qreal(qDot(v, v)));
2453 if (uLen) {
2454 u.x *= 2 * halfPointSize / uLen;
2455 u.y *= 2 * halfPointSize / uLen;
2456 }
2457 if (vLen) {
2458 v.x *= 2 * halfPointSize / vLen;
2459 v.y *= 2 * halfPointSize / vLen;
2460 }
2461 u += q;
2462 v += q;
2463 p.drawLine(u.x, u.y, v.x, v.y);
2464 }
2465}
2466
2467template <typename T>
2468void QTriangulator<T>::ComplexToSimple::DebugDialog::wheelEvent(QWheelEvent *event)
2469{
2470 qreal scale = exp(-0.001 * event->delta());
2471 QPointF center = m_window.center();
2472 QPointF delta = scale * (m_window.bottomRight() - center);
2473 m_window = QRectF(center - delta, center + delta);
2474 event->accept();
2475 update();
2476}
2477
2478template <typename T>
2479void QTriangulator<T>::ComplexToSimple::DebugDialog::mouseMoveEvent(QMouseEvent *event)
2480{
2481 if (event->buttons() & Qt::LeftButton) {
2482 QPointF delta = event->pos() - m_lastMousePos;
2483 delta.setX(delta.x() * m_window.width() / width());
2484 delta.setY(delta.y() * m_window.height() / height());
2485 m_window.translate(-delta.x(), -delta.y());
2486 m_lastMousePos = event->pos();
2487 event->accept();
2488 update();
2489 }
2490}
2491
2492template <typename T>
2493void QTriangulator<T>::ComplexToSimple::DebugDialog::mousePressEvent(QMouseEvent *event)
2494{
2495 if (event->button() == Qt::LeftButton)
2496 m_lastMousePos = event->pos();
2497 event->accept();
2498}
2499
2500
2501#endif
2502
2503//============================================================================//
2504// QTriangulator::SimpleToMonotone //
2505//============================================================================//
2506template <typename T>
2507void QTriangulator<T>::SimpleToMonotone::decompose()
2508{
2509 setupDataStructures();
2510 removeZeroLengthEdges();
2511 monotoneDecomposition();
2512
2513 m_parent->m_indices.clear();
2514 QBitArray processed(m_edges.size(), false);
2515 for (int first = 0; first < m_edges.size(); ++first) {
2516 if (processed.at(first))
2517 continue;
2518 int i = first;
2519 do {
2520 Q_ASSERT(!processed.at(i));
2521 Q_ASSERT(m_edges.at(m_edges.at(i).next).previous == i);
2522 m_parent->m_indices.push_back(m_edges.at(i).from);
2523 processed.setBit(i);
2524 i = m_edges.at(i).next;
2525 } while (i != first);
2526 if (m_parent->m_indices.size() > 0 && m_parent->m_indices.back() != T(-1)) // Q_TRIANGULATE_END_OF_POLYGON
2527 m_parent->m_indices.push_back(T(-1)); // Q_TRIANGULATE_END_OF_POLYGON
2528 }
2529}
2530
2531template <typename T>
2532void QTriangulator<T>::SimpleToMonotone::setupDataStructures()
2533{
2534 int i = 0;
2535 Edge e;
2536 e.node = 0;
2537 e.twin = -1;
2538
2539 while (i + 3 <= m_parent->m_indices.size()) {
2540 int start = m_edges.size();
2541
2542 do {
2543 e.from = m_parent->m_indices.at(i);
2544 e.type = RegularVertex;
2545 e.next = m_edges.size() + 1;
2546 e.previous = m_edges.size() - 1;
2547 m_edges.add(e);
2548 ++i;
2549 Q_ASSERT(i < m_parent->m_indices.size());
2550 } while (m_parent->m_indices.at(i) != T(-1)); // Q_TRIANGULATE_END_OF_POLYGON
2551
2552 m_edges.last().next = start;
2553 m_edges.at(start).previous = m_edges.size() - 1;
2554 ++i; // Skip Q_TRIANGULATE_END_OF_POLYGON.
2555 }
2556
2557 for (i = 0; i < m_edges.size(); ++i) {
2558 m_edges.at(i).to = m_edges.at(m_edges.at(i).next).from;
2559 m_edges.at(i).pointingUp = m_parent->m_vertices.at(m_edges.at(i).to) < m_parent->m_vertices.at(m_edges.at(i).from);
2560 m_edges.at(i).helper = -1; // Not initialized here.
2561 }
2562}
2563
2564template <typename T>
2565void QTriangulator<T>::SimpleToMonotone::removeZeroLengthEdges()
2566{
2567 for (int i = 0; i < m_edges.size(); ++i) {
2568 if (m_parent->m_vertices.at(m_edges.at(i).from) == m_parent->m_vertices.at(m_edges.at(i).to)) {
2569 m_edges.at(m_edges.at(i).previous).next = m_edges.at(i).next;
2570 m_edges.at(m_edges.at(i).next).previous = m_edges.at(i).previous;
2571 m_edges.at(m_edges.at(i).next).from = m_edges.at(i).from;
2572 m_edges.at(i).next = -1; // Mark as removed.
2573 }
2574 }
2575
2576 QDataBuffer<int> newMapping(m_edges.size());
2577 newMapping.resize(m_edges.size());
2578 int count = 0;
2579 for (int i = 0; i < m_edges.size(); ++i) {
2580 if (m_edges.at(i).next != -1) {
2581 m_edges.at(count) = m_edges.at(i);
2582 newMapping.at(i) = count;
2583 ++count;
2584 }
2585 }
2586 m_edges.resize(count);
2587 for (int i = 0; i < m_edges.size(); ++i) {
2588 m_edges.at(i).next = newMapping.at(m_edges.at(i).next);
2589 m_edges.at(i).previous = newMapping.at(m_edges.at(i).previous);
2590 }
2591}
2592
2593template <typename T>
2594void QTriangulator<T>::SimpleToMonotone::fillPriorityQueue()
2595{
2596 m_upperVertex.reset();
2597 m_upperVertex.reserve(m_edges.size());
2598 for (int i = 0; i < m_edges.size(); ++i)
2599 m_upperVertex.add(i);
2600 CompareVertices cmp(this);
2601 //qSort(m_upperVertex.data(), m_upperVertex.data() + m_upperVertex.size(), cmp);
2602 sort(m_upperVertex.data(), m_upperVertex.size(), cmp);
2603 //for (int i = 1; i < m_upperVertex.size(); ++i) {
2604 // Q_ASSERT(!cmp(m_upperVertex.at(i), m_upperVertex.at(i - 1)));
2605 //}
2606}
2607
2608template <typename T>
2609bool QTriangulator<T>::SimpleToMonotone::edgeIsLeftOfEdge(int leftEdgeIndex, int rightEdgeIndex) const
2610{
2611 const Edge &leftEdge = m_edges.at(leftEdgeIndex);
2612 const Edge &rightEdge = m_edges.at(rightEdgeIndex);
2613 const QPodPoint &u = m_parent->m_vertices.at(rightEdge.upper());
2614 const QPodPoint &l = m_parent->m_vertices.at(rightEdge.lower());
2615 qint64 d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(m_parent->m_vertices.at(leftEdge.upper()), l, u);
2616 // d < 0: left, d > 0: right, d == 0: on top
2617 if (d == 0)
2618 d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(m_parent->m_vertices.at(leftEdge.lower()), l, u);
2619 return d < 0;
2620}
2621
2622// Returns the rightmost edge not to the right of the given edge.
2623template <typename T>
2624QRBTree<int>::Node *QTriangulator<T>::SimpleToMonotone::searchEdgeLeftOfEdge(int edgeIndex) const
2625{
2626 QRBTree<int>::Node *current = m_edgeList.root;
2627 QRBTree<int>::Node *result = 0;
2628 while (current) {
2629 if (edgeIsLeftOfEdge(edgeIndex, current->data)) {
2630 current = current->left;
2631 } else {
2632 result = current;
2633 current = current->right;
2634 }
2635 }
2636 return result;
2637}
2638
2639// Returns the rightmost edge left of the given point.
2640template <typename T>
2641QRBTree<int>::Node *QTriangulator<T>::SimpleToMonotone::searchEdgeLeftOfPoint(int pointIndex) const
2642{
2643 QRBTree<int>::Node *current = m_edgeList.root;
2644 QRBTree<int>::Node *result = 0;
2645 while (current) {
2646 const QPodPoint &p1 = m_parent->m_vertices.at(m_edges.at(current->data).lower());
2647 const QPodPoint &p2 = m_parent->m_vertices.at(m_edges.at(current->data).upper());
2648 qint64 d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(m_parent->m_vertices.at(pointIndex), p1, p2);
2649 if (d <= 0) {
2650 current = current->left;
2651 } else {
2652 result = current;
2653 current = current->right;
2654 }
2655 }
2656 return result;
2657}
2658
2659template <typename T>
2660void QTriangulator<T>::SimpleToMonotone::classifyVertex(int i)
2661{
2662 Edge &e2 = m_edges.at(i);
2663 const Edge &e1 = m_edges.at(e2.previous);
2664
2665 bool startOrSplit = (e1.pointingUp && !e2.pointingUp);
2666 bool endOrMerge = (!e1.pointingUp && e2.pointingUp);
2667
2668 const QPodPoint &p1 = m_parent->m_vertices.at(e1.from);
2669 const QPodPoint &p2 = m_parent->m_vertices.at(e2.from);
2670 const QPodPoint &p3 = m_parent->m_vertices.at(e2.to);
2671 qint64 d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(p1, p2, p3);
2672 Q_ASSERT(d != 0 || (!startOrSplit && !endOrMerge));
2673
2674 e2.type = RegularVertex;
2675
2676 if (m_clockwiseOrder) {
2677 if (startOrSplit)
2678 e2.type = (d < 0 ? SplitVertex : StartVertex);
2679 else if (endOrMerge)
2680 e2.type = (d < 0 ? MergeVertex : EndVertex);
2681 } else {
2682 if (startOrSplit)
2683 e2.type = (d > 0 ? SplitVertex : StartVertex);
2684 else if (endOrMerge)
2685 e2.type = (d > 0 ? MergeVertex : EndVertex);
2686 }
2687}
2688
2689template <typename T>
2690void QTriangulator<T>::SimpleToMonotone::classifyVertices()
2691{
2692 for (int i = 0; i < m_edges.size(); ++i)
2693 classifyVertex(i);
2694}
2695
2696template <typename T>
2697bool QTriangulator<T>::SimpleToMonotone::pointIsInSector(const QPodPoint &p, const QPodPoint &v1, const QPodPoint &v2, const QPodPoint &v3)
2698{
2699 bool leftOfPreviousEdge = !qPointIsLeftOfLine(p, v2, v1);
2700 bool leftOfNextEdge = !qPointIsLeftOfLine(p, v3, v2);
2701
2702 if (qPointIsLeftOfLine(v1, v2, v3))
2703 return leftOfPreviousEdge && leftOfNextEdge;
2704 else
2705 return leftOfPreviousEdge || leftOfNextEdge;
2706}
2707
2708template <typename T>
2709bool QTriangulator<T>::SimpleToMonotone::pointIsInSector(int vertex, int sector)
2710{
2711 const QPodPoint &center = m_parent->m_vertices.at(m_edges.at(sector).from);
2712 // Handle degenerate edges.
2713 while (m_parent->m_vertices.at(m_edges.at(vertex).from) == center)
2714 vertex = m_edges.at(vertex).next;
2715 int next = m_edges.at(sector).next;
2716 while (m_parent->m_vertices.at(m_edges.at(next).from) == center)
2717 next = m_edges.at(next).next;
2718 int previous = m_edges.at(sector).previous;
2719 while (m_parent->m_vertices.at(m_edges.at(previous).from) == center)
2720 previous = m_edges.at(previous).previous;
2721
2722 const QPodPoint &p = m_parent->m_vertices.at(m_edges.at(vertex).from);
2723 const QPodPoint &v1 = m_parent->m_vertices.at(m_edges.at(previous).from);
2724 const QPodPoint &v3 = m_parent->m_vertices.at(m_edges.at(next).from);
2725 if (m_clockwiseOrder)
2726 return pointIsInSector(p, v3, center, v1);
2727 else
2728 return pointIsInSector(p, v1, center, v3);
2729}
2730
2731template <typename T>
2732int QTriangulator<T>::SimpleToMonotone::findSector(int edge, int vertex)
2733{
2734 while (!pointIsInSector(vertex, edge)) {
2735 edge = m_edges.at(m_edges.at(edge).previous).twin;
2736 Q_ASSERT(edge != -1);
2737 }
2738 return edge;
2739}
2740
2741template <typename T>
2742void QTriangulator<T>::SimpleToMonotone::createDiagonal(int lower, int upper)
2743{
2744 lower = findSector(lower, upper);
2745 upper = findSector(upper, lower);
2746
2747 int prevLower = m_edges.at(lower).previous;
2748 int prevUpper = m_edges.at(upper).previous;
2749
2750 Edge e;
2751
2752 e.twin = m_edges.size() + 1;
2753 e.next = upper;
2754 e.previous = prevLower;
2755 e.from = m_edges.at(lower).from;
2756 e.to = m_edges.at(upper).from;
2757 m_edges.at(upper).previous = m_edges.at(prevLower).next = int(m_edges.size());
2758 m_edges.add(e);
2759
2760 e.twin = m_edges.size() - 1;
2761 e.next = lower;
2762 e.previous = prevUpper;
2763 e.from = m_edges.at(upper).from;
2764 e.to = m_edges.at(lower).from;
2765 m_edges.at(lower).previous = m_edges.at(prevUpper).next = int(m_edges.size());
2766 m_edges.add(e);
2767}
2768
2769template <typename T>
2770void QTriangulator<T>::SimpleToMonotone::monotoneDecomposition()
2771{
2772 if (m_edges.isEmpty())
2773 return;
2774
2775 Q_ASSERT(!m_edgeList.root);
2776 QDataBuffer<QPair<int, int> > diagonals(m_upperVertex.size());
2777
2778 int i = 0;
2779 for (int index = 1; index < m_edges.size(); ++index) {
2780 if (m_parent->m_vertices.at(m_edges.at(index).from) < m_parent->m_vertices.at(m_edges.at(i).from))
2781 i = index;
2782 }
2783 Q_ASSERT(i < m_edges.size());
2784 int j = m_edges.at(i).previous;
2785 Q_ASSERT(j < m_edges.size());
2786 m_clockwiseOrder = qPointIsLeftOfLine(m_parent->m_vertices.at((quint32)m_edges.at(i).from),
2787 m_parent->m_vertices.at((quint32)m_edges.at(j).from), m_parent->m_vertices.at((quint32)m_edges.at(i).to));
2788
2789 classifyVertices();
2790 fillPriorityQueue();
2791
2792 // debug: set helpers explicitly (shouldn't be necessary)
2793 //for (int i = 0; i < m_edges.size(); ++i)
2794 // m_edges.at(i).helper = m_edges.at(i).upper();
2795
2796 while (!m_upperVertex.isEmpty()) {
2797 i = m_upperVertex.last();
2798 Q_ASSERT(i < m_edges.size());
2799 m_upperVertex.pop_back();
2800 j = m_edges.at(i).previous;
2801 Q_ASSERT(j < m_edges.size());
2802
2803 QRBTree<int>::Node *leftEdgeNode = 0;
2804
2805 switch (m_edges.at(i).type) {
2806 case RegularVertex:
2807 // If polygon interior is to the right of the vertex...
2808 if (m_edges.at(i).pointingUp == m_clockwiseOrder) {
2809 if (m_edges.at(i).node) {
2810 Q_ASSERT(!m_edges.at(j).node);
2811 if (m_edges.at(m_edges.at(i).helper).type == MergeVertex)
2812 diagonals.add(QPair<int, int>(i, m_edges.at(i).helper));
2813 m_edges.at(j).node = m_edges.at(i).node;
2814 m_edges.at(i).node = 0;
2815 m_edges.at(j).node->data = j;
2816 m_edges.at(j).helper = i;
2817 } else if (m_edges.at(j).node) {
2818 Q_ASSERT(!m_edges.at(i).node);
2819 if (m_edges.at(m_edges.at(j).helper).type == MergeVertex)
2820 diagonals.add(QPair<int, int>(i, m_edges.at(j).helper));
2821 m_edges.at(i).node = m_edges.at(j).node;
2822 m_edges.at(j).node = 0;
2823 m_edges.at(i).node->data = i;
2824 m_edges.at(i).helper = i;
2825 } else {
2826 qWarning("Inconsistent polygon. (#1)");
2827 }
2828 } else {
2829 leftEdgeNode = searchEdgeLeftOfPoint(m_edges.at(i).from);
2830 if (leftEdgeNode) {
2831 if (m_edges.at(m_edges.at(leftEdgeNode->data).helper).type == MergeVertex)
2832 diagonals.add(QPair<int, int>(i, m_edges.at(leftEdgeNode->data).helper));
2833 m_edges.at(leftEdgeNode->data).helper = i;
2834 } else {
2835 qWarning("Inconsistent polygon. (#2)");
2836 }
2837 }
2838 break;
2839 case SplitVertex:
2840 leftEdgeNode = searchEdgeLeftOfPoint(m_edges.at(i).from);
2841 if (leftEdgeNode) {
2842 diagonals.add(QPair<int, int>(i, m_edges.at(leftEdgeNode->data).helper));
2843 m_edges.at(leftEdgeNode->data).helper = i;
2844 } else {
2845 qWarning("Inconsistent polygon. (#3)");
2846 }
2847 // Fall through.
2848 case StartVertex:
2849 if (m_clockwiseOrder) {
2850 leftEdgeNode = searchEdgeLeftOfEdge(j);
2851 QRBTree<int>::Node *node = m_edgeList.newNode();
2852 node->data = j;
2853 m_edges.at(j).node = node;
2854 m_edges.at(j).helper = i;
2855 m_edgeList.attachAfter(leftEdgeNode, node);
2856 Q_ASSERT(m_edgeList.validate());
2857 } else {
2858 leftEdgeNode = searchEdgeLeftOfEdge(i);
2859 QRBTree<int>::Node *node = m_edgeList.newNode();
2860 node->data = i;
2861 m_edges.at(i).node = node;
2862 m_edges.at(i).helper = i;
2863 m_edgeList.attachAfter(leftEdgeNode, node);
2864 Q_ASSERT(m_edgeList.validate());
2865 }
2866 break;
2867 case MergeVertex:
2868 leftEdgeNode = searchEdgeLeftOfPoint(m_edges.at(i).from);
2869 if (leftEdgeNode) {
2870 if (m_edges.at(m_edges.at(leftEdgeNode->data).helper).type == MergeVertex)
2871 diagonals.add(QPair<int, int>(i, m_edges.at(leftEdgeNode->data).helper));
2872 m_edges.at(leftEdgeNode->data).helper = i;
2873 } else {
2874 qWarning("Inconsistent polygon. (#4)");
2875 }
2876 // Fall through.
2877 case EndVertex:
2878 if (m_clockwiseOrder) {
2879 if (m_edges.at(m_edges.at(i).helper).type == MergeVertex)
2880 diagonals.add(QPair<int, int>(i, m_edges.at(i).helper));
2881 if (m_edges.at(i).node) {
2882 m_edgeList.deleteNode(m_edges.at(i).node);
2883 Q_ASSERT(m_edgeList.validate());
2884 } else {
2885 qWarning("Inconsistent polygon. (#5)");
2886 }
2887 } else {
2888 if (m_edges.at(m_edges.at(j).helper).type == MergeVertex)
2889 diagonals.add(QPair<int, int>(i, m_edges.at(j).helper));
2890 if (m_edges.at(j).node) {
2891 m_edgeList.deleteNode(m_edges.at(j).node);
2892 Q_ASSERT(m_edgeList.validate());
2893 } else {
2894 qWarning("Inconsistent polygon. (#6)");
2895 }
2896 }
2897 break;
2898 }
2899 }
2900
2901 for (int i = 0; i < diagonals.size(); ++i)
2902 createDiagonal(diagonals.at(i).first, diagonals.at(i).second);
2903}
2904
2905template <typename T>
2906bool QTriangulator<T>::SimpleToMonotone::CompareVertices::operator () (int i, int j) const
2907{
2908 if (m_parent->m_edges.at(i).from == m_parent->m_edges.at(j).from)
2909 return m_parent->m_edges.at(i).type > m_parent->m_edges.at(j).type;
2910 return m_parent->m_parent->m_vertices.at(m_parent->m_edges.at(i).from) >
2911 m_parent->m_parent->m_vertices.at(m_parent->m_edges.at(j).from);
2912}
2913
2914//============================================================================//
2915// QTriangulator::MonotoneToTriangles //
2916//============================================================================//
2917template <typename T>
2918void QTriangulator<T>::MonotoneToTriangles::decompose()
2919{
2920 QVector<T> result;
2921 QDataBuffer<int> stack(m_parent->m_indices.size());
2922 m_first = 0;
2923 // Require at least three more indices.
2924 while (m_first + 3 <= m_parent->m_indices.size()) {
2925 m_length = 0;
2926 while (m_parent->m_indices.at(m_first + m_length) != T(-1)) { // Q_TRIANGULATE_END_OF_POLYGON
2927 ++m_length;
2928 Q_ASSERT(m_first + m_length < m_parent->m_indices.size());
2929 }
2930 if (m_length < 3) {
2931 m_first += m_length + 1;
2932 continue;
2933 }
2934
2935 int minimum = 0;
2936 while (less(next(minimum), minimum))
2937 minimum = next(minimum);
2938 while (less(previous(minimum), minimum))
2939 minimum = previous(minimum);
2940
2941 stack.reset();
2942 stack.add(minimum);
2943 int left = previous(minimum);
2944 int right = next(minimum);
2945 bool stackIsOnLeftSide;
2946 bool clockwiseOrder = leftOfEdge(minimum, left, right);
2947
2948 if (less(left, right)) {
2949 stack.add(left);
2950 left = previous(left);
2951 stackIsOnLeftSide = true;
2952 } else {
2953 stack.add(right);
2954 right = next(right);
2955 stackIsOnLeftSide = false;
2956 }
2957
2958 for (int count = 0; count + 2 < m_length; ++count)
2959 {
2960 Q_ASSERT(stack.size() >= 2);
2961 if (less(left, right)) {
2962 if (stackIsOnLeftSide == false) {
2963 for (int i = 0; i + 1 < stack.size(); ++i) {
2964 result.push_back(indices(stack.at(i + 1)));
2965 result.push_back(indices(left));
2966 result.push_back(indices(stack.at(i)));
2967 }
2968 stack.first() = stack.last();
2969 stack.resize(1);
2970 } else {
2971 while (stack.size() >= 2 && (clockwiseOrder ^ !leftOfEdge(left, stack.at(stack.size() - 2), stack.last()))) {
2972 result.push_back(indices(stack.at(stack.size() - 2)));
2973 result.push_back(indices(left));
2974 result.push_back(indices(stack.last()));
2975 stack.pop_back();
2976 }
2977 }
2978 stack.add(left);
2979 left = previous(left);
2980 stackIsOnLeftSide = true;
2981 } else {
2982 if (stackIsOnLeftSide == true) {
2983 for (int i = 0; i + 1 < stack.size(); ++i) {
2984 result.push_back(indices(stack.at(i)));
2985 result.push_back(indices(right));
2986 result.push_back(indices(stack.at(i + 1)));
2987 }
2988 stack.first() = stack.last();
2989 stack.resize(1);
2990 } else {
2991 while (stack.size() >= 2 && (clockwiseOrder ^ !leftOfEdge(right, stack.last(), stack.at(stack.size() - 2)))) {
2992 result.push_back(indices(stack.last()));
2993 result.push_back(indices(right));
2994 result.push_back(indices(stack.at(stack.size() - 2)));
2995 stack.pop_back();
2996 }
2997 }
2998 stack.add(right);
2999 right = next(right);
3000 stackIsOnLeftSide = false;
3001 }
3002 }
3003
3004 m_first += m_length + 1;
3005 }
3006 m_parent->m_indices = result;
3007}
3008
3009//============================================================================//
3010// qTriangulate //
3011//============================================================================//
3012
3013QTriangleSet qTriangulate(const qreal *polygon,
3014 int count, uint hint, const QTransform &matrix)
3015{
3016 QTriangleSet triangleSet;
3017 if (QGLExtensions::glExtensions() & QGLExtensions::ElementIndexUint) {
3018 QTriangulator<quint32> triangulator;
3019 triangulator.initialize(polygon, count, hint, matrix);
3020 QVertexSet<quint32> vertexSet = triangulator.triangulate();
3021 triangleSet.vertices = vertexSet.vertices;
3022 triangleSet.indices.setDataUint(vertexSet.indices);
3023
3024 } else {
3025 QTriangulator<quint16> triangulator;
3026 triangulator.initialize(polygon, count, hint, matrix);
3027 QVertexSet<quint16> vertexSet = triangulator.triangulate();
3028 triangleSet.vertices = vertexSet.vertices;
3029 triangleSet.indices.setDataUshort(vertexSet.indices);
3030 }
3031 return triangleSet;
3032}
3033
3034QTriangleSet qTriangulate(const QVectorPath &path,
3035 const QTransform &matrix, qreal lod)
3036{
3037 QTriangleSet triangleSet;
3038 if (QGLExtensions::glExtensions() & QGLExtensions::ElementIndexUint) {
3039 QTriangulator<quint32> triangulator;
3040 triangulator.initialize(path, matrix, lod);
3041 QVertexSet<quint32> vertexSet = triangulator.triangulate();
3042 triangleSet.vertices = vertexSet.vertices;
3043 triangleSet.indices.setDataUint(vertexSet.indices);
3044 } else {
3045 QTriangulator<quint16> triangulator;
3046 triangulator.initialize(path, matrix, lod);
3047 QVertexSet<quint16> vertexSet = triangulator.triangulate();
3048 triangleSet.vertices = vertexSet.vertices;
3049 triangleSet.indices.setDataUshort(vertexSet.indices);
3050 }
3051 return triangleSet;
3052}
3053
3054QTriangleSet qTriangulate(const QPainterPath &path,
3055 const QTransform &matrix, qreal lod)
3056{
3057 QTriangleSet triangleSet;
3058 if (QGLExtensions::glExtensions() & QGLExtensions::ElementIndexUint) {
3059 QTriangulator<quint32> triangulator;
3060 triangulator.initialize(path, matrix, lod);
3061 QVertexSet<quint32> vertexSet = triangulator.triangulate();
3062 triangleSet.vertices = vertexSet.vertices;
3063 triangleSet.indices.setDataUint(vertexSet.indices);
3064 } else {
3065 QTriangulator<quint16> triangulator;
3066 triangulator.initialize(path, matrix, lod);
3067 QVertexSet<quint16> vertexSet = triangulator.triangulate();
3068 triangleSet.vertices = vertexSet.vertices;
3069 triangleSet.indices.setDataUshort(vertexSet.indices);
3070 }
3071 return triangleSet;
3072}
3073
3074QPolylineSet qPolyline(const QVectorPath &path,
3075 const QTransform &matrix, qreal lod)
3076{
3077 QPolylineSet polyLineSet;
3078 if (QGLExtensions::glExtensions() & QGLExtensions::ElementIndexUint) {
3079 QTriangulator<quint32> triangulator;
3080 triangulator.initialize(path, matrix, lod);
3081 QVertexSet<quint32> vertexSet = triangulator.polyline();
3082 polyLineSet.vertices = vertexSet.vertices;
3083 polyLineSet.indices.setDataUint(vertexSet.indices);
3084 } else {
3085 QTriangulator<quint16> triangulator;
3086 triangulator.initialize(path, matrix, lod);
3087 QVertexSet<quint16> vertexSet = triangulator.triangulate();
3088 polyLineSet.vertices = vertexSet.vertices;
3089 polyLineSet.indices.setDataUshort(vertexSet.indices);
3090 }
3091 return polyLineSet;
3092}
3093
3094QPolylineSet qPolyline(const QPainterPath &path,
3095 const QTransform &matrix, qreal lod)
3096{
3097 QPolylineSet polyLineSet;
3098 if (QGLExtensions::glExtensions() & QGLExtensions::ElementIndexUint) {
3099 QTriangulator<quint32> triangulator;
3100 triangulator.initialize(path, matrix, lod);
3101 QVertexSet<quint32> vertexSet = triangulator.polyline();
3102 polyLineSet.vertices = vertexSet.vertices;
3103 polyLineSet.indices.setDataUint(vertexSet.indices);
3104 } else {
3105 QTriangulator<quint16> triangulator;
3106 triangulator.initialize(path, matrix, lod);
3107 QVertexSet<quint16> vertexSet = triangulator.triangulate();
3108 polyLineSet.vertices = vertexSet.vertices;
3109 polyLineSet.indices.setDataUshort(vertexSet.indices);
3110 }
3111 return polyLineSet;
3112}
3113
3114QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.