Krita Source Code Documentation
Loading...
Searching...
No Matches
KoRTree< T > Class Template Reference

The KoRTree class is a template class that provides a R-tree. More...

#include <KoRTree.h>

Classes

class  LeafNode
 
class  Node
 
class  NonLeafNode
 

Public Member Functions

virtual void clear ()
 
QList< T > contained (const QRectF &point) const
 Find all data item which contain the point The items are sorted by insertion time in ascending order.
 
QList< T > contains (const QPointF &point) const
 Find all data item which contain the point The items are sorted by insertion time in ascending order.
 
bool contains (const T &data)
 Show if a shape is a part of the tree.
 
virtual void insert (const QRectF &bb, const T &data)
 Insert data item into the tree.
 
virtual QList< T > intersects (const QRectF &rect) const
 Find all data items which intersects rect The items are sorted by insertion time in ascending order.
 
QList< QRectF > keys () const
 Find all data rectangles The order is NOT guaranteed to be the same as that used by values().
 
 KoRTree (int capacity, int minimum)
 Constructor.
 
void remove (const T &data)
 Remove a data item from the tree.
 
QList< T > values () const
 Find all data items The order is NOT guaranteed to be the same as that used by keys().
 
virtual ~KoRTree ()
 Destructor.
 

Protected Member Functions

virtual void adjustTree (Node *node1, Node *node2)
 
virtual void condenseTree (Node *node, QVector< Node * > &reinsert)
 
virtual LeafNodecreateLeafNode (int capacity, int level, Node *parent)
 
virtual NonLeafNodecreateNonLeafNode (int capacity, int level, Node *parent)
 
void insert (Node *node)
 
void insertHelper (const QRectF &bb, const T &data, int id)
 
QPair< int, int > pickNext (Node *node, QVector< bool > &marker, Node *group1, Node *group2)
 
QPair< int, int > pickSeeds (Node *node)
 
QPair< Node *, Node * > splitNode (Node *node)
 

Protected Attributes

int m_capacity
 
QMap< T, LeafNode * > m_leafMap
 
int m_minimum
 
Nodem_root
 

Detailed Description

template<typename T>
class KoRTree< T >

The KoRTree class is a template class that provides a R-tree.

This class implements a R-tree as described in "R-TREES. A DYNAMIC INDEX STRUCTURE FOR SPATIAL SEARCHING" by Antonin Guttman

It only supports 2 dimensional bounding boxes which are represented by a QRectF. For node splitting the Quadratic-Cost Algorithm is used as described by Guttman.

Definition at line 38 of file KoRTree.h.

Constructor & Destructor Documentation

◆ KoRTree()

template<typename T >
KoRTree< T >::KoRTree ( int capacity,
int minimum )

Constructor.

Parameters
capacitythe capacity a node can take
minimumthe minimum filling of a node max 0.5 * capacity

Definition at line 342 of file KoRTree.h.

343 : m_capacity(capacity)
344 , m_minimum(minimum)
345 , m_root(createLeafNode(m_capacity + 1, 0, 0))
346{
347 if (minimum > capacity / 2)
348 qFatal("KoRTree::KoRTree minimum can be maximal capacity/2");
349 //debugFlake << "root node " << m_root->nodeId();
350}
virtual LeafNode * createLeafNode(int capacity, int level, Node *parent)
Definition KoRTree.h:317
int m_minimum
Definition KoRTree.h:336
Node * m_root
Definition KoRTree.h:337
int m_capacity
Definition KoRTree.h:335

◆ ~KoRTree()

template<typename T >
KoRTree< T >::~KoRTree ( )
virtual

Destructor.

Definition at line 353 of file KoRTree.h.

354{
355 delete m_root;
356}

Member Function Documentation

◆ adjustTree()

template<typename T >
void KoRTree< T >::adjustTree ( Node * node1,
Node * node2 )
protectedvirtual

Definition at line 673 of file KoRTree.h.

674{
675 //debugFlake << "KoRTree::adjustTree";
676 if (node1->isRoot()) {
677 //debugFlake << " root";
678 if (node2) {
679 NonLeafNode * newRoot = createNonLeafNode(m_capacity + 1, node1->level() + 1, 0);
680 newRoot->insert(node1->boundingBox(), node1);
681 newRoot->insert(node2->boundingBox(), node2);
682 m_root = newRoot;
683 //debugFlake << "new root" << m_root->nodeId();
684 }
685 } else {
686 NonLeafNode * parent = dynamic_cast<NonLeafNode *>(node1->parent());
687 if (!parent) {
688 qFatal("KoRTree::adjustTree: no parent node found!");
689 return;
690 }
691 //QRectF pbbold( parent->boundingBox() );
692 parent->setChildBoundingBox(node1->place(), node1->boundingBox());
693 parent->updateBoundingBox();
694 //debugFlake << " bb1 =" << node1->boundingBox() << node1->place() << pbbold << "->" << parent->boundingBox() << parent->nodeId();
695
696 if (!node2) {
697 //debugFlake << " update";
698 adjustTree(parent, 0);
699 } else {
700 if (parent->childCount() < m_capacity) {
701 //debugFlake << " no split needed";
702 parent->insert(node2->boundingBox(), node2);
703 adjustTree(parent, 0);
704 } else {
705 //debugFlake << " split again";
706 parent->insert(node2->boundingBox(), node2);
707 QPair<Node *, Node *> newNodes = splitNode(parent);
708 adjustTree(newNodes.first, newNodes.second);
709 }
710 }
711 }
712}
virtual NonLeafNode * createNonLeafNode(int capacity, int level, Node *parent)
Definition KoRTree.h:320
virtual void adjustTree(Node *node1, Node *node2)
Definition KoRTree.h:673
QPair< Node *, Node * > splitNode(Node *node)
Definition KoRTree.h:544
ChildIterator< value_type, is_const > parent(const ChildIterator< value_type, is_const > &it)
Definition KisForest.h:327

References KoRTree< T >::Node::boundingBox(), KoRTree< T >::NonLeafNode::insert(), KoRTree< T >::Node::isRoot(), KoRTree< T >::Node::level(), KoRTree< T >::Node::parent(), and KoRTree< T >::Node::place().

◆ clear()

template<typename T >
virtual void KoRTree< T >::clear ( )
inlinevirtual

Definition at line 127 of file KoRTree.h.

127 {
128 delete m_root;
129 m_root = createLeafNode(m_capacity + 1, 0, 0);
130 m_leafMap.clear();
131 }
QMap< T, LeafNode * > m_leafMap
Definition KoRTree.h:338

References KoRTree< T >::createLeafNode(), KoRTree< T >::m_capacity, KoRTree< T >::m_leafMap, and KoRTree< T >::m_root.

◆ condenseTree()

template<typename T >
void KoRTree< T >::condenseTree ( Node * node,
QVector< Node * > & reinsert )
protectedvirtual

WARNING: here we leave the tree in an inconsistent state! 'reinsert' nodes may still be kept in m_leafMap structure, but we will not remove them for the efficiency reasons. They are guaranteed to be readded in remove().

Definition at line 715 of file KoRTree.h.

716{
717 //debugFlake << "KoRTree::condenseTree begin reinsert.size()" << reinsert.size();
718 if (!node->isRoot()) {
719 Node * parent = node->parent();
720 //debugFlake << " !node->isRoot us" << node->childCount();
721
722 if (node->childCount() < m_minimum) {
723 //debugFlake << " remove node";
724 parent->remove(node->place());
725 reinsert.push_back(node);
726
734 } else {
735 //debugFlake << " update BB parent is root" << parent->isRoot();
736 parent->setChildBoundingBox(node->place(), node->boundingBox());
737 parent->updateBoundingBox();
738 }
739 condenseTree(parent, reinsert);
740 } else {
741 //debugFlake << " node->isRoot us" << node->childCount();
742 if (node->childCount() == 1 && !node->isLeaf()) {
743 //debugFlake << " usedSpace = 1";
744 NonLeafNode * n = dynamic_cast<NonLeafNode *>(node);
745 if (n) {
746 Node * kid = n->getNode(0);
747 // clear is needed as the data items are not removed
748 m_root->clear();
749 delete m_root;
750 m_root = kid;
751 m_root->setParent(0);
752 //debugFlake << " new root" << m_root;
753 } else {
754 qFatal("KoRTree::condenseTree cast to NonLeafNode failed");
755 }
756 }
757 }
758 //debugFlake << "KoRTree::condenseTree end reinsert.size()" << reinsert.size();
759}
virtual void clear()
Definition KoRTree.h:808
virtual void setParent(Node *parent)
Definition KoRTree.h:177
virtual void condenseTree(Node *node, QVector< Node * > &reinsert)
Definition KoRTree.h:715
Definition Node.h:24

References KoRTree< T >::Node::boundingBox(), KoRTree< T >::Node::childCount(), KoRTree< T >::Node::clear(), KoRTree< T >::NonLeafNode::getNode(), KoRTree< T >::Node::isLeaf(), KoRTree< T >::Node::isRoot(), KoRTree< T >::Node::parent(), KoRTree< T >::Node::place(), and KoRTree< T >::Node::setParent().

◆ contained()

template<typename T >
QList< T > KoRTree< T >::contained ( const QRectF & point) const

Find all data item which contain the point The items are sorted by insertion time in ascending order.

Parameters
pointwhich should be contained in the objects
Returns
objects which contain the point

Definition at line 502 of file KoRTree.h.

503{
504 QMap<int, T> found;
505 m_root->contained(rect, found);
506 return found.values();
507}
virtual void contained(const QRectF &point, QMap< int, T > &result) const =0

◆ contains() [1/2]

template<typename T >
QList< T > KoRTree< T >::contains ( const QPointF & point) const

Find all data item which contain the point The items are sorted by insertion time in ascending order.

Parameters
pointwhich should be contained in the objects
Returns
objects which contain the point

Definition at line 494 of file KoRTree.h.

495{
496 QMap<int, T> found;
497 m_root->contains(point, found);
498 return found.values();
499}
virtual void contains(const QPointF &point, QMap< int, T > &result) const =0

◆ contains() [2/2]

template<typename T >
bool KoRTree< T >::contains ( const T & data)

Show if a shape is a part of the tree.

Parameters
data

Definition at line 433 of file KoRTree.h.

434{
435 return m_leafMap[data];
436}

◆ createLeafNode()

template<typename T >
virtual LeafNode * KoRTree< T >::createLeafNode ( int capacity,
int level,
Node * parent )
inlineprotectedvirtual

Definition at line 317 of file KoRTree.h.

317 {
318 return new LeafNode(capacity, level, parent);
319 }

◆ createNonLeafNode()

template<typename T >
virtual NonLeafNode * KoRTree< T >::createNonLeafNode ( int capacity,
int level,
Node * parent )
inlineprotectedvirtual

Definition at line 320 of file KoRTree.h.

320 {
321 return new NonLeafNode(capacity, level, parent);
322 }

◆ insert() [1/2]

template<typename T >
void KoRTree< T >::insert ( const QRectF & bb,
const T & data )
virtual

Insert data item into the tree.

This will insert a data item into the tree. If necessary the tree will adjust itself.

Parameters
data
bb

Definition at line 359 of file KoRTree.h.

360{
361 // check if the shape is not already registered
363
365}
static int dataIdCounter
Definition KoRTree.h:280
void insertHelper(const QRectF &bb, const T &data, int id)
Definition KoRTree.h:368
#define KIS_SAFE_ASSERT_RECOVER_NOOP(cond)
Definition kis_assert.h:130

References KIS_SAFE_ASSERT_RECOVER_NOOP.

◆ insert() [2/2]

template<typename T >
void KoRTree< T >::insert ( Node * node)
protected

Definition at line 414 of file KoRTree.h.

415{
416 if (node->level() == m_root->level()) {
417 adjustTree(m_root, node);
418 } else {
419 QRectF bb(node->boundingBox());
420 NonLeafNode * newParent = m_root->chooseNode(bb, node->level() + 1);
421
422 newParent->insert(bb, node);
423
424 QPair<Node *, Node *> newNodes(node, 0);
425 if (newParent->childCount() > m_capacity) {
426 newNodes = splitNode(newParent);
427 }
428 adjustTree(newNodes.first, newNodes.second);
429 }
430}
virtual NonLeafNode * chooseNode(const QRectF &bb, int level)=0
virtual int level() const
Definition KoRTree.h:212
virtual void insert(const QRectF &bb, Node *data)
Definition KoRTree.h:850

References KoRTree< T >::Node::boundingBox(), KoRTree< T >::Node::childCount(), KoRTree< T >::NonLeafNode::chooseNode(), KoRTree< T >::NonLeafNode::insert(), and KoRTree< T >::Node::level().

