KiCad PCB EDA Suite
Loading...
Searching...
No Matches
connectivity_algo.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-2017 CERN
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * @author Maciej Suminski <[email protected]>
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// #define CONNECTIVITY_DEBUG
29
30#ifndef __CONNECTIVITY_ALGO_H
31#define __CONNECTIVITY_ALGO_H
32
34
35#include <algorithm>
36#include <deque>
37#include <functional>
38#include <list>
39#include <memory>
40#include <vector>
41
45
46class CN_RATSNEST_NODES;
47class BOARD;
49class BOARD_ITEM;
50class FOOTPRINT;
51class ZONE;
53
54
60{
61public:
63 m_weight( 0 ),
64 m_visible( true )
65 {}
66
67 CN_EDGE( const std::shared_ptr<CN_ANCHOR>& aSource, const std::shared_ptr<CN_ANCHOR>& aTarget,
68 unsigned aWeight = 0 ) :
69 m_source( aSource ),
70 m_target( aTarget ),
71 m_weight( aWeight ),
72 m_visible( true )
73 {}
74
81 bool operator<( CN_EDGE aOther ) const
82 {
83 return m_weight < aOther.m_weight;
84 }
85
98 bool StableSortCompare( const CN_EDGE& aOther ) const
99 {
100 const VECTOR2I& thisPos = GetSourcePos();
101 const VECTOR2I& otherPos = aOther.GetSourcePos();
102
103 // First compare by source node position
104 if( thisPos.x != otherPos.x )
105 return thisPos.x < otherPos.x;
106
107 if( thisPos.y != otherPos.y )
108 return thisPos.y < otherPos.y;
109
110 // Then compare by weight
111 if( m_weight != aOther.m_weight )
112 return m_weight < aOther.m_weight;
113
114 // Then by visibility
115 if( m_visible != aOther.m_visible )
116 return m_visible && !aOther.m_visible;
117
118 // If everything is equal, return false for stable ordering
119 return false;
120 }
121
122 std::shared_ptr<const CN_ANCHOR> GetSourceNode() const { return m_source; }
123 std::shared_ptr<const CN_ANCHOR> GetTargetNode() const { return m_target; }
124
125 void SetSourceNode( const std::shared_ptr<const CN_ANCHOR>& aNode ) { m_source = aNode; }
126 void SetTargetNode( const std::shared_ptr<const CN_ANCHOR>& aNode ) { m_target = aNode; }
127
129 {
130 if( m_source && !m_source->Valid() )
131 m_source.reset();
132
133 if( m_target && !m_target->Valid() )
134 m_target.reset();
135 }
136
137 void SetWeight( unsigned weight ) { m_weight = weight; }
138 unsigned GetWeight() const { return m_weight; }
139
140 void SetVisible( bool aVisible ) { m_visible = aVisible; }
141 bool IsVisible() const { return m_visible; }
142
143 const VECTOR2I GetSourcePos() const { return m_source->Pos(); }
144 const VECTOR2I GetTargetPos() const { return m_target->Pos(); }
145 unsigned GetLength() const
146 {
147 return ( m_target->Pos() - m_source->Pos() ).EuclideanNorm();
148 }
149
150private:
151 std::shared_ptr<const CN_ANCHOR> m_source;
152 std::shared_ptr<const CN_ANCHOR> m_target;
153 unsigned m_weight;
155};
156
157
159{
160public:
167
168 using CLUSTERS = std::vector<std::shared_ptr<CN_CLUSTER>>;
169
170 /*
171 * Holds a list of CN_ITEMs for a given BOARD_CONNECTED_ITEM. For most items (pads, tracks,
172 * etc.) the list will have a single CN_ITEM, but for ZONEs it will have one item for each
173 * distinct outline on each layer.
174 */
176 {
177 public:
178 ITEM_MAP_ENTRY( CN_ITEM* aItem = nullptr )
179 {
180 if( aItem )
181 m_items.push_back( aItem );
182 }
183
185 {
186 for( CN_ITEM* item : m_items )
187 item->SetValid( false );
188 }
189
190 void Link( CN_ITEM* aItem )
191 {
192 m_items.push_back( aItem );
193 }
194
195 const std::list<CN_ITEM*>& GetItems() const
196 {
197 return m_items;
198 }
199
200 std::list<CN_ITEM*> m_items;
201 };
202
203 CN_CONNECTIVITY_ALGO( CONNECTIVITY_DATA* aParentConnectivityData ) :
204 m_parentConnectivityData( aParentConnectivityData ),
205 m_isLocal( false )
206 {}
207
209 {
210 Clear();
211 }
212
213 bool ItemExists( const BOARD_CONNECTED_ITEM* aItem ) const
214 {
215 return m_itemMap.find( aItem ) != m_itemMap.end();
216 }
217
219 {
220 return m_itemMap[ aItem ];
221 }
222
223 bool IsNetDirty( int aNet ) const
224 {
225 if( aNet < 0 )
226 return false;
227
228 return m_dirtyNets[ aNet ];
229 }
230
232 {
233 for( size_t ii = 0; ii < m_dirtyNets.size(); ii++ )
234 m_dirtyNets[ii] = false;
235 }
236
237 void GetDirtyClusters( CLUSTERS& aClusters ) const
238 {
239 for( const std::shared_ptr<CN_CLUSTER>& cl : m_ratsnestClusters )
240 {
241 int net = cl->OriginNet();
242
243 if( net >= 0 && m_dirtyNets[net] )
244 aClusters.push_back( cl );
245 }
246 }
247
248 int NetCount() const
249 {
250 return m_dirtyNets.size();
251 }
252
253 void Build( BOARD* aBoard, PROGRESS_REPORTER* aReporter = nullptr );
254 void LocalBuild( const std::shared_ptr<CONNECTIVITY_DATA>& aGlobalConnectivity,
255 const std::vector<BOARD_ITEM*>& aLocalItems );
256
257 void Clear();
258
259 bool Remove( BOARD_ITEM* aItem );
260 bool Add( BOARD_ITEM* aItem );
261
262 const CLUSTERS SearchClusters( CLUSTER_SEARCH_MODE aMode, bool aExcludeZones, int aSingleNet );
264
269 void PropagateNets( BOARD_COMMIT* aCommit = nullptr );
270
274 void FillIsolatedIslandsMap( std::map<ZONE*, std::map<PCB_LAYER_ID, ISOLATED_ISLANDS>>& aMap,
275 bool aConnectivityAlreadyRebuilt );
276
277 const CLUSTERS& GetClusters();
278
279 const CN_LIST& ItemList() const
280 {
281 return m_itemList;
282 }
283
284 template <typename Func>
285 void ForEachAnchor( Func&& aFunc ) const
286 {
287 for( CN_ITEM* item : m_itemList )
288 {
289 for( std::shared_ptr<CN_ANCHOR>& anchor : item->Anchors() )
290 aFunc( *anchor );
291 }
292 }
293
294 template <typename Func>
295 void ForEachItem( Func&& aFunc ) const
296 {
297 for( CN_ITEM* item : m_itemList )
298 aFunc( *item );
299 }
300
301 void MarkNetAsDirty( int aNet );
302 void RemoveInvalidRefs();
303
304 void SetProgressReporter( PROGRESS_REPORTER* aReporter );
305
306private:
307 void searchConnections();
308
309 void propagateConnections( BOARD_COMMIT* aCommit = nullptr );
310
311 template <class Container, class BItem>
312 void add( Container& c, BItem brditem )
313 {
314 CN_ITEM* item = c.Add( brditem );
315
316 m_itemMap[ brditem ] = ITEM_MAP_ENTRY( item );
317 }
318
319 void markItemNetAsDirty( const BOARD_ITEM* aItem );
320
321 void updateJumperPads();
322
323private:
326 std::unordered_map<const BOARD_ITEM*, ITEM_MAP_ENTRY> m_itemMap;
327
328 std::vector<std::shared_ptr<CN_CLUSTER>> m_connClusters;
329 std::vector<std::shared_ptr<CN_CLUSTER>> m_ratsnestClusters;
330 std::vector<bool> m_dirtyNets;
331
333 std::shared_ptr<CONNECTIVITY_DATA> m_globalConnectivityData;
334
335 std::mutex m_mutex;
336
338};
339
340
342{
343public:
344 CN_VISITOR( CN_ITEM* aItem, std::vector<std::pair<BOARD_CONNECTED_ITEM*, int>>* aDeferredNetCodes,
345 std::mutex* aDeferredNetCodesMutex ) :
346 m_item( aItem ),
347 m_deferredNetCodes( aDeferredNetCodes ),
348 m_deferredNetCodesMutex( aDeferredNetCodesMutex )
349 {}
350
351 bool operator()( CN_ITEM* aCandidate );
352
353protected:
354 void checkZoneItemConnection( CN_ZONE_LAYER* aZoneLayer, CN_ITEM* aItem );
355
356 void checkZoneZoneConnection( CN_ZONE_LAYER* aZoneLayerA, CN_ZONE_LAYER* aZoneLayerB );
357
358protected:
360
363 std::vector<std::pair<BOARD_CONNECTED_ITEM*, int>>* m_deferredNetCodes;
365};
366
367#endif
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition board_item.h:84
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:322
ITEM_MAP_ENTRY(CN_ITEM *aItem=nullptr)
const std::list< CN_ITEM * > & GetItems() const
void MarkItemsAsInvalid()
std::list< CN_ITEM * > m_items
void Link(CN_ITEM *aItem)
void FillIsolatedIslandsMap(std::map< ZONE *, std::map< PCB_LAYER_ID, ISOLATED_ISLANDS > > &aMap, bool aConnectivityAlreadyRebuilt)
Fill in the isolated islands map with copper islands that are not connected to a net.
bool Remove(BOARD_ITEM *aItem)
bool ItemExists(const BOARD_CONNECTED_ITEM *aItem) const
void ForEachItem(Func &&aFunc) const
CN_CONNECTIVITY_ALGO(CONNECTIVITY_DATA *aParentConnectivityData)
CONNECTIVITY_DATA * m_parentConnectivityData
void add(Container &c, BItem brditem)
PROGRESS_REPORTER * m_progressReporter
std::vector< std::shared_ptr< CN_CLUSTER > > m_connClusters
ITEM_MAP_ENTRY & ItemEntry(const BOARD_CONNECTED_ITEM *aItem)
void GetDirtyClusters(CLUSTERS &aClusters) const
void propagateConnections(BOARD_COMMIT *aCommit=nullptr)
const CLUSTERS & GetClusters()
void LocalBuild(const std::shared_ptr< CONNECTIVITY_DATA > &aGlobalConnectivity, const std::vector< BOARD_ITEM * > &aLocalItems)
const CLUSTERS SearchClusters(CLUSTER_SEARCH_MODE aMode, bool aExcludeZones, int aSingleNet)
void markItemNetAsDirty(const BOARD_ITEM *aItem)
std::vector< std::shared_ptr< CN_CLUSTER > > m_ratsnestClusters
void ForEachAnchor(Func &&aFunc) const
void PropagateNets(BOARD_COMMIT *aCommit=nullptr)
Propagate nets from pads to other items in clusters.
std::shared_ptr< CONNECTIVITY_DATA > m_globalConnectivityData
const CN_LIST & ItemList() const
bool IsNetDirty(int aNet) const
std::vector< bool > m_dirtyNets
std::unordered_map< const BOARD_ITEM *, ITEM_MAP_ENTRY > m_itemMap
void SetProgressReporter(PROGRESS_REPORTER *aReporter)
std::vector< std::shared_ptr< CN_CLUSTER > > CLUSTERS
void Build(BOARD *aBoard, PROGRESS_REPORTER *aReporter=nullptr)
bool Add(BOARD_ITEM *aItem)
std::shared_ptr< const CN_ANCHOR > GetSourceNode() const
std::shared_ptr< const CN_ANCHOR > m_target
bool StableSortCompare(const CN_EDGE &aOther) const
Comparison operator for std::stable_sort.
void SetTargetNode(const std::shared_ptr< const CN_ANCHOR > &aNode)
void SetWeight(unsigned weight)
void RemoveInvalidRefs()
void SetSourceNode(const std::shared_ptr< const CN_ANCHOR > &aNode)
void SetVisible(bool aVisible)
unsigned GetWeight() const
std::shared_ptr< const CN_ANCHOR > GetTargetNode() const
unsigned m_weight
const VECTOR2I GetTargetPos() const
unsigned GetLength() const
std::shared_ptr< const CN_ANCHOR > m_source
CN_EDGE(const std::shared_ptr< CN_ANCHOR > &aSource, const std::shared_ptr< CN_ANCHOR > &aTarget, unsigned aWeight=0)
const VECTOR2I GetSourcePos() const
bool IsVisible() const
bool operator<(CN_EDGE aOther) const
This sort operator provides a sort-by-weight for the ratsnest operation.
CN_ITEM represents a BOARD_CONNETED_ITEM in the connectivity system (ie: a pad, track/arc/via,...
std::vector< std::pair< BOARD_CONNECTED_ITEM *, int > > * m_deferredNetCodes
Deferred net code changes collected during parallel connectivity search.
void checkZoneItemConnection(CN_ZONE_LAYER *aZoneLayer, CN_ITEM *aItem)
CN_ITEM * m_item
The item we are looking for connections to.
void checkZoneZoneConnection(CN_ZONE_LAYER *aZoneLayerA, CN_ZONE_LAYER *aZoneLayerB)
CN_VISITOR(CN_ITEM *aItem, std::vector< std::pair< BOARD_CONNECTED_ITEM *, int > > *aDeferredNetCodes, std::mutex *aDeferredNetCodesMutex)
std::mutex * m_deferredNetCodesMutex
bool operator()(CN_ITEM *aCandidate)
A progress reporter interface for use in multi-threaded environments.
Handle a list of polygons defining a copper zone.
Definition zone.h:73
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:695