Qt 4.8
Classes | Public Functions | Properties | Friends | List of all members
QTessellator Class Referenceabstract

#include <qtessellator_p.h>

Inheritance diagram for QTessellator:
QOpenGLTessellator QXRenderTessellator QOpenGLImmediateModeTessellator QOpenGLTrapezoidToArrayTessellator

Classes

struct  Trapezoid
 
struct  Vertex
 

Public Functions

virtual void addTrap (const Trapezoid &trap)=0
 
 QTessellator ()
 
void setWinding (bool w)
 
QRectF tessellate (const QPointF *points, int nPoints)
 
void tessellateConvex (const QPointF *points, int nPoints)
 
void tessellateRect (const QPointF &a, const QPointF &b, qreal width)
 
virtual ~QTessellator ()
 

Properties

QTessellatorPrivated
 

Friends

class QTessellatorPrivate
 

Detailed Description

Definition at line 70 of file qtessellator_p.h.

Constructors and Destructors

◆ QTessellator()

QTessellator::QTessellator ( )

Definition at line 1199 of file qtessellator.cpp.

1200 {
1201  d = new QTessellatorPrivate;
1202 }
QTessellatorPrivate * d
friend class QTessellatorPrivate

◆ ~QTessellator()

QTessellator::~QTessellator ( )
virtual

Definition at line 1204 of file qtessellator.cpp.

1205 {
1206  delete d;
1207 }
QTessellatorPrivate * d

Functions

◆ addTrap()

virtual void QTessellator::addTrap ( const Trapezoid trap)
pure virtual

◆ setWinding()

void QTessellator::setWinding ( bool  w)

Definition at line 1209 of file qtessellator.cpp.

Referenced by QXRenderTessellator::tessellate().

1210 {
1211  d->winding = w;
1212 }
QTessellatorPrivate * d

◆ tessellate()

QRectF QTessellator::tessellate ( const QPointF points,
int  nPoints 
)

Definition at line 1215 of file qtessellator.cpp.

Referenced by QXRenderTessellator::tessellate(), QOpenGLImmediateModeTessellator::tessellate(), and QOpenGLTrapezoidToArrayTessellator::tessellate().

1216 {
1217  Q_ASSERT(points[0] == points[nPoints-1]);
1218  --nPoints;
1219 
1220 #ifdef DEBUG
1221  QDEBUG()<< "POINTS:";
1222  for (int i = 0; i < nPoints; ++i) {
1223  QDEBUG() << points[i];
1224  }
1225 #endif
1226 
1227  // collect edges and calculate bounds
1228  d->vertices.nPoints = nPoints;
1229  d->vertices.init(nPoints);
1230 
1231  int maxActiveEdges = 0;
1232  QRectF br = d->collectAndSortVertices(points, &maxActiveEdges);
1234 
1235 #ifdef DEBUG
1236  QDEBUG() << "nPoints = " << nPoints << "using " << d->vertices.nPoints;
1237  QDEBUG()<< "VERTICES:";
1238  for (int i = 0; i < d->vertices.nPoints; ++i) {
1239  QDEBUG() << " " << i << ": "
1240  << "point=" << d->vertices.position(d->vertices.sorted[i])
1241  << "flags=" << d->vertices.sorted[i]->flags
1242  << "pos=(" << Q27Dot5ToDouble(d->vertices.sorted[i]->x) << '/'
1243  << Q27Dot5ToDouble(d->vertices.sorted[i]->y) << ')';
1244  }
1245 #endif
1246 
1247  d->scanline.init(maxActiveEdges);
1248  d->y = INT_MIN/256;
1249  d->currentVertex = 0;
1250 
1251  while (d->currentVertex < d->vertices.nPoints) {
1252  d->scanline.clearMarks();
1253 
1254  d->y = d->vertices.sorted[d->currentVertex]->y;
1255  if (!d->intersections.isEmpty())
1256  d->y = qMin(d->y, d->intersections.constBegin().key().y);
1257 
1258  QDEBUG()<< "===== SCANLINE: y =" << Q27Dot5ToDouble(d->y) << " =====";
1259 
1260  d->scanline.prepareLine();
1262  d->removeEdges();
1263  d->addEdges();
1264  d->addIntersections();
1265  d->emitEdges(this);
1266  d->scanline.lineDone();
1267 
1268 #ifdef DEBUG
1269  QDEBUG()<< "===== edges:";
1270  for (int i = 0; i < d->scanline.size; ++i) {
1271  QDEBUG() << " " << d->scanline.edges[i]->edge
1272  << "p0= (" << Q27Dot5ToDouble(d->scanline.edges[i]->v0->x)
1273  << '/' << Q27Dot5ToDouble(d->scanline.edges[i]->v0->y)
1274  << ") p1= (" << Q27Dot5ToDouble(d->scanline.edges[i]->v1->x)
1275  << '/' << Q27Dot5ToDouble(d->scanline.edges[i]->v1->y) << ')'
1276  << "x=" << Q27Dot5ToDouble(d->scanline.edges[i]->positionAt(d->y))
1277  << "isLeftOfNext="
1278  << ((i < d->scanline.size - 1)
1279  ? d->scanline.edges[i]->isLeftOf(*d->scanline.edges[i+1], d->y)
1280  : true);
1281  }
1282 #endif
1283 }
1284 
1285  d->scanline.done();
1286  d->intersections.clear();
1287  return br;
1288 }
void init(int maxActiveEdges)
Q_DECL_CONSTEXPR const T & qMin(const T &a, const T &b)
Definition: qglobal.h:1215
#define Q27Dot5ToDouble(i)
int position(const Vertex *v) const
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
QTessellatorPrivate * d
#define QDEBUG
The QRectF class defines a rectangle in the plane using floating point precision. ...
Definition: qrect.h:511
void emitEdges(QTessellator *tessellator)
void init(int maxVertices)
const_iterator constBegin() const
Returns a const STL-style iterator pointing to the first item in the map.
Definition: qmap.h:374
Q27Dot5 positionAt(Q27Dot5 y) const
Intersections intersections
bool isEmpty() const
Returns true if the map contains no items; otherwise returns false.
Definition: qmap.h:203
QRectF collectAndSortVertices(const QPointF *points, int *maxActiveEdges)
bool isLeftOf(const Edge &other, Q27Dot5 y) const
void clear()
Removes all items from the map.
Definition: qmap.h:444

