Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qgraphicsscene_bsp.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
5
6#include <QtCore/qstring.h>
7#include <private/qgraphicsitem_p.h>
8
10
11
16
20
22{
23 this->rect = rect;
24 leafCnt = 0;
25 nodes.resize((1 << (depth + 1)) - 1);
26 nodes.fill(Node());
27 leaves.resize(1ll << depth);
28 leaves.fill(QList<QGraphicsItem *>());
29
31}
32
34{
35 leafCnt = 0;
36 nodes.clear();
37 leaves.clear();
38}
39
41{
42 climbTree([item](QList<QGraphicsItem *> *items){
44 }, rect);
45}
46
48{
49 climbTree([item](QList<QGraphicsItem *> *items){
51 }, rect);
52}
53
54void QGraphicsSceneBspTree::removeItems(const QSet<QGraphicsItem *> &items)
55{
56 for (int i = 0; i < leaves.size(); ++i) {
57 QList<QGraphicsItem *> newItemList;
58 const QList<QGraphicsItem *> &oldItemList = leaves[i];
59 for (int j = 0; j < oldItemList.size(); ++j) {
60 QGraphicsItem *item = oldItemList.at(j);
61 if (!items.contains(item))
62 newItemList << item;
63 }
64 leaves[i] = newItemList;
65 }
66}
67
68QList<QGraphicsItem *> QGraphicsSceneBspTree::items(const QRectF &rect, bool onlyTopLevelItems) const
69{
70 QList<QGraphicsItem *> foundItems;
71 climbTree([&foundItems, onlyTopLevelItems](QList<QGraphicsItem *> *items) {
72 for (int i = 0; i < items->size(); ++i) {
74 if (onlyTopLevelItems && item->d_ptr->parent)
76 if (!item->d_func()->itemDiscovered && item->d_ptr->visible) {
77 item->d_func()->itemDiscovered = 1;
78 foundItems.prepend(item);
79 }
80 }
81 }, rect);
82 // Reset discovery bits.
83 for (const auto &foundItem : std::as_const(foundItems))
84 foundItem->d_ptr->itemDiscovered = 0;
85 return foundItems;
86}
87
89{
90 return leafCnt;
91}
92
94{
95 const Node *node = &nodes.at(index);
96
97 QString tmp;
98 if (node->type == Node::Leaf) {
99 QRectF rect = rectForIndex(index);
100 if (!leaves[node->leafIndex].isEmpty()) {
101 tmp += QString::fromLatin1("[%1, %2, %3, %4] contains %5 items\n")
102 .arg(rect.left()).arg(rect.top())
103 .arg(rect.width()).arg(rect.height())
104 .arg(leaves[node->leafIndex].size());
105 }
106 } else {
107 if (node->type == Node::Horizontal) {
108 tmp += debug(firstChildIndex(index));
109 tmp += debug(firstChildIndex(index) + 1);
110 } else {
111 tmp += debug(firstChildIndex(index));
112 tmp += debug(firstChildIndex(index) + 1);
113 }
114 }
115
116 return tmp;
117}
118
120{
121 Node *node = &nodes[index];
122 if (index == 0) {
123 node->type = Node::Horizontal;
124 node->offset = rect.center().y();
125 }
126
127 if (depth) {
129 QRectF rect1, rect2;
130 qreal offset1, offset2;
131
132 if (node->type == Node::Horizontal) {
134 rect1.setRect(rect.left(), rect.top(), rect.width(), rect.height() / 2);
135 rect2.setRect(rect1.left(), rect1.bottom(), rect1.width(), rect.height() - rect1.height());
136 offset1 = rect1.center().x();
137 offset2 = rect2.center().x();
138 } else {
140 rect1.setRect(rect.left(), rect.top(), rect.width() / 2, rect.height());
141 rect2.setRect(rect1.right(), rect1.top(), rect.width() - rect1.width(), rect1.height());
142 offset1 = rect1.center().y();
143 offset2 = rect2.center().y();
144 }
145
146 int childIndex = firstChildIndex(index);
147
148 Node *child = &nodes[childIndex];
149 child->offset = offset1;
150 child->type = type;
151
152 child = &nodes[childIndex + 1];
153 child->offset = offset2;
154 child->type = type;
155
156 initialize(rect1, depth - 1, childIndex);
157 initialize(rect2, depth - 1, childIndex + 1);
158 } else {
159 node->type = Node::Leaf;
160 node->leafIndex = leafCnt++;
161 }
162}
163
164template<typename Visitor>
165void QGraphicsSceneBspTree::climbTree(Visitor &&visitor, const QRectF &rect, int index) const
166{
167 if (nodes.isEmpty())
168 return;
169
170 const Node &node = nodes.at(index);
171 const int childIndex = firstChildIndex(index);
172
173 switch (node.type) {
174 case Node::Leaf: {
175 visitor(const_cast<QList<QGraphicsItem*>*>(&leaves[node.leafIndex]));
176 break;
177 }
178 case Node::Vertical:
179 if (rect.left() < node.offset) {
180 climbTree(visitor, rect, childIndex);
181 if (rect.right() >= node.offset)
182 climbTree(visitor, rect, childIndex + 1);
183 } else {
184 climbTree(visitor, rect, childIndex + 1);
185 }
186 break;
187 case Node::Horizontal:
188 if (rect.top() < node.offset) {
189 climbTree(visitor, rect, childIndex);
190 if (rect.bottom() >= node.offset)
191 climbTree(visitor, rect, childIndex + 1);
192 } else {
193 climbTree(visitor, rect, childIndex + 1);
194 }
195 }
196}
197
198QRectF QGraphicsSceneBspTree::rectForIndex(int index) const
199{
200 if (index <= 0)
201 return rect;
202
203 int parentIdx = parentIndex(index);
204 QRectF rect = rectForIndex(parentIdx);
205 const Node *parent = &nodes.at(parentIdx);
206
207 if (parent->type == Node::Vertical) {
208 if (index & 1)
209 rect.setRight(parent->offset);
210 else
211 rect.setLeft(parent->offset);
212 } else {
213 if (index & 1)
214 rect.setBottom(parent->offset);
215 else
216 rect.setTop(parent->offset);
217 }
218
219 return rect;
220}
221
Definition lalr.h:136
QGraphicsItem * parent
The QGraphicsItem class is the base class for all graphical items in a QGraphicsScene.
QScopedPointer< QGraphicsItemPrivate > d_ptr
QGraphicsItem * topLevelItem() const
Returns this item's top-level item.
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
qsizetype size() const noexcept
Definition qlist.h:397
QList< T > & fill(parameter_type t, qsizetype size=-1)
Definition qlist.h:903
bool isEmpty() const noexcept
Definition qlist.h:401
const_reference at(qsizetype i) const noexcept
Definition qlist.h:446
qsizetype removeAll(const AT &t)
Definition qlist.h:592
void prepend(rvalue_ref t)
Definition qlist.h:473
void resize(qsizetype size)
Definition qlist.h:403
void clear()
Definition qlist.h:434
\inmodule QtCore\reentrant
Definition qrect.h:484
constexpr void setRect(qreal x, qreal y, qreal w, qreal h) noexcept
Sets the coordinates of the rectangle's top-left corner to (x, y), and its size to the given width an...
Definition qrect.h:781
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5871
rect
[4]
Combined button and popup list for selecting options.
static bool initialize()
Definition qctf.cpp:94
GLint GLenum GLsizei GLsizei GLsizei depth
GLuint index
[2]
GLenum type
double qreal
Definition qtypes.h:187
QGraphicsItem * item
QList< QTreeWidgetItem * > items
QLayoutItem * child
[0]
bool contains(const AT &t) const noexcept
Definition qlist.h:45