KiCad PCB EDA Suite
Loading...
Searching...
No Matches
shape_index.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 (C) 2013 CERN
5 * Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * @author Jacobo Aragunde PĂ©rez
8 * @author Tomasz Wlostowski <[email protected]>
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, you may find one here:
22 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
23 * or you may search the http://www.gnu.org website for the version 2 license,
24 * or you may write to the Free Software Foundation, Inc.,
25 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
26 */
27
28#ifndef __SHAPE_INDEX_H
29#define __SHAPE_INDEX_H
30
31#include <vector>
32
33#include <geometry/rtree.h>
34#include <geometry/shape.h>
35#include <math/box2.h>
36
46template <class T>
47static const SHAPE* shapeFunctor( T aItem, int aLayer )
48{
49 return aItem->Shape( aLayer );
50}
51
61template <class T>
62BOX2I boundingBox( T aObject, int aLayer )
63{
64 BOX2I bbox = shapeFunctor( aObject, aLayer )->BBox();
65
66 return bbox;
67}
68
78template <class T, class V>
79void acceptVisitor( T aObject, V aVisitor )
80{
81 aVisitor( aObject );
82}
83
96template <class T, class U>
97bool collide( T aObject, U aAnotherObject, int aLayer, int aMinDistance )
98{
99 return shapeFunctor( aObject, aLayer )->Collide( aAnotherObject, aMinDistance );
100}
101
102template <class T, class V>
103bool queryCallback( T aShape, void* aContext )
104{
105 V* visitor = (V*) aContext;
106
107 acceptVisitor<T, V>( aShape, *visitor );
108
109 return true;
110}
111
112template <class T = SHAPE*>
114{
115 public:
117 {
118 private:
119 typedef typename RTree<T, int, 2, double>::Iterator RTreeIterator;
121
127 void Init( RTree<T, int, 2, double>* aTree )
128 {
129 aTree->GetFirst( iterator );
130 }
131
132 public:
139 {
140 Init( aIndex->m_tree );
141 }
142
147 {
148 return *iterator;
149 }
150
155 {
156 return ++iterator;
157 }
158
162 bool operator++( int )
163 {
164 return ++iterator;
165 }
166
172 bool IsNull() const
173 {
174 return iterator.IsNull();
175 }
176
182 bool IsNotNull() const
183 {
184 return iterator.IsNotNull();
185 }
186
193 {
194 T object = *iterator;
195 ++iterator;
196
197 return object;
198 }
199 };
200
201 explicit SHAPE_INDEX( int aLayer );
202
203 ~SHAPE_INDEX();
204
210 void Add( T aShape );
211
218 void Add( T aShape, const BOX2I& aBbox );
219
225 void Remove( T aShape );
226
230 void RemoveAll();
231
237 template <class V>
238 void Accept( V aVisitor )
239 {
240 Iterator iter = this->Begin();
241
242 while( !iter.IsNull() )
243 {
244 T shape = *iter;
245 acceptVisitor( shape, aVisitor );
246 iter++;
247 }
248 }
249
255 void Reindex();
256
264 template <class V>
265 int Query( const SHAPE *aShape, int aMinDistance, V& aVisitor) const
266 {
267 BOX2I box = aShape->BBox();
268 box.Inflate( aMinDistance );
269
270 int min[2] = { box.GetX(), box.GetY() };
271 int max[2] = { box.GetRight(), box.GetBottom() };
272
273 return this->m_tree->Search( min, max, aVisitor );
274 }
275
281 Iterator Begin();
282
283 private:
284 RTree<T, int, 2, double>* m_tree;
286};
287
288/*
289 * Class members implementation
290 */
291
292template <class T>
294{
295 this->m_tree = new RTree<T, int, 2, double>();
296 this->m_shapeLayer = aLayer;
297}
298
299template <class T>
301{
302 delete this->m_tree;
303}
304
305template <class T>
306void SHAPE_INDEX<T>::Add( T aShape, const BOX2I& aBbox )
307{
308 int min[2] = { aBbox.GetX(), aBbox.GetY() };
309 int max[2] = { aBbox.GetRight(), aBbox.GetBottom() };
310
311 this->m_tree->Insert( min, max, aShape );
312}
313
314template <class T>
315void SHAPE_INDEX<T>::Add( T aShape )
316{
317 BOX2I box = boundingBox( aShape, this->m_shapeLayer );
318 int min[2] = { box.GetX(), box.GetY() };
319 int max[2] = { box.GetRight(), box.GetBottom() };
320
321 this->m_tree->Insert( min, max, aShape );
322}
323
324template <class T>
326{
327 BOX2I box = boundingBox( aShape, this->m_shapeLayer );
328 int min[2] = { box.GetX(), box.GetY() };
329 int max[2] = { box.GetRight(), box.GetBottom() };
330
331 this->m_tree->Remove( min, max, aShape );
332}
333
334template <class T>
336{
337 this->m_tree->RemoveAll();
338}
339
340template <class T>
342{
343 RTree<T, int, 2, double>* newTree;
344 newTree = new RTree<T, int, 2, double>();
345
346 Iterator iter = this->Begin();
347
348 while( !iter.IsNull() )
349 {
350 T shape = *iter;
351 BOX2I box = boundingBox( shape, this->m_shapeLayer );
352 int min[2] = { box.GetX(), box.GetY() };
353 int max[2] = { box.GetRight(), box.GetBottom() };
354 newTree->Insert( min, max, shape );
355 iter++;
356 }
357
358 delete this->m_tree;
359 this->m_tree = newTree;
360}
361
362template <class T>
364{
365 return Iterator( this );
366}
367
368#endif /* __SHAPE_INDEX_H */
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
bool operator++()
Shift the iterator to the next element.
Definition: shape_index.h:154
RTree< T, int, 2, double >::Iterator RTreeIterator
Definition: shape_index.h:119
RTreeIterator iterator
Definition: shape_index.h:120
bool IsNotNull() const
Check if the iterator has not reached the end.
Definition: shape_index.h:182
bool operator++(int)
Shift the iterator to the next element.
Definition: shape_index.h:162
T Next()
Return the current element of the iterator and moves to the next position.
Definition: shape_index.h:192
void Init(RTree< T, int, 2, double > *aTree)
Setup the internal tree iterator.
Definition: shape_index.h:127
bool IsNull() const
Check if the iterator has reached the end.
Definition: shape_index.h:172
T operator*()
Return the next data element.
Definition: shape_index.h:146
Iterator(SHAPE_INDEX *aIndex)
Create an iterator for the index object.
Definition: shape_index.h:138
void Remove(T aShape)
Remove a SHAPE from the index.
Definition: shape_index.h:325
int m_shapeLayer
Definition: shape_index.h:285
RTree< T, int, 2, double > * m_tree
Definition: shape_index.h:284
SHAPE_INDEX(int aLayer)
Definition: shape_index.h:293
Iterator Begin()
Create an iterator for the current index object.
Definition: shape_index.h:363
void RemoveAll()
Remove all the contents of the index.
Definition: shape_index.h:335
void Accept(V aVisitor)
Accept a visitor for every SHAPE object contained in this INDEX.
Definition: shape_index.h:238
void Reindex()
Rebuild the index.
Definition: shape_index.h:341
void Add(T aShape)
Add a SHAPE to the index.
Definition: shape_index.h:315
int Query(const SHAPE *aShape, int aMinDistance, V &aVisitor) const
Run a callback on every SHAPE object contained in the bounding box of (shape).
Definition: shape_index.h:265
An abstract shape on 2D plane.
Definition: shape.h:126
virtual bool Collide(const VECTOR2I &aP, int aClearance=0, int *aActual=nullptr, VECTOR2I *aLocation=nullptr) const
Check if the boundary of shape (this) lies closer to the point aP than aClearance,...
Definition: shape.h:181
virtual const BOX2I BBox(int aClearance=0) const =0
Compute a bounding box of the shape, with a margin of aClearance a collision.
bool collide(T aObject, U aAnotherObject, int aLayer, int aMinDistance)
Used by SHAPE_INDEX to implement Query().
Definition: shape_index.h:97
bool queryCallback(T aShape, void *aContext)
Definition: shape_index.h:103
static const SHAPE * shapeFunctor(T aItem, int aLayer)
Used by SHAPE_INDEX to get a SHAPE* from another type.
Definition: shape_index.h:47
void acceptVisitor(T aObject, V aVisitor)
Used by SHAPE_INDEX to implement Accept().
Definition: shape_index.h:79
BOX2I boundingBox(T aObject, int aLayer)
Used by SHAPE_INDEX to get the bounding box of a generic T object.
Definition: shape_index.h:62