27 #include <unordered_set>
29 #include <boost/range/adaptor/map.hpp>
32 #include <geometry/shape_index.h>
49 typedef std::list<ITEM*> NET_ITEMS_LIST;
51 typedef std::unordered_set<ITEM*> ITEM_SET;
90 template<
class Visitor>
91 int Query(
const ITEM* aItem,
int aMinDistance, Visitor& aVisitor );
106 template<
class Visitor>
107 int Query(
const SHAPE* aShape,
int aMinDistance, Visitor& aVisitor );
130 return m_allItems.find( aItem ) != m_allItems.end();
138 int Size()
const {
return m_allItems.size(); }
140 ITEM_SET::iterator begin() {
return m_allItems.begin(); }
141 ITEM_SET::iterator end() {
return m_allItems.end(); }
144 static const int MaxSubIndices = 128;
145 static const int SI_Multilayer = 2;
146 static const int SI_SegDiagonal = 0;
147 static const int SI_SegStraight = 1;
148 static const int SI_Traces = 3;
149 static const int SI_PadsTop = 0;
150 static const int SI_PadsBottom = 1;
152 template <
class Visitor>
153 int querySingle(
int index,
const SHAPE* aShape,
int aMinDistance, Visitor& aVisitor );
155 ITEM_SHAPE_INDEX* getSubindex(
const ITEM* aItem );
157 ITEM_SHAPE_INDEX* m_subIndices[MaxSubIndices];
158 std::map<int, NET_ITEMS_LIST> m_netMap;
164 memset( m_subIndices, 0,
sizeof( m_subIndices ) );
167 INDEX::ITEM_SHAPE_INDEX* INDEX::getSubindex(
const ITEM* aItem )
173 switch( aItem->Kind() )
176 idx_n = SI_Multilayer;
181 if( l.IsMultilayer() )
182 idx_n = SI_Multilayer;
183 else if( l.Start() == B_Cu )
185 else if( l.Start() == F_Cu )
186 idx_n = SI_PadsBottom;
188 idx_n = SI_Traces + 2 * l.Start() + SI_SegStraight;
192 case ITEM::SEGMENT_T:
194 idx_n = SI_Traces + 2 * l.Start() + SI_SegStraight;
201 if( idx_n < 0 || idx_n >= MaxSubIndices )
203 assert( idx_n >= 0 );
204 assert( idx_n < MaxSubIndices );
208 if( !m_subIndices[idx_n] )
209 m_subIndices[idx_n] =
new ITEM_SHAPE_INDEX;
211 return m_subIndices[idx_n];
222 m_allItems.insert( aItem );
223 int net = aItem->
Net();
227 m_netMap[net].push_back( aItem );
239 m_allItems.erase( aItem );
240 int net = aItem->
Net();
242 if( net >= 0 && m_netMap.find( net ) != m_netMap.end() )
243 m_netMap[net].remove( aItem );
252 template<
class Visitor>
253 int INDEX::querySingle(
int index,
const SHAPE* aShape,
int aMinDistance, Visitor& aVisitor )
255 if( !m_subIndices[index] )
258 return m_subIndices[index]->
Query( aShape, aMinDistance, aVisitor,
false );
261 template<
class Visitor>
267 total += querySingle( SI_Multilayer, shape, aMinDistance, aVisitor );
271 if( layers.IsMultilayer() )
273 total += querySingle( SI_PadsTop, shape, aMinDistance, aVisitor );
274 total += querySingle( SI_PadsBottom, shape, aMinDistance, aVisitor );
276 for(
int i = layers.Start(); i <= layers.End(); ++i )
277 total += querySingle( SI_Traces + 2 * i + SI_SegStraight, shape, aMinDistance, aVisitor );
281 int l = layers.Start();
284 total += querySingle( SI_PadsTop, shape, aMinDistance, aVisitor );
286 total += querySingle( SI_PadsBottom, shape, aMinDistance, aVisitor );
288 total += querySingle( SI_Traces + 2 * l + SI_SegStraight, shape, aMinDistance, aVisitor );
294 template<
class Visitor>
299 for(
int i = 0; i < MaxSubIndices; i++ )
300 total += querySingle( i, aShape, aMinDistance, aVisitor );
307 for(
int i = 0; i < MaxSubIndices; ++i )
314 m_subIndices[i] = NULL;
325 if( m_netMap.find( aNet ) == m_netMap.end() )
328 return &m_netMap[aNet];