KiCad PCB EDA Suite
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 (C) 2019-2021 KiCad Developers, see AUTHORS.txt for contributors.
6  *
7  * @author Maciej Suminski <maciej.suminski@cern.ch>
8  * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
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 
33 #include <board.h>
34 #include <pad.h>
35 #include <footprint.h>
36 #include <zone.h>
37 
40 
41 #include <memory>
42 #include <algorithm>
43 #include <functional>
44 #include <vector>
45 #include <deque>
46 #include <intrusive_list.h>
47 
51 
52 class CN_CONNECTIVITY_ALGO_IMPL;
53 class CN_RATSNEST_NODES;
54 class BOARD;
56 class BOARD_ITEM;
57 class ZONE;
58 class PROGRESS_REPORTER;
59 
60 class CN_EDGE
61 {
62 public:
64  : m_weight( 0 ), m_visible( true )
65  {}
66 
67  CN_EDGE( CN_ANCHOR_PTR aSource, CN_ANCHOR_PTR aTarget, unsigned aWeight = 0 )
68  : m_source( aSource ), m_target( aTarget ), m_weight( aWeight ), m_visible( true )
69  {}
70 
77  bool operator<( CN_EDGE aOther ) const
78  {
79  return m_weight < aOther.m_weight;
80  }
81 
82  CN_ANCHOR_PTR GetSourceNode() const { return m_source; }
83  CN_ANCHOR_PTR GetTargetNode() const { return m_target; }
84  unsigned GetWeight() const { return m_weight; }
85 
86  void SetSourceNode( const CN_ANCHOR_PTR& aNode ) { m_source = aNode; }
87  void SetTargetNode( const CN_ANCHOR_PTR& aNode ) { m_target = aNode; }
88  void SetWeight( unsigned weight ) { m_weight = weight; }
89 
90  void SetVisible( bool aVisible )
91  {
92  m_visible = aVisible;
93  }
94 
95  bool IsVisible() const
96  {
97  return m_visible;
98  }
99 
100  const VECTOR2I GetSourcePos() const
101  {
102  return m_source->Pos();
103  }
104 
105  const VECTOR2I GetTargetPos() const
106  {
107  return m_target->Pos();
108  }
109 
110 private:
113  unsigned m_weight;
114  bool m_visible;
115 };
116 
118 {
119 public:
121  {
125  };
126 
127  using CLUSTERS = std::vector<CN_CLUSTER_PTR>;
128 
130  {
131  public:
132  ITEM_MAP_ENTRY( CN_ITEM* aItem = nullptr )
133  {
134  if( aItem )
135  m_items.push_back( aItem );
136  }
137 
139  {
140  for( auto item : m_items )
141  {
142  item->SetValid( false );
143  }
144  }
145 
146  void Link( CN_ITEM* aItem )
147  {
148  m_items.push_back( aItem );
149  }
150 
151  const std::list<CN_ITEM*> GetItems() const
152  {
153  return m_items;
154  }
155 
156  std::list<CN_ITEM*> m_items;
157  };
158 
161 
162  bool ItemExists( const BOARD_CONNECTED_ITEM* aItem ) const
163  {
164  return m_itemMap.find( aItem ) != m_itemMap.end();
165  }
166 
168  {
169  return m_itemMap[ aItem ];
170  }
171 
172  bool IsNetDirty( int aNet ) const
173  {
174  if( aNet < 0 )
175  return false;
176 
177  return m_dirtyNets[ aNet ];
178  }
179 
181  {
182  for( auto i = m_dirtyNets.begin(); i != m_dirtyNets.end(); ++i )
183  *i = false;
184  }
185 
186  void GetDirtyClusters( CLUSTERS& aClusters ) const
187  {
188  for( const auto& cl : m_ratsnestClusters )
189  {
190  int net = cl->OriginNet();
191 
192  if( net >= 0 && m_dirtyNets[net] )
193  aClusters.push_back( cl );
194  }
195  }
196 
197  int NetCount() const
198  {
199  return m_dirtyNets.size();
200  }
201 
202  void Build( BOARD* aBoard, PROGRESS_REPORTER* aReporter = nullptr );
203  void Build( const std::vector<BOARD_ITEM*>& aItems );
204 
205  void Clear();
206 
207  bool Remove( BOARD_ITEM* aItem );
208  bool Add( BOARD_ITEM* aItem );
209 
210  const CLUSTERS SearchClusters( CLUSTER_SEARCH_MODE aMode, const KICAD_T aTypes[],
211  int aSingleNet );
213 
219  void PropagateNets( BOARD_COMMIT* aCommit = nullptr,
221 
222  void FindIsolatedCopperIslands( ZONE* aZone, PCB_LAYER_ID aLayer, std::vector<int>& aIslands );
223 
232  void FindIsolatedCopperIslands( std::vector<CN_ZONE_ISOLATED_ISLAND_LIST>& aZones );
233 
234  const CLUSTERS& GetClusters();
235 
236  const CN_LIST& ItemList() const
237  {
238  return m_itemList;
239  }
240 
241  template <typename Func>
242  void ForEachAnchor( Func&& aFunc ) const
243  {
244  for( auto&& item : m_itemList )
245  {
246  for( auto&& anchor : item->Anchors() )
247  aFunc( *anchor );
248  }
249  }
250 
251  template <typename Func>
252  void ForEachItem( Func&& aFunc ) const
253  {
254  for( auto&& item : m_itemList )
255  aFunc( *item );
256  }
257 
258  void MarkNetAsDirty( int aNet );
259  void SetProgressReporter( PROGRESS_REPORTER* aReporter );
260 
261 private:
262  void searchConnections();
263 
264  void propagateConnections( BOARD_COMMIT* aCommit = nullptr,
266 
267  template <class Container, class BItem>
268  void add( Container& c, BItem brditem )
269  {
270  auto item = c.Add( brditem );
271 
272  m_itemMap[ brditem ] = ITEM_MAP_ENTRY( item );
273  }
274 
275  void markItemNetAsDirty( const BOARD_ITEM* aItem );
276 
278 
279  std::unordered_map<const BOARD_ITEM*, ITEM_MAP_ENTRY> m_itemMap;
280 
283  std::vector<bool> m_dirtyNets;
285 
286 };
287 
289 {
290 public:
291  CN_VISITOR( CN_ITEM* aItem ) :
292  m_item( aItem )
293  {}
294 
295  bool operator()( CN_ITEM* aCandidate );
296 
297 protected:
298  void checkZoneItemConnection( CN_ZONE_LAYER* aZoneLayer, CN_ITEM* aItem );
299 
300  void checkZoneZoneConnection( CN_ZONE_LAYER* aZoneLayerA, CN_ZONE_LAYER* aZoneLayerB );
301 
304 };
305 
306 #endif
void SetSourceNode(const CN_ANCHOR_PTR &aNode)
bool operator<(CN_EDGE aOther) const
This sort operator provides a sort-by-weight for the ratsnest operation.
void Link(CN_ITEM *aItem)
bool Remove(BOARD_ITEM *aItem)
PROPAGATE_MODE
Controls how nets are propagated through clusters.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:80
void checkZoneItemConnection(CN_ZONE_LAYER *aZoneLayer, CN_ITEM *aItem)
A progress reporter for use in multi-threaded environments.
CN_ANCHOR_PTR GetTargetNode() const
const std::list< CN_ITEM * > GetItems() const
CN_ANCHOR_PTR m_target
unsigned m_weight
void MarkNetAsDirty(int aNet)
bool Add(BOARD_ITEM *aItem)
void FindIsolatedCopperIslands(ZONE *aZone, PCB_LAYER_ID aLayer, std::vector< int > &aIslands)
void add(Container &c, BItem brditem)
ITEM_MAP_ENTRY(CN_ITEM *aItem=nullptr)
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
void GetDirtyClusters(CLUSTERS &aClusters) const
bool ItemExists(const BOARD_CONNECTED_ITEM *aItem) const
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition: typeinfo.h:77
std::vector< bool > m_dirtyNets
void PropagateNets(BOARD_COMMIT *aCommit=nullptr, PROPAGATE_MODE aMode=PROPAGATE_MODE::SKIP_CONFLICTS)
Propagate nets from pads to other items in clusters.
const CLUSTERS SearchClusters(CLUSTER_SEARCH_MODE aMode, const KICAD_T aTypes[], int aSingleNet)
void MarkItemsAsInvalid()
PCB_LAYER_ID
A quick note on layer IDs:
void markItemNetAsDirty(const BOARD_ITEM *aItem)
void ForEachItem(Func &&aFunc) const
std::list< CN_ITEM * > m_items
ITEM_MAP_ENTRY & ItemEntry(const BOARD_CONNECTED_ITEM *aItem)
void propagateConnections(BOARD_COMMIT *aCommit=nullptr, PROPAGATE_MODE aMode=PROPAGATE_MODE::SKIP_CONFLICTS)
const CN_LIST & ItemList() const
unsigned GetWeight() const
bool IsVisible() const
void SetTargetNode(const CN_ANCHOR_PTR &aNode)
void checkZoneZoneConnection(CN_ZONE_LAYER *aZoneLayerA, CN_ZONE_LAYER *aZoneLayerB)
The item we are looking for connections to.
Handle a list of polygons defining a copper zone.
Definition: zone.h:57
void SetVisible(bool aVisible)
CN_EDGE(CN_ANCHOR_PTR aSource, CN_ANCHOR_PTR aTarget, unsigned aWeight=0)
void SetWeight(unsigned weight)
void ForEachAnchor(Func &&aFunc) const
bool operator()(CN_ITEM *aCandidate)
bool IsNetDirty(int aNet) const
const CLUSTERS & GetClusters()
void Build(BOARD *aBoard, PROGRESS_REPORTER *aReporter=nullptr)
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:190
CN_ANCHOR_PTR m_source
std::shared_ptr< CN_ANCHOR > CN_ANCHOR_PTR
const VECTOR2I GetSourcePos() const
const VECTOR2I GetTargetPos() const
CN_ITEM * m_item
CN_VISITOR(CN_ITEM *aItem)
std::vector< CN_CLUSTER_PTR > CLUSTERS
std::unordered_map< const BOARD_ITEM *, ITEM_MAP_ENTRY > m_itemMap
CN_ANCHOR_PTR GetSourceNode() const
void SetProgressReporter(PROGRESS_REPORTER *aReporter)
PROGRESS_REPORTER * m_progressReporter