◆ tessellateConvex()

void QTessellator::tessellateConvex ( const QPointF points,
int  nPoints 
)

Definition at line 1291 of file qtessellator.cpp.

1292 {
1293  Q_ASSERT(points[0] == points[nPoints-1]);
1294  --nPoints;
1295 
1296  d->vertices.nPoints = nPoints;
1297  d->vertices.init(nPoints);
1298 
1299  for (int i = 0; i < nPoints; ++i) {
1300  d->vertices[i]->x = FloatToQ27Dot5(points[i].x());
1301  d->vertices[i]->y = FloatToQ27Dot5(points[i].y());
1302  }
1303 
1304  int left = 0, right = 0;
1305 
1306  int top = 0;
1307  for (int i = 1; i < nPoints; ++i) {
1308  if (d->vertices[i]->y < d->vertices[top]->y)
1309  top = i;
1310  }
1311 
1312  left = (top + nPoints - 1) % nPoints;
1313  right = (top + 1) % nPoints;
1314 
1315  while (d->vertices[left]->x == d->vertices[top]->x && d->vertices[left]->y == d->vertices[top]->y && left != right)
1316  left = (left + nPoints - 1) % nPoints;
1317 
1318  while (d->vertices[right]->x == d->vertices[top]->x && d->vertices[right]->y == d->vertices[top]->y && left != right)
1319  right = (right + 1) % nPoints;
1320 
1321  if (left == right)
1322  return;
1323 
1324  int dir = 1;
1325 
1326  Vertex dLeft = { d->vertices[top]->x - d->vertices[left]->x,
1327  d->vertices[top]->y - d->vertices[left]->y };
1328 
1329  Vertex dRight = { d->vertices[right]->x - d->vertices[top]->x,
1330  d->vertices[right]->y - d->vertices[top]->y };
1331 
1332  Q27Dot5 cross = dLeft.x * dRight.y - dLeft.y * dRight.x;
1333 
1334  // flip direction if polygon is clockwise
1335  if (cross < 0 || (cross == 0 && dLeft.x > 0)) {
1336  qSwap(left, right);
1337  dir = -1;
1338  }
1339 
1340  Vertex *lastLeft = d->vertices[top];
1341  Vertex *lastRight = d->vertices[top];
1342 
1344 
1345  while (lastLeft->y == d->vertices[left]->y && left != right) {
1346  lastLeft = d->vertices[left];
1347  left = (left + nPoints - dir) % nPoints;
1348  }
1349 
1350  while (lastRight->y == d->vertices[right]->y && left != right) {
1351  lastRight = d->vertices[right];
1352  right = (right + nPoints + dir) % nPoints;
1353  }
1354 
1355  while (true) {
1356  trap.top = qMax(lastRight->y, lastLeft->y);
1357  trap.bottom = qMin(d->vertices[left]->y, d->vertices[right]->y);
1358  trap.topLeft = lastLeft;
1359  trap.topRight = lastRight;
1360  trap.bottomLeft = d->vertices[left];
1361  trap.bottomRight = d->vertices[right];
1362 
1363  if (trap.bottom > trap.top)
1364  addTrap(trap);
1365 
1366  if (left == right)
1367  break;
1368 
1369  if (d->vertices[right]->y < d->vertices[left]->y) {
1370  do {
1371  lastRight = d->vertices[right];
1372  right = (right + nPoints + dir) % nPoints;
1373  }
1374  while (lastRight->y == d->vertices[right]->y && left != right);
1375  } else {
1376  do {
1377  lastLeft = d->vertices[left];
1378  left = (left + nPoints - dir) % nPoints;
1379  }
1380  while (lastLeft->y == d->vertices[left]->y && left != right);
1381  }
1382  }
1383 }
const Vertex * topRight
Q_DECL_CONSTEXPR const T & qMin(const T &a, const T &b)
Definition: qglobal.h:1215
const Vertex * bottomLeft
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
Q_CORE_EXPORT QTextStream & right(QTextStream &s)
#define FloatToQ27Dot5(i)
Q_DECL_CONSTEXPR const T & qMax(const T &a, const T &b)
Definition: qglobal.h:1217
QTessellatorPrivate * d
const Vertex * bottomRight
void init(int maxVertices)
int Q27Dot5
void qSwap(T &value1, T &value2)
Definition: qglobal.h:2181
const Vertex * topLeft
virtual void addTrap(const Trapezoid &trap)=0
Q_CORE_EXPORT QTextStream & left(QTextStream &s)

