7#include <QtCore/qstring.h>
8#include <private/qgraphicsitem_p.h>
13QGraphicsSceneBspTree::QGraphicsSceneBspTree()
26 nodes.resize((1 << (depth + 1)) - 1);
28 leaves.resize(1ll << depth);
29 leaves.fill(QList<QGraphicsItem *>());
31 initialize(rect, depth, 0);
43 climbTree([item](QList<QGraphicsItem *> *items){
50 climbTree([item](QList<QGraphicsItem *> *items){
51 items->removeAll(item);
57 for (
int i = 0; i < leaves.size(); ++i) {
58 QList<QGraphicsItem *> newItemList;
59 const QList<QGraphicsItem *> &oldItemList = leaves[i];
60 for (
int j = 0; j < oldItemList.size(); ++j) {
61 QGraphicsItem *item = oldItemList.at(j);
62 if (!items.contains(item))
65 leaves[i] = newItemList;
71 QList<QGraphicsItem *> foundItems;
72 climbTree([&foundItems, onlyTopLevelItems](QList<QGraphicsItem *> *items) {
73 for (
int i = 0; i < items->size(); ++i) {
74 QGraphicsItem *item = items->at(i);
75 if (onlyTopLevelItems && item->d_ptr->parent)
76 item = item->topLevelItem();
77 if (!item->d_func()->itemDiscovered && item->d_ptr->visible) {
78 item->d_func()->itemDiscovered = 1;
79 foundItems.prepend(item);
84 for (
const auto &foundItem : std::as_const(foundItems))
85 foundItem->d_ptr->itemDiscovered = 0;
96 const Node *node = &nodes.at(index);
100 QRectF rect = rectForIndex(index);
101 if (!leaves[node->leafIndex].isEmpty()) {
102 tmp += QString::fromLatin1(
"[%1, %2, %3, %4] contains %5 items\n")
103 .arg(rect.left()).arg(rect.top())
104 .arg(rect.width()).arg(rect.height())
105 .arg(leaves[node->leafIndex].size());
109 tmp += debug(firstChildIndex(index));
110 tmp += debug(firstChildIndex(index) + 1);
112 tmp += debug(firstChildIndex(index));
113 tmp += debug(firstChildIndex(index) + 1);
122 Node *node = &nodes[index];
125 node->offset = rect.center().y();
131 qreal offset1, offset2;
135 rect1.setRect(rect.left(), rect.top(), rect.width(), rect.height() / 2);
136 rect2.setRect(rect1.left(), rect1.bottom(), rect1.width(), rect.height() - rect1.height());
137 offset1 = rect1.center().x();
138 offset2 = rect2.center().x();
141 rect1.setRect(rect.left(), rect.top(), rect.width() / 2, rect.height());
142 rect2.setRect(rect1.right(), rect1.top(), rect.width() - rect1.width(), rect1.height());
143 offset1 = rect1.center().y();
144 offset2 = rect2.center().y();
149 Node *child = &nodes[childIndex];
150 child->offset = offset1;
153 child = &nodes[childIndex + 1];
154 child->offset = offset2;
157 initialize(rect1, depth - 1, childIndex);
158 initialize(rect2, depth - 1, childIndex + 1);
161 node->leafIndex = leafCnt++;
165template<
typename Visitor>
171 const Node &node = nodes.at(index);
176 visitor(
const_cast<QList<QGraphicsItem*>*>(&leaves[node.leafIndex]));
180 if (rect.left() < node.offset) {
181 climbTree(visitor, rect, childIndex);
182 if (rect.right() >= node.offset)
183 climbTree(visitor, rect, childIndex + 1);
185 climbTree(visitor, rect, childIndex + 1);
189 if (rect.top() < node.offset) {
190 climbTree(visitor, rect, childIndex);
191 if (rect.bottom() >= node.offset)
192 climbTree(visitor, rect, childIndex + 1);
194 climbTree(visitor, rect, childIndex + 1);
205 QRectF rect = rectForIndex(parentIdx);
206 const Node *parent = &nodes.at(parentIdx);
210 rect.setRight(parent->offset);
212 rect.setLeft(parent->offset);
215 rect.setBottom(parent->offset);
217 rect.setTop(parent->offset);
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