void QGraphicsSceneBspTree::climbTree(QGraphicsSceneBspTreeVisitor *visitor, const QPointF &pos, int index) { if (nodes.isEmpty()) return; const Node &node = nodes.at(index); int childIndex = firstChildIndex(index); switch (node.type) { case Node::Leaf: { visitor->visit(&leaves[node.leafIndex]); break; } case Node::Vertical: if (pos.x() < node.offset) { climbTree(visitor, pos, childIndex); } else { climbTree(visitor, pos, childIndex + 1); } break; case Node::Horizontal: if (pos.y() < node.offset) { climbTree(visitor, pos, childIndex); } else { climbTree(visitor, pos, childIndex + 1); } break; } }
void QBspTree::climbTree(const QRect &rect, callback *function, QBspTreeData data) { if (nodes.isEmpty()) return; ++visited; climbTree(rect, function, data, 0); }
QList<QGraphicsItem *> QGraphicsSceneBspTree::items(const QPointF &pos) { QList<QGraphicsItem *> tmp; findVisitor->foundItems = &tmp; climbTree(findVisitor, pos); return tmp; }
QList<QGraphicsItem *> QGraphicsSceneBspTree::items(const QRectF &rect) { QList<QGraphicsItem *> tmp; findVisitor->foundItems = &tmp; climbTree(findVisitor, rect); return tmp; }
QList<QGraphicsItem *> QGraphicsSceneBspTree::items(const QRectF &rect, bool onlyTopLevelItems) const { QList<QGraphicsItem *> tmp; findVisitor->foundItems = &tmp; findVisitor->onlyTopLevelItems = onlyTopLevelItems; climbTree(findVisitor, rect); // Reset discovery bits. for (int i = 0; i < tmp.size(); ++i) tmp.at(i)->d_ptr->itemDiscovered = 0; return tmp; }
void QGraphicsSceneBspTree::climbTree(QGraphicsSceneBspTreeVisitor *visitor, const QRectF &rect, int index) const { if (nodes.isEmpty()) return; const Node &node = nodes.at(index); const int childIndex = firstChildIndex(index); switch (node.type) { case Node::Leaf: { visitor->visit(const_cast<QList<QGraphicsItem*>*>(&leaves[node.leafIndex])); break; } case Node::Vertical: if (rect.left() < node.offset) { climbTree(visitor, rect, childIndex); if (rect.right() >= node.offset) climbTree(visitor, rect, childIndex + 1); } else { climbTree(visitor, rect, childIndex + 1); } break; case Node::Horizontal: if (rect.top() < node.offset) { climbTree(visitor, rect, childIndex); if (rect.bottom() >= node.offset) climbTree(visitor, rect, childIndex + 1); } else { climbTree(visitor, rect, childIndex + 1); } } }
void QBspTree::climbTree(const QRect &area, callback *function, QBspTreeData data, int index) { if (index >= nodes.count()) { // the index points to a leaf Q_ASSERT(!nodes.isEmpty()); function(leaf(index - nodes.count()), area, visited, data); return; } Node::Type t = (Node::Type) nodes.at(index).type; int pos = nodes.at(index).pos; int idx = firstChildIndex(index); if (t == Node::VerticalPlane) { if (area.left() < pos) climbTree(area, function, data, idx); // back if (area.right() >= pos) climbTree(area, function, data, idx + 1); // front } else { if (area.top() < pos) climbTree(area, function, data, idx); // back if (area.bottom() >= pos) climbTree(area, function, data, idx + 1); // front } }
void QGraphicsSceneBspTree::removeItem(QGraphicsItem *item, const QRectF &rect) { removeVisitor->item = item; climbTree(removeVisitor, rect); }
void QGraphicsSceneBspTree::insertItem(QGraphicsItem *item, const QRectF &rect) { insertVisitor->item = item; climbTree(insertVisitor, rect); }