QtBase  v6.3.1
qgraphicsscene_bsp.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the QtWidgets module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39 
40 #include "qgraphicsscene_bsp_p.h"
41 
42 #include <QtCore/qstring.h>
43 #include <private/qgraphicsitem_p.h>
44 
46 
48 {
49 public:
51 
53  { items->prepend(item); }
54 };
55 
57 {
58 public:
60 
62  { items->removeAll(item); }
63 };
64 
66 {
67 public:
70 
72  {
73  for (int i = 0; i < items->size(); ++i) {
76  item = item->topLevelItem();
77  if (!item->d_func()->itemDiscovered && item->d_ptr->visible) {
78  item->d_func()->itemDiscovered = 1;
80  }
81  }
82  }
83 };
84 
86  : leafCnt(0)
87 {
88  insertVisitor = new QGraphicsSceneInsertItemBspTreeVisitor;
89  removeVisitor = new QGraphicsSceneRemoveItemBspTreeVisitor;
90  findVisitor = new QGraphicsSceneFindItemBspTreeVisitor;
91 }
92 
94 {
95  delete insertVisitor;
96  delete removeVisitor;
97  delete findVisitor;
98 }
99 
101 {
102  this->rect = rect;
103  leafCnt = 0;
104  nodes.resize((1 << (depth + 1)) - 1);
105  nodes.fill(Node());
106  leaves.resize(1ll << depth);
107  leaves.fill(QList<QGraphicsItem *>());
108 
109  initialize(rect, depth, 0);
110 }
111 
113 {
114  leafCnt = 0;
115  nodes.clear();
116  leaves.clear();
117 }
118 
120 {
121  insertVisitor->item = item;
122  climbTree(insertVisitor, rect);
123 }
124 
126 {
127  removeVisitor->item = item;
128  climbTree(removeVisitor, rect);
129 }
130 
132 {
133  for (int i = 0; i < leaves.size(); ++i) {
134  QList<QGraphicsItem *> newItemList;
135  const QList<QGraphicsItem *> &oldItemList = leaves[i];
136  for (int j = 0; j < oldItemList.size(); ++j) {
137  QGraphicsItem *item = oldItemList.at(j);
138  if (!items.contains(item))
139  newItemList << item;
140  }
141  leaves[i] = newItemList;
142  }
143 }
144 
145 QList<QGraphicsItem *> QGraphicsSceneBspTree::items(const QRectF &rect, bool onlyTopLevelItems) const
146 {
148  findVisitor->foundItems = &tmp;
149  findVisitor->onlyTopLevelItems = onlyTopLevelItems;
150  climbTree(findVisitor, rect);
151  // Reset discovery bits.
152  for (int i = 0; i < tmp.size(); ++i)
153  tmp.at(i)->d_ptr->itemDiscovered = 0;
154  return tmp;
155 }
156 
158 {
159  return leafCnt;
160 }
161 
163 {
164  const Node *node = &nodes.at(index);
165 
166  QString tmp;
167  if (node->type == Node::Leaf) {
168  QRectF rect = rectForIndex(index);
169  if (!leaves[node->leafIndex].isEmpty()) {
170  tmp += QString::fromLatin1("[%1, %2, %3, %4] contains %5 items\n")
171  .arg(rect.left()).arg(rect.top())
172  .arg(rect.width()).arg(rect.height())
173  .arg(leaves[node->leafIndex].size());
174  }
175  } else {
176  if (node->type == Node::Horizontal) {
177  tmp += debug(firstChildIndex(index));
178  tmp += debug(firstChildIndex(index) + 1);
179  } else {
180  tmp += debug(firstChildIndex(index));
181  tmp += debug(firstChildIndex(index) + 1);
182  }
183  }
184 
185  return tmp;
186 }
187 
189 {
190  Node *node = &nodes[index];
191  if (index == 0) {
192  node->type = Node::Horizontal;
193  node->offset = rect.center().y();
194  }
195 
196  if (depth) {
198  QRectF rect1, rect2;
199  qreal offset1, offset2;
200 
201  if (node->type == Node::Horizontal) {
203  rect1.setRect(rect.left(), rect.top(), rect.width(), rect.height() / 2);
204  rect2.setRect(rect1.left(), rect1.bottom(), rect1.width(), rect.height() - rect1.height());
205  offset1 = rect1.center().x();
206  offset2 = rect2.center().x();
207  } else {
209  rect1.setRect(rect.left(), rect.top(), rect.width() / 2, rect.height());
210  rect2.setRect(rect1.right(), rect1.top(), rect.width() - rect1.width(), rect1.height());
211  offset1 = rect1.center().y();
212  offset2 = rect2.center().y();
213  }
214 
215  int childIndex = firstChildIndex(index);
216 
217  Node *child = &nodes[childIndex];
218  child->offset = offset1;
219  child->type = type;
220 
221  child = &nodes[childIndex + 1];
222  child->offset = offset2;
223  child->type = type;
224 
225  initialize(rect1, depth - 1, childIndex);
226  initialize(rect2, depth - 1, childIndex + 1);
227  } else {
228  node->type = Node::Leaf;
229  node->leafIndex = leafCnt++;
230  }
231 }
232 
233 void QGraphicsSceneBspTree::climbTree(QGraphicsSceneBspTreeVisitor *visitor, const QRectF &rect, int index) const
234 {
235  if (nodes.isEmpty())
236  return;
237 
238  const Node &node = nodes.at(index);
239  const int childIndex = firstChildIndex(index);
240 
241  switch (node.type) {
242  case Node::Leaf: {
243  visitor->visit(const_cast<QList<QGraphicsItem*>*>(&leaves[node.leafIndex]));
244  break;
245  }
246  case Node::Vertical:
247  if (rect.left() < node.offset) {
248  climbTree(visitor, rect, childIndex);
249  if (rect.right() >= node.offset)
250  climbTree(visitor, rect, childIndex + 1);
251  } else {
252  climbTree(visitor, rect, childIndex + 1);
253  }
254  break;
255  case Node::Horizontal:
256  if (rect.top() < node.offset) {
257  climbTree(visitor, rect, childIndex);
258  if (rect.bottom() >= node.offset)
259  climbTree(visitor, rect, childIndex + 1);
260  } else {
261  climbTree(visitor, rect, childIndex + 1);
262  }
263  }
264 }
265 
266 QRectF QGraphicsSceneBspTree::rectForIndex(int index) const
267 {
268  if (index <= 0)
269  return rect;
270 
271  int parentIdx = parentIndex(index);
272  QRectF rect = rectForIndex(parentIdx);
273  const Node *parent = &nodes.at(parentIdx);
274 
275  if (parent->type == Node::Vertical) {
276  if (index & 1)
277  rect.setRight(parent->offset);
278  else
279  rect.setLeft(parent->offset);
280  } else {
281  if (index & 1)
282  rect.setBottom(parent->offset);
283  else
284  rect.setTop(parent->offset);
285  }
286 
287  return rect;
288 }
289 
small capitals from c petite p scientific i
[1]
Definition: afcover.h:80
[0]
Definition: node.h:62
The QGraphicsItem class is the base class for all graphical items in a QGraphicsScene.
Definition: qgraphicsitem.h:83
QScopedPointer< QGraphicsItemPrivate > d_ptr
QGraphicsItem * topLevelItem() const
QGraphicsItem * parent
void removeItem(QGraphicsItem *item, const QRectF &rect)
void removeItems(const QSet< QGraphicsItem * > &items)
int firstChildIndex(int index) const
void initialize(const QRectF &rect, int depth)
int parentIndex(int index) const
QList< QGraphicsItem * > items(const QRectF &rect, bool onlyTopLevelItems=false) const
void insertItem(QGraphicsItem *item, const QRectF &rect)
QString debug(int index) const
virtual void visit(QList< QGraphicsItem * > *items)=0
void visit(QList< QGraphicsItem * > *items) override
QList< QGraphicsItem * > * foundItems
void visit(QList< QGraphicsItem * > *items) override
void visit(QList< QGraphicsItem * > *items) override
qsizetype size() const noexcept
Definition: qlist.h:414
QList< T > & fill(parameter_type t, qsizetype size=-1)
Definition: qlist.h:907
bool isEmpty() const noexcept
Definition: qlist.h:418
const_reference at(qsizetype i) const noexcept
Definition: qlist.h:457
qsizetype removeAll(const AT &t)
Definition: qlist.h:590
void prepend(rvalue_ref t)
Definition: qlist.h:484
void resize(qsizetype size)
Definition: qlist.h:420
void clear()
Definition: qlist.h:445
constexpr qreal x() const noexcept
Definition: qpoint.h:361
constexpr qreal y() const noexcept
Definition: qpoint.h:366
The QRectF class defines a finite rectangle in the plane using floating point precision.
Definition: qrect.h:511
constexpr qreal bottom() const noexcept
Definition: qrect.h:527
constexpr qreal height() const noexcept
Definition: qrect.h:741
constexpr qreal width() const noexcept
Definition: qrect.h:738
constexpr qreal left() const noexcept
Definition: qrect.h:524
constexpr QPointF center() const noexcept
Definition: qrect.h:708
constexpr qreal top() const noexcept
Definition: qrect.h:525
constexpr qreal right() const noexcept
Definition: qrect.h:526
constexpr void setRect(qreal x, qreal y, qreal w, qreal h) noexcept
Definition: qrect.h:790
The QString class provides a Unicode character string.
Definition: qstring.h:388
static QString fromLatin1(QByteArrayView ba)
Definition: qstring.cpp:5488
QString arg(qlonglong a, int fieldwidth=0, int base=10, QChar fillChar=QLatin1Char(' ')) const
Definition: qstring.cpp:8318
rect
[4]
QPainterPath node()
Definition: paths.cpp:574
QPainterPath rect2()
Definition: paths.cpp:391
QT_END_INCLUDE_NAMESPACE typedef double qreal
Definition: qglobal.h:341
GLenum type
Definition: qopengl.h:270
GLint GLenum GLsizei GLsizei GLsizei depth
GLuint index
[2]
QGraphicsItem * item
QList< QTreeWidgetItem * > items
QLayoutItem * child
[0]
bool contains(const AT &t) const noexcept
Definition: qlist.h:78
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent