KiCad PCB EDA Suite
Loading...
Searching...
No Matches
shape_index_list.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 The KiCad Developers, see AUTHORS.txt for contributors.
6 * @author Tomasz Wlostowski <[email protected]>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 */
21
22#ifndef __SHAPE_INDEX_LIST_H
23#define __SHAPE_INDEX_LIST_H
24
25#include <vector>
26
27#include <geometry/shape.h>
28#include <math/box2.h>
29#include <math/vector2d.h>
30
31template <class T>
32const SHAPE* defaultShapeFunctor( const T aItem )
33{
34 return aItem->Shape( -1 );
35}
36
37template <class T, const SHAPE* (ShapeFunctor) (const T) = defaultShapeFunctor<T> >
39{
41 {
42 SHAPE_ENTRY( T aParent )
43 {
44 shape = ShapeFunctor( aParent );
45 bbox = shape->BBox( 0 );
46 parent = aParent;
47 }
48
50 {
51 }
52
54 const SHAPE* shape;
56 };
57
58 typedef std::vector<SHAPE_ENTRY> SHAPE_VEC;
59 typedef typename std::vector<SHAPE_ENTRY>::iterator SHAPE_VEC_ITER;
60
61public:
62 // "Normal" iterator interface, for STL algorithms.
64 {
65 public:
67 {}
68
70 m_current( aCurrent )
71 {}
72
73 iterator( const iterator& aB ) :
75 {}
76
77 T operator*() const
78 {
79 return (*m_current).parent;
80 }
81
83 {
84 ++m_current;
85 }
86
87 iterator& operator++( int aDummy )
88 {
89 ++m_current;
90 return *this;
91 }
92
93 bool operator==( const iterator& aRhs ) const
94 {
95 return m_current == aRhs.m_current;
96 }
97
98 bool operator!=( const iterator& aRhs ) const
99 {
100 return m_current != aRhs.m_current;
101 }
102
103 const iterator& operator=( const iterator& aRhs )
104 {
105 m_current = aRhs.m_current;
106 return *this;
107 }
108
109 private:
111 };
112
113 // "Query" iterator, for iterating over a set of spatially matching shapes.
115 {
116 public:
118 {
119 }
120
122 int aMinDistance, bool aExact ) :
123 m_end( aEnd ),
124 m_current( aCurrent ),
125 m_shape( aShape ),
126 m_minDistance( aMinDistance ),
127 m_exact( aExact )
128 {
129 if( aShape )
130 {
131 m_refBBox = aShape->BBox();
132 next();
133 }
134 }
135
137 m_end( aB.m_end ),
138 m_current( aB.m_current ),
139 m_shape( aB.m_shape ),
141 m_exact( aB.m_exact ),
142 m_refBBox( aB.m_refBBox )
143 {
144 }
145
146 T operator*() const
147 {
148 return (*m_current).parent;
149 }
150
152 {
153 ++m_current;
154 next();
155 return *this;
156 }
157
159 {
160 ++m_current;
161 next();
162 return *this;
163 }
164
165 bool operator==( const query_iterator& aRhs ) const
166 {
167 return m_current == aRhs.m_current;
168 }
169
170 bool operator!=( const query_iterator& aRhs ) const
171 {
172 return m_current != aRhs.m_current;
173 }
174
176 {
177 m_end = aRhs.m_end;
178 m_current = aRhs.m_current;
179 m_shape = aRhs.m_shape;
181 m_exact = aRhs.m_exact;
182 m_refBBox = aRhs.m_refBBox;
183 return *this;
184 }
185
186 private:
187 void next()
188 {
189 while( m_current != m_end )
190 {
191 if( m_refBBox.Distance( m_current->bbox ) <= m_minDistance )
192 {
193 if( !m_exact || m_current->shape->Collide( m_shape, m_minDistance ) )
194 return;
195 }
196
197 ++m_current;
198 }
199 }
200
207 };
208
209 void Add( T aItem )
210 {
211 SHAPE_ENTRY s( aItem );
212
213 m_shapes.push_back( s );
214 }
215
216 void Remove( const T aItem )
217 {
219
220 for( i = m_shapes.begin(); i != m_shapes.end(); ++i )
221 {
222 if( i->parent == aItem )
223 break;
224 }
225
226 if( i == m_shapes.end() )
227 return;
228
229 m_shapes.erase( i );
230 }
231
232 int Size() const
233 {
234 return m_shapes.size();
235 }
236
237 template <class Visitor>
238 int Query( const SHAPE* aShape, int aMinDistance, Visitor& aV, bool aExact = true ) // const
239 {
241 int n = 0;
242 VECTOR2I::extended_type minDistSq = (VECTOR2I::extended_type) aMinDistance * aMinDistance;
243
244 BOX2I refBBox = aShape->BBox();
245
246 for( i = m_shapes.begin(); i != m_shapes.end(); ++i )
247 {
248 if( refBBox.SquaredDistance( i->bbox ) <= minDistSq )
249 {
250 if( !aExact || i->shape->Collide( aShape, aMinDistance ) )
251 {
252 n++;
253
254 if( !aV( i->parent ) )
255 return n;
256 }
257 }
258 }
259
260 return n;
261 }
262
263 void Clear()
264 {
265 m_shapes.clear();
266 }
267
268 query_iterator qbegin( SHAPE* aShape, int aMinDistance, bool aExact )
269 {
270 return query_iterator( m_shapes.begin(), m_shapes.end(), aShape, aMinDistance, aExact );
271 }
272
274 {
275 return query_iterator( m_shapes.end(), m_shapes.end(), nullptr, 0, false );
276 }
277
279 {
280 return iterator( m_shapes.begin() );
281 }
282
284 {
285 return iterator( m_shapes.end() );
286 }
287
288private:
290};
291
292#endif
BOX2< VECTOR2I > BOX2I
Definition box2.h:918
constexpr ecoord_type SquaredDistance(const Vec &aP) const
Definition box2.h:782
iterator(SHAPE_VEC_ITER aCurrent)
const iterator & operator=(const iterator &aRhs)
iterator(const iterator &aB)
bool operator!=(const iterator &aRhs) const
iterator & operator++(int aDummy)
bool operator==(const iterator &aRhs) const
query_iterator(SHAPE_VEC_ITER aCurrent, SHAPE_VEC_ITER aEnd, SHAPE *aShape, int aMinDistance, bool aExact)
query_iterator & operator++(int aDummy)
bool operator==(const query_iterator &aRhs) const
bool operator!=(const query_iterator &aRhs) const
query_iterator(const query_iterator &aB)
const query_iterator & operator=(const query_iterator &aRhs)
const query_iterator qend()
int Query(const SHAPE *aShape, int aMinDistance, Visitor &aV, bool aExact=true)
query_iterator qbegin(SHAPE *aShape, int aMinDistance, bool aExact)
std::vector< SHAPE_ENTRY >::iterator SHAPE_VEC_ITER
void Remove(const T aItem)
std::vector< SHAPE_ENTRY > SHAPE_VEC
An abstract shape on 2D plane.
Definition shape.h:124
virtual const BOX2I BBox(int aClearance=0) const =0
Compute a bounding box of the shape, with a margin of aClearance a collision.
VECTOR2_TRAITS< int32_t >::extended_type extended_type
Definition vector2d.h:69
const SHAPE * defaultShapeFunctor(const T aItem)
~SHAPE_ENTRY()
BOX2I bbox
SHAPE_ENTRY(T aParent)
T parent
const SHAPE * shape