◆ tessellateRect()

void QTessellator::tessellateRect ( const QPointF a,
const QPointF b,
qreal  width 
)

Definition at line 1386 of file qtessellator.cpp.

Referenced by QGLLineMaskGenerator::generateTrapezoids().

1387 {
1388  Vertex a = { FloatToQ27Dot5(a_.x()), FloatToQ27Dot5(a_.y()) };
1389  Vertex b = { FloatToQ27Dot5(b_.x()), FloatToQ27Dot5(b_.y()) };
1390 
1391  QPointF pa = a_, pb = b_;
1392 
1393  if (a.y > b.y) {
1394  qSwap(a, b);
1395  qSwap(pa, pb);
1396  }
1397 
1398  Vertex delta = { b.x - a.x, b.y - a.y };
1399 
1400  if (delta.x == 0 && delta.y == 0)
1401  return;
1402 
1403  qreal hw = qreal(0.5) * width;
1404 
1405  if (delta.x == 0) {
1406  Q27Dot5 halfWidth = FloatToQ27Dot5(hw);
1407 
1408  if (halfWidth == 0)
1409  return;
1410 
1411  Vertex topLeft = { a.x - halfWidth, a.y };
1412  Vertex topRight = { a.x + halfWidth, a.y };
1413  Vertex bottomLeft = { a.x - halfWidth, b.y };
1414  Vertex bottomRight = { a.x + halfWidth, b.y };
1415 
1416  QTessellator::Trapezoid trap = { topLeft.y, bottomLeft.y, &topLeft, &bottomLeft, &topRight, &bottomRight };
1417  addTrap(trap);
1418  } else if (delta.y == 0) {
1419  Q27Dot5 halfWidth = FloatToQ27Dot5(hw);
1420 
1421  if (halfWidth == 0)
1422  return;
1423 
1424  if (a.x > b.x)
1425  qSwap(a.x, b.x);
1426 
1427  Vertex topLeft = { a.x, a.y - halfWidth };
1428  Vertex topRight = { b.x, a.y - halfWidth };
1429  Vertex bottomLeft = { a.x, a.y + halfWidth };
1430  Vertex bottomRight = { b.x, a.y + halfWidth };
1431 
1432  QTessellator::Trapezoid trap = { topLeft.y, bottomLeft.y, &topLeft, &bottomLeft, &topRight, &bottomRight };
1433  addTrap(trap);
1434  } else {
1435  QPointF perp(pb.y() - pa.y(), pa.x() - pb.x());
1436  qreal length = qSqrt(perp.x() * perp.x() + perp.y() * perp.y());
1437 
1438  if (qFuzzyIsNull(length))
1439  return;
1440 
1441  // need the half of the width
1442  perp *= hw / length;
1443 
1444  QPointF pta = pa + perp;
1445  QPointF ptb = pa - perp;
1446  QPointF ptc = pb - perp;
1447  QPointF ptd = pb + perp;
1448 
1449  Vertex ta = { FloatToQ27Dot5(pta.x()), FloatToQ27Dot5(pta.y()) };
1450  Vertex tb = { FloatToQ27Dot5(ptb.x()), FloatToQ27Dot5(ptb.y()) };
1451  Vertex tc = { FloatToQ27Dot5(ptc.x()), FloatToQ27Dot5(ptc.y()) };
1452  Vertex td = { FloatToQ27Dot5(ptd.x()), FloatToQ27Dot5(ptd.y()) };
1453 
1454  if (ta.y < tb.y) {
1455  if (tb.y < td.y) {
1456  QTessellator::Trapezoid top = { ta.y, tb.y, &ta, &tb, &ta, &td };
1457  QTessellator::Trapezoid bottom = { td.y, tc.y, &tb, &tc, &td, &tc };
1458  addTrap(top);
1459  addTrap(bottom);
1460 
1461  QTessellator::Trapezoid middle = { tb.y, td.y, &tb, &tc, &ta, &td };
1462  addTrap(middle);
1463  } else {
1464  QTessellator::Trapezoid top = { ta.y, td.y, &ta, &tb, &ta, &td };
1465  QTessellator::Trapezoid bottom = { tb.y, tc.y, &tb, &tc, &td, &tc };
1466  addTrap(top);
1467  addTrap(bottom);
1468 
1469  if (tb.y != td.y) {
1470  QTessellator::Trapezoid middle = { td.y, tb.y, &ta, &tb, &td, &tc };
1471  addTrap(middle);
1472  }
1473  }
1474  } else {
1475  if (ta.y < tc.y) {
1476  QTessellator::Trapezoid top = { tb.y, ta.y, &tb, &tc, &tb, &ta };
1477  QTessellator::Trapezoid bottom = { tc.y, td.y, &tc, &td, &ta, &td };
1478  addTrap(top);
1479  addTrap(bottom);
1480 
1481  QTessellator::Trapezoid middle = { ta.y, tc.y, &tb, &tc, &ta, &td };
1482  addTrap(middle);
1483  } else {
1484  QTessellator::Trapezoid top = { tb.y, tc.y, &tb, &tc, &tb, &ta };
1485  QTessellator::Trapezoid bottom = { ta.y, td.y, &tc, &td, &ta, &td };
1486  addTrap(top);
1487  addTrap(bottom);
1488 
1489  if (ta.y != tc.y) {
1490  QTessellator::Trapezoid middle = { tc.y, ta.y, &tc, &td, &tb, &ta };
1491  addTrap(middle);
1492  }
1493  }
1494  }
1495  }
1496 }
double qreal
Definition: qglobal.h:1193
The QPointF class defines a point in the plane using floating point precision.
Definition: qpoint.h:214
#define FloatToQ27Dot5(i)
qreal x() const
Returns the x-coordinate of this point.
Definition: qpoint.h:282
int Q27Dot5
void qSwap(T &value1, T &value2)
Definition: qglobal.h:2181
static int perp(bool vertical, const QSize &size)
qreal y() const
Returns the y-coordinate of this point.
Definition: qpoint.h:287
static Q_DECL_CONSTEXPR bool qFuzzyIsNull(double d)
Definition: qglobal.h:2043
virtual void addTrap(const Trapezoid &trap)=0
qreal qSqrt(qreal v)
Definition: qmath.h:205

Friends and Related Functions

◆ QTessellatorPrivate

friend class QTessellatorPrivate
friend

Definition at line 96 of file qtessellator_p.h.

Properties

◆ d

QTessellatorPrivate* QTessellator::d
private

Definition at line 97 of file qtessellator_p.h.


The documentation for this class was generated from the following files: