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, you may find one here:
19 * http://www.gnu.org/licenses/old-licenses/gpl-3.0.html
20 * or you may search the http://www.gnu.org website for the version 3 license,
21 * or you may write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23 */
24
25#ifndef EESCHEMA_SCH_RTREE_H_
26#define EESCHEMA_SCH_RTREE_H_
27
28#include <core/typeinfo.h>
29#include <sch_item.h>
30
32
38{
39private:
41
42public:
43 EE_RTREE() = default;
44 ~EE_RTREE() = default;
45
49 void insert( SCH_ITEM* aItem )
50 {
51 BOX2I bbox = aItem->GetBoundingBox();
52
53 // Inflate a bit for safety, selection shadows, etc.
54 bbox.Inflate( aItem->GetPenWidth() );
55
56 const int type = int( aItem->Type() );
57 const int mmin[3] = { type, bbox.GetX(), bbox.GetY() };
58 const int mmax[3] = { type, bbox.GetRight(), bbox.GetBottom() };
59
60 m_tree.Insert( mmin, mmax, aItem );
61 m_count++;
62 }
63
69 bool remove( SCH_ITEM* aItem )
70 {
71 BOX2I bbox = aItem->GetBoundingBox();
72
73 // Inflate a bit for safety, selection shadows, etc.
74 bbox.Inflate( aItem->GetPenWidth() );
75
76 const int type = int( aItem->Type() );
77 const int mmin[3] = { type, bbox.GetX(), bbox.GetY() };
78 const int mmax[3] = { type, bbox.GetRight(), bbox.GetBottom() };
79
80 // DYNAMIC_RTREE::Remove tries the provided bbox first, then falls back
81 // to full-tree search if the item has moved since insertion.
82 if( !m_tree.Remove( mmin, mmax, aItem ) )
83 return false;
84
85 m_count--;
86 return true;
87 }
88
92 void clear()
93 {
94 m_tree.RemoveAll();
95 m_count = 0;
96 }
97
108 bool contains( const SCH_ITEM* aItem, bool aRobust = false ) const
109 {
110 BOX2I bbox = aItem->GetBoundingBox();
111
112 // Inflate a bit for safety, selection shadows, etc.
113 bbox.Inflate( aItem->GetPenWidth() );
114
115 const int type = int( aItem->Type() );
116 const int mmin[3] = { type, bbox.GetX(), bbox.GetY() };
117 const int mmax[3] = { type, bbox.GetRight(), bbox.GetBottom() };
118 bool found = false;
119
120 auto search =
121 [&found, &aItem]( const SCH_ITEM* aSearchItem )
122 {
123 if( aSearchItem == aItem )
124 {
125 found = true;
126 return false;
127 }
128
129 return true;
130 };
131
132 m_tree.Search( mmin, mmax, search );
133
134 if( !found && aRobust )
135 {
136 // N.B. We must search the whole tree for the pointer to remove
137 // because the item may have been moved. We do not expand the item
138 // type search as this should not change.
139
140 const int mmin2[3] = { type, INT_MIN, INT_MIN };
141 const int mmax2[3] = { type, INT_MAX, INT_MAX };
142
143 m_tree.Search( mmin2, mmax2, search );
144 }
145
146 return found;
147 }
148
154 size_t size() const
155 {
156 return m_count;
157 }
158
159 bool empty() const
160 {
161 return m_count == 0;
162 }
163
174 struct EE_TYPE
175 {
176 using SearchIter = typename ee_rtree::SearchIterator;
177
178 EE_TYPE( const ee_rtree& aTree, KICAD_T aType )
179 {
180 KICAD_T type = BaseType( aType );
181
182 if( type == SCH_LOCATE_ANY_T )
183 {
184 m_min[0] = INT_MIN; m_min[1] = INT_MIN; m_min[2] = INT_MIN;
185 m_max[0] = INT_MAX; m_max[1] = INT_MAX; m_max[2] = INT_MAX;
186 }
187 else
188 {
189 m_min[0] = type; m_min[1] = INT_MIN; m_min[2] = INT_MIN;
190 m_max[0] = type; m_max[1] = INT_MAX; m_max[2] = INT_MAX;
191 }
192
193 m_range = aTree.Overlapping( m_min, m_max );
194 }
195
196 EE_TYPE( const ee_rtree& aTree, KICAD_T aType, const BOX2I& aRect )
197 {
198 KICAD_T type = BaseType( aType );
199
200 if( type == SCH_LOCATE_ANY_T )
201 {
202 m_min[0] = INT_MIN; m_min[1] = aRect.GetX(); m_min[2] = aRect.GetY();
203 m_max[0] = INT_MAX; m_max[1] = aRect.GetRight(); m_max[2] = aRect.GetBottom();
204 }
205 else
206 {
207 m_min[0] = type; m_min[1] = aRect.GetX(); m_min[2] = aRect.GetY();
208 m_max[0] = type; m_max[1] = aRect.GetRight(); m_max[2] = aRect.GetBottom();
209 }
210
211 m_range = aTree.Overlapping( m_min, m_max );
212 }
213
214 SearchIter begin() { return m_range.begin(); }
215 SearchIter end() { return m_range.end(); }
216
217 bool empty() { return m_range.empty(); }
218
219 private:
220 int m_min[3] = {};
221 int m_max[3] = {};
222 typename ee_rtree::SearchRange m_range{ nullptr, m_min, m_max };
223 };
224
225 EE_TYPE OfType( KICAD_T aType ) const
226 {
227 return EE_TYPE( m_tree, aType );
228 }
229
230 EE_TYPE Overlapping( const BOX2I& aRect ) const
231 {
232 return EE_TYPE( m_tree, SCH_LOCATE_ANY_T, aRect );
233 }
234
235 EE_TYPE Overlapping( const VECTOR2I& aPoint, int aAccuracy = 0 ) const
236 {
237 BOX2I rect( aPoint, VECTOR2I( 0, 0 ) );
238 rect.Inflate( aAccuracy );
239 return EE_TYPE( m_tree, SCH_LOCATE_ANY_T, rect );
240 }
241
242 EE_TYPE Overlapping( KICAD_T aType, const VECTOR2I& aPoint, int aAccuracy = 0 ) const
243 {
244 BOX2I rect( aPoint, VECTOR2I( 0, 0 ) );
245 rect.Inflate( aAccuracy );
246 return EE_TYPE( m_tree, aType, rect );
247 }
248
249 EE_TYPE Overlapping( KICAD_T aType, const BOX2I& aRect ) const
250 {
251 return EE_TYPE( m_tree, aType, aRect );
252 }
253
265 typename ee_rtree::Iterator begin() const
266 {
267 return m_tree.begin();
268 }
269
273 typename ee_rtree::Iterator end() const
274 {
275 return m_tree.end();
276 }
277
278
279private:
281 size_t m_count = 0;
282};
283
284
285#endif /* EESCHEMA_SCH_RTREE_H_ */
BOX2< VECTOR2I > BOX2I
Definition box2.h:922
constexpr BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
Definition box2.h:558
constexpr coord_type GetY() const
Definition box2.h:208
constexpr coord_type GetX() const
Definition box2.h:207
constexpr coord_type GetRight() const
Definition box2.h:217
constexpr coord_type GetBottom() const
Definition box2.h:222
virtual const BOX2I GetBoundingBox() const
Return the orthogonal bounding box of this object for display purposes.
Definition eda_item.cpp:120
KICAD_T Type() const
Returns the type of object.
Definition eda_item.h:112
~EE_RTREE()=default
bool empty() const
Definition sch_rtree.h:159
EE_TYPE Overlapping(KICAD_T aType, const BOX2I &aRect) const
Definition sch_rtree.h:249
size_t size() const
Return the number of items in the tree.
Definition sch_rtree.h:154
EE_TYPE Overlapping(const BOX2I &aRect) const
Definition sch_rtree.h:230
ee_rtree m_tree
Definition sch_rtree.h:280
bool remove(SCH_ITEM *aItem)
Remove an item from the tree.
Definition sch_rtree.h:69
ee_rtree::Iterator begin() const
Return a read/write iterator that points to the first.
Definition sch_rtree.h:265
void insert(SCH_ITEM *aItem)
Insert an item into the tree.
Definition sch_rtree.h:49
bool contains(const SCH_ITEM *aItem, bool aRobust=false) const
Determine if a given item exists in the tree.
Definition sch_rtree.h:108
EE_RTREE()=default
KIRTREE::DYNAMIC_RTREE< SCH_ITEM *, int, 3 > ee_rtree
Definition sch_rtree.h:40
EE_TYPE Overlapping(const VECTOR2I &aPoint, int aAccuracy=0) const
Definition sch_rtree.h:235
size_t m_count
Definition sch_rtree.h:281
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:273
EE_TYPE Overlapping(KICAD_T aType, const VECTOR2I &aPoint, int aAccuracy=0) const
Definition sch_rtree.h:242
EE_TYPE OfType(KICAD_T aType) const
Definition sch_rtree.h:225
void clear()
Remove all items from the RTree.
Definition sch_rtree.h:92
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:168
virtual int GetPenWidth() const
Definition sch_item.h:357
The EE_TYPE struct provides a type-specific auto-range iterator to the RTree.
Definition sch_rtree.h:175
ee_rtree::SearchRange m_range
Definition sch_rtree.h:222
EE_TYPE(const ee_rtree &aTree, KICAD_T aType, const BOX2I &aRect)
Definition sch_rtree.h:196
typename ee_rtree::SearchIterator SearchIter
Definition sch_rtree.h:176
SearchIter begin()
Definition sch_rtree.h:214
EE_TYPE(const ee_rtree &aTree, KICAD_T aType)
Definition sch_rtree.h:178
SearchIter end()
Definition sch_rtree.h:215
constexpr KICAD_T BaseType(const KICAD_T aType)
Return the underlying type of the given type.
Definition typeinfo.h:251
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition typeinfo.h:75
@ SCH_LOCATE_ANY_T
Definition typeinfo.h:200
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:687