◆ insertHelper()

template<typename T >
void KoRTree< T >::insertHelper ( const QRectF & bb,
const T & data,
int id )
protected

Definition at line 368 of file KoRTree.h.

369{
370 QRectF nbb(bb.normalized());
371 // This has to be done as it is not possible to use QRectF::united() with a isNull()
372 if (nbb.isNull()) {
373 qWarning() << "KoRTree::insert boundingBox isNull setting size to" << nbb.size();
374
375 nbb.setWidth(0.0001);
376 nbb.setHeight(0.0001);
377 }
378 else {
379 // This has to be done as QRectF::intersects() return false if the rect does not have any area overlapping.
380 // If there is no width or height there is no area and therefore no overlapping.
381 if ( nbb.width() == 0 ) {
382 nbb.setWidth(0.0001);
383 }
384 if ( nbb.height() == 0 ) {
385 nbb.setHeight(0.0001);
386 }
387 }
388
389 LeafNode * leaf = m_root->chooseLeaf(nbb);
390 //debugFlake << " leaf" << leaf->nodeId() << nbb;
391
392 if (leaf->childCount() < m_capacity) {
393 leaf->insert(nbb, data, id);
394 m_leafMap[data] = leaf;
395 adjustTree(leaf, 0);
396 } else {
397 leaf->insert(nbb, data, id);
398 m_leafMap[data] = leaf;
399 QPair<Node *, Node *> newNodes = splitNode(leaf);
400 LeafNode * l = dynamic_cast<LeafNode *>(newNodes.first);
401 if (l)
402 for (int i = 0; i < l->childCount(); ++i)
403 m_leafMap[l->getData(i)] = l;
404 l = dynamic_cast<LeafNode *>(newNodes.second);
405 if (l)
406 for (int i = 0; i < l->childCount(); ++i)
407 m_leafMap[l->getData(i)] = l;
408
409 adjustTree(newNodes.first, newNodes.second);
410 }
411}
virtual void insert(const QRectF &bb, const T &data, int id)
Definition KoRTree.h:1016
virtual LeafNode * chooseLeaf(const QRectF &bb)=0

References KoRTree< T >::Node::childCount(), KoRTree< T >::LeafNode::chooseLeaf(), KoRTree< T >::LeafNode::getData(), and KoRTree< T >::LeafNode::insert().

◆ intersects()

template<typename T >
QList< T > KoRTree< T >::intersects ( const QRectF & rect) const
virtual

Find all data items which intersects rect The items are sorted by insertion time in ascending order.

Parameters
rectwhere the objects have to be in
Returns
objects intersecting the rect

Definition at line 486 of file KoRTree.h.

487{
488 QMap<int, T> found;
489 m_root->intersects(rect, found);
490 return found.values();
491}
virtual void intersects(const QRectF &rect, QMap< int, T > &result) const =0

◆ keys()

template<typename T >
QList< QRectF > KoRTree< T >::keys ( ) const

Find all data rectangles The order is NOT guaranteed to be the same as that used by values().

Returns
a list containing all the data rectangles used in the tree

Definition at line 511 of file KoRTree.h.

512{
513 QList<QRectF> found;
514 m_root->keys(found);
515 return found;
516}
virtual void keys(QList< QRectF > &result) const =0

◆ pickNext()

template<typename T >
QPair< int, int > KoRTree< T >::pickNext ( Node * node,
QVector< bool > & marker,
Node * group1,
Node * group2 )
protected

Definition at line 641 of file KoRTree.h.

642{
643 //debugFlake << "KoRTree::pickNext" << marker;
644 qreal max = -1.0;
645 int select = 0;
646 int group = 0;
647 for (int i = 0; i < m_capacity + 1; ++i) {
648 if (marker[i] == false) {
649 QRectF bb1 = group1->boundingBox().united(node->childBoundingBox(i));
650 QRectF bb2 = group2->boundingBox().united(node->childBoundingBox(i));
651 qreal d1 = bb1.width() * bb1.height() - group1->boundingBox().width() * group1->boundingBox().height();
652 qreal d2 = bb2.width() * bb2.height() - group2->boundingBox().width() * group2->boundingBox().height();
653 qreal diff = qAbs(d1 - d2);
654 //debugFlake << " diff" << diff << i << d1 << d2;
655 if (diff > max) {
656 max = diff;
657 select = i;
658 //debugFlake << " i =" << i;
659 if (qAbs(d1) > qAbs(d2)) {
660 group = 1;
661 } else {
662 group = 0;
663 }
664 //debugFlake << " group =" << group;
665 }
666 }
667 }
668 marker[select] = true;
669 return qMakePair(group, select);
670}
constexpr std::enable_if< sizeof...(values)==0, size_t >::type max()

