KiCad PCB EDA Suite
Loading...
Searching...
No Matches
sch_rtree.h
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 * Copyright (C) 2020 CERN
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 3
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 */
20
21#ifndef EESCHEMA_SCH_RTREE_H_
22#define EESCHEMA_SCH_RTREE_H_
23
24#include <core/typeinfo.h>
25#include <sch_item.h>
26
28
34{
35private:
37
38public:
39 EE_RTREE() = default;
40 ~EE_RTREE() = default;
41
45 void insert( SCH_ITEM* aItem )
46 {
47 BOX2I bbox = aItem->GetBoundingBox();
48
49 // Inflate a bit for safety, selection shadows, etc.
50 bbox.Inflate( aItem->GetPenWidth() );
51
52 const int type = int( aItem->Type() );
53 const int mmin[3] = { type, bbox.GetX(), bbox.GetY() };
54 const int mmax[3] = { type, bbox.GetRight(), bbox.GetBottom() };
55
56 m_tree.Insert( mmin, mmax, aItem );
57 m_count++;
58 }
59
65 bool remove( SCH_ITEM* aItem )
66 {
67 BOX2I bbox = aItem->GetBoundingBox();
68
69 // Inflate a bit for safety, selection shadows, etc.
70 bbox.Inflate( aItem->GetPenWidth() );
71
72 const int type = int( aItem->Type() );
73 const int mmin[3] = { type, bbox.GetX(), bbox.GetY() };
74 const int mmax[3] = { type, bbox.GetRight(), bbox.GetBottom() };
75
76 // DYNAMIC_RTREE::Remove tries the provided bbox first, then falls back
77 // to full-tree search if the item has moved since insertion.
78 if( !m_tree.Remove( mmin, mmax, aItem ) )
79 return false;
80
81 m_count--;
82 return true;
83 }
84
88 void clear()
89 {
90 m_tree.RemoveAll();
91 m_count = 0;
92 }
93
104 bool contains( const SCH_ITEM* aItem, bool aRobust = false ) const
105 {
106 BOX2I bbox = aItem->GetBoundingBox();
107
108 // Inflate a bit for safety, selection shadows, etc.
109 bbox.Inflate( aItem->GetPenWidth() );
110
111 const int type = int( aItem->Type() );
112 const int mmin[3] = { type, bbox.GetX(), bbox.GetY() };
113 const int mmax[3] = { type, bbox.GetRight(), bbox.GetBottom() };
114 bool found = false;
115
116 auto search =
117 [&found, &aItem]( const SCH_ITEM* aSearchItem )
118 {
119 if( aSearchItem == aItem )
120 {
121 found = true;
122 return false;
123 }
124
125 return true;
126 };
127
128 m_tree.Search( mmin, mmax, search );
129
130 if( !found && aRobust )
131 {
132 // N.B. We must search the whole tree for the pointer to remove
133 // because the item may have been moved. We do not expand the item
134 // type search as this should not change.
135
136 const int mmin2[3] = { type, INT_MIN, INT_MIN };
137 const int mmax2[3] = { type, INT_MAX, INT_MAX };
138
139 m_tree.Search( mmin2, mmax2, search );
140 }
141
142 return found;
143 }
144
150 size_t size() const
151 {
152 return m_count;
153 }
154
155 bool empty() const
156 {
157 return m_count == 0;
158 }
159
170 struct EE_TYPE
171 {
172 using SearchIter = typename ee_rtree::SearchIterator;
173
174 EE_TYPE( const ee_rtree& aTree, KICAD_T aType )
175 {
176 KICAD_T type = BaseType( aType );
177
178 if( type == SCH_LOCATE_ANY_T )
179 {
180 m_min[0] = INT_MIN; m_min[1] = INT_MIN; m_min[2] = INT_MIN;
181 m_max[0] = INT_MAX; m_max[1] = INT_MAX; m_max[2] = INT_MAX;
182 }
183 else
184 {
185 m_min[0] = type; m_min[1] = INT_MIN; m_min[2] = INT_MIN;
186 m_max[0] = type; m_max[1] = INT_MAX; m_max[2] = INT_MAX;
187 }
188
189 m_range = aTree.Overlapping( m_min, m_max );
190 }
191
192 EE_TYPE( const ee_rtree& aTree, KICAD_T aType, const BOX2I& aRect )
193 {
194 KICAD_T type = BaseType( aType );
195
196 if( type == SCH_LOCATE_ANY_T )
197 {
198 m_min[0] = INT_MIN; m_min[1] = aRect.GetX(); m_min[2] = aRect.GetY();
199 m_max[0] = INT_MAX; m_max[1] = aRect.GetRight(); m_max[2] = aRect.GetBottom();
200 }
201 else
202 {
203 m_min[0] = type; m_min[1] = aRect.GetX(); m_min[2] = aRect.GetY();
204 m_max[0] = type; m_max[1] = aRect.GetRight(); m_max[2] = aRect.GetBottom();
205 }
206
207 m_range = aTree.Overlapping( m_min, m_max );
208 }
209
210 SearchIter begin() { return m_range.begin(); }
211 SearchIter end() { return m_range.end(); }
212
213 bool empty() { return m_range.empty(); }
214
215 private:
216 int m_min[3] = {};
217 int m_max[3] = {};
218 typename ee_rtree::SearchRange m_range{ nullptr, m_min, m_max };
219 };
220
221 EE_TYPE OfType( KICAD_T aType ) const
222 {
223 return EE_TYPE( m_tree, aType );
224 }
225
226 EE_TYPE Overlapping( const BOX2I& aRect ) const
227 {
228 return EE_TYPE( m_tree, SCH_LOCATE_ANY_T, aRect );
229 }
230
231 EE_TYPE Overlapping( const VECTOR2I& aPoint, int aAccuracy = 0 ) const
232 {
233 BOX2I rect( aPoint, VECTOR2I( 0, 0 ) );
234 rect.Inflate( aAccuracy );
235 return EE_TYPE( m_tree, SCH_LOCATE_ANY_T, rect );
236 }
237
238 EE_TYPE Overlapping( KICAD_T aType, const VECTOR2I& aPoint, int aAccuracy = 0 ) const
239 {
240 BOX2I rect( aPoint, VECTOR2I( 0, 0 ) );
241 rect.Inflate( aAccuracy );
242 return EE_TYPE( m_tree, aType, rect );
243 }
244
245 EE_TYPE Overlapping( KICAD_T aType, const BOX2I& aRect ) const
246 {
247 return EE_TYPE( m_tree, aType, aRect );
248 }
249
261 typename ee_rtree::Iterator begin() const
262 {
263 return m_tree.begin();
264 }
265
269 typename ee_rtree::Iterator end() const
270 {
271 return m_tree.end();
272 }
273
274
275private:
277 size_t m_count = 0;
278};
279
280
281#endif /* EESCHEMA_SCH_RTREE_H_ */
BOX2< VECTOR2I > BOX2I
Definition box2.h:918
constexpr BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
Definition box2.h:554
constexpr coord_type GetY() const
Definition box2.h:204
constexpr coord_type GetX() const
Definition box2.h:203
constexpr coord_type GetRight() const
Definition box2.h:213
constexpr coord_type GetBottom() const
Definition box2.h:218
virtual const BOX2I GetBoundingBox() const
Return the orthogonal bounding box of this object for display purposes.
Definition eda_item.cpp:135
KICAD_T Type() const
Returns the type of object.
Definition eda_item.h:108
~EE_RTREE()=default
bool empty() const
Definition sch_rtree.h:155
EE_TYPE Overlapping(KICAD_T aType, const BOX2I &aRect) const
Definition sch_rtree.h:245
size_t size() const
Return the number of items in the tree.
Definition sch_rtree.h:150
EE_TYPE Overlapping(const BOX2I &aRect) const
Definition sch_rtree.h:226
ee_rtree m_tree
Definition sch_rtree.h:276
bool remove(SCH_ITEM *aItem)
Remove an item from the tree.
Definition sch_rtree.h:65
ee_rtree::Iterator begin() const
Return a read/write iterator that points to the first.
Definition sch_rtree.h:261
void insert(SCH_ITEM *aItem)
Insert an item into the tree.
Definition sch_rtree.h:45
bool contains(const SCH_ITEM *aItem, bool aRobust=false) const
Determine if a given item exists in the tree.
Definition sch_rtree.h:104
EE_RTREE()=default
KIRTREE::DYNAMIC_RTREE< SCH_ITEM *, int, 3 > ee_rtree
Definition sch_rtree.h:36
EE_TYPE Overlapping(const VECTOR2I &aPoint, int aAccuracy=0) const
Definition sch_rtree.h:231
size_t m_count
Definition sch_rtree.h:277
ee_rtree::Iterator end() const
Return a read/write iterator that points to one past the last element in the EE_RTREE.
Definition sch_rtree.h:269
EE_TYPE Overlapping(KICAD_T aType, const VECTOR2I &aPoint, int aAccuracy=0) const
Definition sch_rtree.h:238
EE_TYPE OfType(KICAD_T aType) const
Definition sch_rtree.h:221
void clear()
Remove all items from the RTree.
Definition sch_rtree.h:88
Dynamic R*-tree with SoA node layout and stored insertion bounding boxes.
SearchRange Overlapping(const ELEMTYPE aMin[NUMDIMS], const ELEMTYPE aMax[NUMDIMS]) const
Return a lazy range of items overlapping the query rectangle.
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition sch_item.h:162
virtual int GetPenWidth() const
Definition sch_item.h:351
The EE_TYPE struct provides a type-specific auto-range iterator to the RTree.
Definition sch_rtree.h:171
ee_rtree::SearchRange m_range
Definition sch_rtree.h:218
EE_TYPE(const ee_rtree &aTree, KICAD_T aType, const BOX2I &aRect)
Definition sch_rtree.h:192
typename ee_rtree::SearchIterator SearchIter
Definition sch_rtree.h:172
SearchIter begin()
Definition sch_rtree.h:210
EE_TYPE(const ee_rtree &aTree, KICAD_T aType)
Definition sch_rtree.h:174
SearchIter end()
Definition sch_rtree.h:211
constexpr KICAD_T BaseType(const KICAD_T aType)
Return the underlying type of the given type.
Definition typeinfo.h:256
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition typeinfo.h:71
@ SCH_LOCATE_ANY_T
Definition typeinfo.h:196
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683