References KoRTree< T >::Node::boundingBox(), and KoRTree< T >::Node::childBoundingBox().

◆ pickSeeds()

template<typename T >
QPair< int, int > KoRTree< T >::pickSeeds ( Node * node)
protected

Definition at line 616 of file KoRTree.h.

617{
618 int s1 = 0;
619 int s2 = 1;
620 qreal max = 0;
621 for (int i = 0; i < m_capacity + 1; ++i) {
622 for (int j = i+1; j < m_capacity + 1; ++j) {
623 if (i != j) {
624 QRectF bb1(node->childBoundingBox(i));
625 QRectF bb2(node->childBoundingBox(j));
626 QRectF comp(node->childBoundingBox(i).united(node->childBoundingBox(j)));
627 qreal area = comp.width() * comp.height() - bb1.width() * bb1.height() - bb2.width() * bb2.height();
628 //debugFlake << " ps" << i << j << area;
629 if (area > max) {
630 max = area;
631 s1 = i;
632 s2 = j;
633 }
634 }
635 }
636 }
637 return qMakePair(s1, s2);
638}
QPointF s1
QPointF s2

References KoRTree< T >::Node::childBoundingBox(), s1, and s2.

◆ remove()

template<typename T >
void KoRTree< T >::remove ( const T & data)

Remove a data item from the tree.

This removed a data item from the tree. If necessary the tree will adjust itself.

Parameters
data

WARNING: after calling condenseTree() the temporary enters an inconsistent state! m_leafMap still points to the nodes now stored in 'reinsert' list, although they are not a part of the hierarchy. This state does not cause any use visible changes, but should be considered while implementing sanity checks.

Definition at line 440 of file KoRTree.h.

441{
442 //debugFlake << "KoRTree remove";
443 LeafNode * leaf = m_leafMap[data];
444
445 // Trying to remove inexistent leaf. Most probably, this leaf hasn't been added
446 // to the shape manager correctly
448
449 m_leafMap.remove(data);
450 leaf->remove(data);
451
459 QVector<Node *> reinsert;
460 condenseTree(leaf, reinsert);
461
462 for (int i = 0; i < reinsert.size(); ++i) {
463 if (reinsert[i]->isLeaf()) {
464 LeafNode * leaf = dynamic_cast<LeafNode *>(reinsert[i]);
465 KIS_SAFE_ASSERT_RECOVER(leaf) { reinsert[i]->clear(); delete reinsert[i]; continue; } // mostly for the sake of Coverity
466 for (int j = 0; j < leaf->childCount(); ++j) {
467 insertHelper(leaf->childBoundingBox(j), leaf->getData(j), leaf->getDataId(j));
468 }
469 // clear is needed as the data items are not removed when insert into a new node
470 leaf->clear();
471 delete leaf;
472 } else {
473 NonLeafNode * node = dynamic_cast<NonLeafNode *>(reinsert[i]);
474 KIS_SAFE_ASSERT_RECOVER(node) { reinsert[i]->clear(); delete reinsert[i]; continue; } // mostly for the sake of Coverity
475 for (int j = 0; j < node->childCount(); ++j) {
476 insert(node->getNode(j));
477 }
478 // clear is needed as the data items are not removed when insert into a new node
479 node->clear();
480 delete node;
481 }
482 }
483}
virtual void insert(const QRectF &bb, const T &data)
Insert data item into the tree.
Definition KoRTree.h:359
#define KIS_SAFE_ASSERT_RECOVER(cond)
Definition kis_assert.h:126
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
Definition kis_assert.h:128

References KoRTree< T >::Node::childBoundingBox(), KoRTree< T >::Node::childCount(), KoRTree< T >::Node::clear(), KoRTree< T >::LeafNode::getData(), KoRTree< T >::LeafNode::getDataId(), KoRTree< T >::NonLeafNode::getNode(), KIS_SAFE_ASSERT_RECOVER, KIS_SAFE_ASSERT_RECOVER_RETURN, and KoRTree< T >::LeafNode::remove().

◆ splitNode()

template<typename T >
QPair< typename KoRTree< T >::Node *, typename KoRTree< T >::Node * > KoRTree< T >::splitNode ( Node * node)
protected

Definition at line 544 of file KoRTree.h.

545{
546 //debugFlake << "KoRTree::splitNode" << node;
547 Node * n1;
548 Node * n2;
549 if (node->isLeaf()) {
550 n1 = createLeafNode(m_capacity + 1, node->level(), node->parent());
551 n2 = createLeafNode(m_capacity + 1, node->level(), node->parent());
552 } else {
553 n1 = createNonLeafNode(m_capacity + 1, node->level(), node->parent());
554 n2 = createNonLeafNode(m_capacity + 1, node->level(), node->parent());
555 }
556 //debugFlake << " n1" << n1 << n1->nodeId();
557 //debugFlake << " n2" << n2 << n2->nodeId();
558
559 QVector<bool> marker(m_capacity + 1);
560
561 QPair<int, int> seeds(pickSeeds(node));
562
563 n1->move(node, seeds.first);
564 n2->move(node, seeds.second);
565
566 marker[seeds.first] = true;
567 marker[seeds.second] = true;
568
569 // There is one more in a node to split than the capacity and as we
570 // already put the seeds in the new nodes subtract them.
571 int remaining = m_capacity + 1 - 2;
572
573 while (remaining > 0) {
574 if (m_minimum - n1->childCount() == remaining) {
575 for (int i = 0; i < m_capacity + 1; ++i) {
576 if (!marker[i]) {
577 n1->move(node, i);
578 --remaining;
579 }
580 }
581 } else if (m_minimum - n2->childCount() == remaining) {
582 for (int i = 0; i < m_capacity + 1; ++i) {
583 if (!marker[i]) {
584 n2->move(node, i);
585 --remaining;
586 }
587 }
588 } else {
589 QPair<int, int> next(pickNext(node, marker, n1, n2));
590
591 if (next.first == 0) {
592 n1->move(node, next.second);
593 } else {
594 n2->move(node, next.second);
595 }
596 --remaining;
597 }
598 }
599 Q_ASSERT(n1->childCount() + n2->childCount() == node->childCount());
600
601 // move the data back to the old node
602 // this has to be done as the current node is already in the tree.
603 node->clear();
604 for (int i = 0; i < n1->childCount(); ++i) {
605 node->move(n1, i);
606 }
607
608 //debugFlake << " delete n1" << n1 << n1->nodeId();
609 // clear is needed as the data items are not removed
610 n1->clear();
611 delete n1;
612 return qMakePair(node, n2);
613}
QPair< int, int > pickSeeds(Node *node)
Definition KoRTree.h:616
QPair< int, int > pickNext(Node *node, QVector< bool > &marker, Node *group1, Node *group2)
Definition KoRTree.h:641
void move(int x, int y)
Definition Node.cpp:621
QAction * next(const QObject *recvr, const char *slot, QObject *parent)

References KoRTree< T >::Node::childCount(), KoRTree< T >::Node::clear(), KoRTree< T >::Node::isLeaf(), KoRTree< T >::Node::level(), KoRTree< T >::Node::move(), and KoRTree< T >::Node::parent().

◆ values()

template<typename T >
QList< T > KoRTree< T >::values ( ) const

Find all data items The order is NOT guaranteed to be the same as that used by keys().

Returns
a list containing all the data used in the tree

Definition at line 519 of file KoRTree.h.

520{
521 QMap<int, T> found;
522 m_root->values(found);
523 return found.values();
524}
virtual void values(QMap< int, T > &result) const =0

Member Data Documentation

◆ m_capacity

template<typename T >
int KoRTree< T >::m_capacity
protected

Definition at line 335 of file KoRTree.h.

◆ m_leafMap

template<typename T >
QMap<T, LeafNode *> KoRTree< T >::m_leafMap
protected

Definition at line 338 of file KoRTree.h.

◆ m_minimum

template<typename T >
int KoRTree< T >::m_minimum
protected

Definition at line 336 of file KoRTree.h.

◆ m_root

template<typename T >
Node* KoRTree< T >::m_root
protected

Definition at line 337 of file KoRTree.h.


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