KiCad PCB EDA Suite
connectivity_data.cpp
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) 2017 CERN
5  * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, you may find one here:
19  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20  * or you may search the http://www.gnu.org website for the version 2 license,
21  * or you may write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23  */
24 
25 #ifdef PROFILE
26 #include <profile.h>
27 #endif
28 
29 #include <thread>
30 #include <algorithm>
31 #include <future>
32 
35 #include <ratsnest_data.h>
36 
38 {
39  m_connAlgo.reset( new CN_CONNECTIVITY_ALGO );
40  m_progressReporter = nullptr;
41 }
42 
43 
44 CONNECTIVITY_DATA::CONNECTIVITY_DATA( const std::vector<BOARD_ITEM*>& aItems )
45 {
46  Build( aItems );
47  m_progressReporter = nullptr;
48 }
49 
50 
52 {
53  Clear();
54 }
55 
56 
58 {
59  m_connAlgo->Add( aItem );
60  return true;
61 }
62 
63 
65 {
66  m_connAlgo->Remove( aItem );
67  return true;
68 }
69 
70 
72 {
73  m_connAlgo->Remove( aItem );
74  m_connAlgo->Add( aItem );
75  return true;
76 }
77 
78 
80 {
81  m_connAlgo.reset( new CN_CONNECTIVITY_ALGO );
82  m_connAlgo->Build( aBoard );
84 }
85 
86 
87 void CONNECTIVITY_DATA::Build( const std::vector<BOARD_ITEM*>& aItems )
88 {
89  m_connAlgo.reset( new CN_CONNECTIVITY_ALGO );
90  m_connAlgo->Build( aItems );
91 
93 }
94 
95 
97 {
98  #ifdef PROFILE
99  PROF_COUNTER rnUpdate( "update-ratsnest" );
100  #endif
101  std::vector<RN_NET*> dirty_nets;
102 
103  // Start with net 1 as net 0 is reserved for not-connected
104  // Nets without nodes are also ignored
105  std::copy_if( m_nets.begin() + 1, m_nets.end(), std::back_inserter( dirty_nets ),
106  [] ( RN_NET* aNet ) { return aNet->IsDirty() && aNet->GetNodeCount() > 0; } );
107 
108  // We don't want to spin up a new thread for fewer than 8 nets (overhead costs)
109  size_t parallelThreadCount = std::min<size_t>( std::thread::hardware_concurrency(),
110  ( dirty_nets.size() + 7 ) / 8 );
111 
112  std::atomic<size_t> nextNet( 0 );
113  std::vector<std::future<size_t>> returns( parallelThreadCount );
114 
115  auto update_lambda = [&nextNet, &dirty_nets]() -> size_t
116  {
117  for( size_t i = nextNet++; i < dirty_nets.size(); i = nextNet++ )
118  dirty_nets[i]->Update();
119 
120  return 1;
121  };
122 
123  if( parallelThreadCount == 1 )
124  update_lambda();
125  else
126  {
127  for( size_t ii = 0; ii < parallelThreadCount; ++ii )
128  returns[ii] = std::async( std::launch::async, update_lambda );
129 
130  // Finalize the ratsnest threads
131  for( size_t ii = 0; ii < parallelThreadCount; ++ii )
132  returns[ii].wait();
133  }
134 
135  #ifdef PROFILE
136  rnUpdate.Show();
137  #endif /* PROFILE */
138 }
139 
140 
141 void CONNECTIVITY_DATA::addRatsnestCluster( const std::shared_ptr<CN_CLUSTER>& aCluster )
142 {
143  auto rnNet = m_nets[ aCluster->OriginNet() ];
144 
145  rnNet->AddCluster( aCluster );
146 }
147 
148 
150 {
151  m_connAlgo->PropagateNets();
152 
153  int lastNet = m_connAlgo->NetCount();
154 
155  if( lastNet >= (int) m_nets.size() )
156  {
157  unsigned int prevSize = m_nets.size();
158  m_nets.resize( lastNet + 1 );
159 
160  for( unsigned int i = prevSize; i < m_nets.size(); i++ )
161  m_nets[i] = new RN_NET;
162  }
163 
164  auto clusters = m_connAlgo->GetClusters();
165 
166  int dirtyNets = 0;
167 
168  for( int net = 0; net < lastNet; net++ )
169  {
170  if( m_connAlgo->IsNetDirty( net ) )
171  {
172  m_nets[net]->Clear();
173  dirtyNets++;
174  }
175  }
176 
177  for( auto c : clusters )
178  {
179  int net = c->OriginNet();
180 
181  if( m_connAlgo->IsNetDirty( net ) )
182  {
183  addRatsnestCluster( c );
184  }
185  }
186 
187  m_connAlgo->ClearDirtyFlags();
188 
189  updateRatsnest();
190 }
191 
192 
193 void CONNECTIVITY_DATA::BlockRatsnestItems( const std::vector<BOARD_ITEM*>& aItems )
194 {
195  std::vector<BOARD_CONNECTED_ITEM*> citems;
196 
197  for( auto item : aItems )
198  {
199  if( item->Type() == PCB_MODULE_T )
200  {
201  for( auto pad : static_cast<MODULE*>(item)->Pads() )
202  citems.push_back( pad );
203  }
204  else
205  {
206  citems.push_back( static_cast<BOARD_CONNECTED_ITEM*>(item) );
207  }
208  }
209 
210  for( auto item : citems )
211  {
212  if ( m_connAlgo->ItemExists( item ) )
213  {
214  auto& entry = m_connAlgo->ItemEntry( item );
215 
216  for( auto cnItem : entry.GetItems() )
217  {
218  for( auto anchor : cnItem->Anchors() )
219  anchor->SetNoLine( true );
220  }
221  }
222  }
223 }
224 
225 
227 {
228  return m_connAlgo->NetCount();
229 }
230 
231 
233  std::vector<int>& aIslands )
234 {
235  m_connAlgo->FindIsolatedCopperIslands( aZone, aIslands );
236 }
237 
238 void CONNECTIVITY_DATA::FindIsolatedCopperIslands( std::vector<CN_ZONE_ISOLATED_ISLAND_LIST>& aZones )
239 {
240  m_connAlgo->FindIsolatedCopperIslands( aZones );
241 }
242 
243 
244 void CONNECTIVITY_DATA::ComputeDynamicRatsnest( const std::vector<BOARD_ITEM*>& aItems )
245 {
246  m_dynamicRatsnest.clear();
247 
248  if( std::none_of( aItems.begin(), aItems.end(), []( const BOARD_ITEM* aItem )
249  { return( aItem->Type() == PCB_TRACE_T || aItem->Type() == PCB_PAD_T ||
250  aItem->Type() == PCB_ZONE_AREA_T || aItem->Type() == PCB_MODULE_T ||
251  aItem->Type() == PCB_VIA_T ); } ) )
252  {
253  return ;
254  }
255 
256  CONNECTIVITY_DATA connData( aItems );
257  BlockRatsnestItems( aItems );
258 
259  for( unsigned int nc = 1; nc < connData.m_nets.size(); nc++ )
260  {
261  auto dynNet = connData.m_nets[nc];
262 
263  if( dynNet->GetNodeCount() != 0 )
264  {
265  auto ourNet = m_nets[nc];
266  CN_ANCHOR_PTR nodeA, nodeB;
267 
268  if( ourNet->NearestBicoloredPair( *dynNet, nodeA, nodeB ) )
269  {
270  RN_DYNAMIC_LINE l;
271  l.a = nodeA->Pos();
272  l.b = nodeB->Pos();
273  l.netCode = nc;
274 
275  m_dynamicRatsnest.push_back( l );
276  }
277  }
278  }
279 
280  for( auto net : connData.m_nets )
281  {
282  if( !net )
283  continue;
284 
285  const auto& edges = net->GetUnconnected();
286 
287  if( edges.empty() )
288  continue;
289 
290  for( const auto& edge : edges )
291  {
292  const auto& nodeA = edge.GetSourceNode();
293  const auto& nodeB = edge.GetTargetNode();
294  RN_DYNAMIC_LINE l;
295 
296  l.a = nodeA->Pos();
297  l.b = nodeB->Pos();
298  l.netCode = 0;
299  m_dynamicRatsnest.push_back( l );
300  }
301  }
302 }
303 
304 
306 {
307  m_connAlgo->ForEachAnchor( [] ( CN_ANCHOR& anchor ) { anchor.SetNoLine( false ); } );
309 }
310 
311 
313 {
314  m_dynamicRatsnest.clear();
315 }
316 
317 
319 {
320  m_connAlgo->PropagateNets();
321 }
322 
323 
325 {
326  unsigned int unconnected = 0;
327 
328  for( auto net : m_nets )
329  {
330  if( !net )
331  continue;
332 
333  const auto& edges = net->GetUnconnected();
334 
335  if( edges.empty() )
336  continue;
337 
338  unconnected += edges.size();
339  }
340 
341  return unconnected;
342 }
343 
344 
346 {
347  for( auto net : m_nets )
348  delete net;
349 
350  m_nets.clear();
351 }
352 
353 
354 const std::vector<BOARD_CONNECTED_ITEM*> CONNECTIVITY_DATA::GetConnectedItems(
355  const BOARD_CONNECTED_ITEM* aItem,
356  const KICAD_T aTypes[] ) const
357 {
358  std::vector<BOARD_CONNECTED_ITEM*> rv;
359  const auto clusters = m_connAlgo->SearchClusters( CN_CONNECTIVITY_ALGO::CSM_CONNECTIVITY_CHECK,
360  aTypes, aItem->GetNetCode() );
361 
362  for( auto cl : clusters )
363  {
364  if( cl->Contains( aItem ) )
365  {
366  for( const auto item : *cl )
367  {
368  if( item->Valid() )
369  rv.push_back( item->Parent() );
370  }
371  }
372  }
373 
374  return rv;
375 }
376 
377 
378 const std::vector<BOARD_CONNECTED_ITEM*> CONNECTIVITY_DATA::GetNetItems( int aNetCode,
379  const KICAD_T aTypes[] ) const
380 {
381  std::set<BOARD_CONNECTED_ITEM*> items;
382  std::vector<BOARD_CONNECTED_ITEM*> rv;
383 
384  m_connAlgo->ForEachItem( [&items, aNetCode, &aTypes] ( CN_ITEM& aItem )
385  {
386  if( aItem.Valid() && ( aItem.Net() == aNetCode ) )
387  {
388  KICAD_T itemType = aItem.Parent()->Type();
389 
390  for( int i = 0; aTypes[i] > 0; ++i )
391  {
392  wxASSERT( aTypes[i] < MAX_STRUCT_TYPE_ID );
393 
394  if( itemType == aTypes[i] )
395  {
396  items.insert( aItem.Parent() );
397  break;
398  }
399  }
400  }
401  } );
402 
403  std::copy( items.begin(), items.end(), std::back_inserter( rv ) );
404 
405  return rv;
406 }
407 
408 
409 bool CONNECTIVITY_DATA::CheckConnectivity( std::vector<CN_DISJOINT_NET_ENTRY>& aReport )
410 {
412 
413  for( auto net : m_nets )
414  {
415  if( net )
416  {
417  for( const auto& edge : net->GetEdges() )
418  {
420  ent.net = edge.GetSourceNode()->Parent()->GetNetCode();
421  ent.a = edge.GetSourceNode()->Parent();
422  ent.b = edge.GetTargetNode()->Parent();
423  ent.anchorA = edge.GetSourceNode()->Pos();
424  ent.anchorB = edge.GetTargetNode()->Pos();
425  aReport.push_back( ent );
426  }
427  }
428  }
429 
430  return aReport.empty();
431 }
432 
433 
434 const std::vector<TRACK*> CONNECTIVITY_DATA::GetConnectedTracks( const BOARD_CONNECTED_ITEM* aItem )
435 const
436 {
437  auto& entry = m_connAlgo->ItemEntry( aItem );
438 
439  std::set<TRACK*> tracks;
440  std::vector<TRACK*> rv;
441 
442  for( auto citem : entry.GetItems() )
443  {
444  for( auto connected : citem->ConnectedItems() )
445  {
446  if( connected->Valid() && ( connected->Parent()->Type() == PCB_TRACE_T || connected->Parent()->Type() == PCB_VIA_T ) )
447  tracks.insert( static_cast<TRACK*> ( connected->Parent() ) );
448  }
449  }
450 
451  std::copy( tracks.begin(), tracks.end(), std::back_inserter( rv ) );
452  return rv;
453 }
454 
455 
457  std::set<D_PAD*>* pads ) const
458 {
459  for( auto citem : m_connAlgo->ItemEntry( aItem ).GetItems() )
460  {
461  for( auto connected : citem->ConnectedItems() )
462  {
463  if( connected->Valid() && connected->Parent()->Type() == PCB_PAD_T )
464  pads->insert( static_cast<D_PAD*> ( connected->Parent() ) );
465  }
466  }
467 }
468 
469 
470 const std::vector<D_PAD*> CONNECTIVITY_DATA::GetConnectedPads( const BOARD_CONNECTED_ITEM* aItem )
471 const
472 {
473  std::set<D_PAD*> pads;
474  std::vector<D_PAD*> rv;
475 
476  GetConnectedPads( aItem, &pads );
477 
478  std::copy( pads.begin(), pads.end(), std::back_inserter( rv ) );
479  return rv;
480 }
481 
482 
483 unsigned int CONNECTIVITY_DATA::GetNodeCount( int aNet ) const
484 {
485  int sum = 0;
486 
487  if( aNet < 0 ) // Node count for all nets
488  {
489  for( const auto& net : m_nets )
490  sum += net->GetNodeCount();
491  }
492  else if( aNet < (int) m_nets.size() )
493  {
494  sum = m_nets[aNet]->GetNodeCount();
495  }
496 
497  return sum;
498 }
499 
500 
501 unsigned int CONNECTIVITY_DATA::GetPadCount( int aNet ) const
502 {
503  int n = 0;
504 
505  for( auto pad : m_connAlgo->ItemList() )
506  {
507  if( !pad->Valid() || pad->Parent()->Type() != PCB_PAD_T)
508  continue;
509 
510  auto dpad = static_cast<D_PAD*>( pad->Parent() );
511 
512  if( aNet < 0 || aNet == dpad->GetNetCode() )
513  {
514  n++;
515  }
516  }
517 
518  return n;
519 }
520 
521 
523  const BOARD_CONNECTED_ITEM* aRef,
524  const VECTOR2I& aPos,
525  int aNet )
526 {
527  CN_CLUSTER_PTR refCluster;
528  int refNet = -1;
529 
530  if( aRef )
531  refNet = aRef->GetNetCode();
532 
533  if( aNet >= 0 )
534  refNet = aNet;
535 
536  if( aRef )
537  {
538  for( auto cl : m_connAlgo->GetClusters() )
539  {
540  if( cl->Contains( aRef ) )
541  {
542  refCluster = cl;
543  break;
544  }
545  }
546  }
547 
548  std::set <VECTOR2I> anchors;
549 
550  for( auto cl : m_connAlgo->GetClusters() )
551  {
552  if( cl != refCluster )
553  {
554  for( auto item : *cl )
555  {
556  if( item->Valid() && item->Parent()->GetNetCode() == refNet
557  && item->Parent()->Type() != PCB_ZONE_AREA_T )
558  {
559  for( auto anchor : item->Anchors() )
560  {
561  anchors.insert( anchor->Pos() );
562  }
563  }
564  }
565  }
566  }
567 
568 
569  std::vector<VECTOR2I> rv;
570 
571  std::copy( anchors.begin(), anchors.end(), std::back_inserter( rv ) );
572  std::sort( rv.begin(), rv.end(), [aPos] ( const VECTOR2I& a, const VECTOR2I& b )
573  {
574  auto da = (a - aPos).EuclideanNorm();
575  auto db = (b - aPos).EuclideanNorm();
576 
577  return da < db;
578  } );
579 
580  return rv;
581 }
582 
583 
584 void CONNECTIVITY_DATA::GetUnconnectedEdges( std::vector<CN_EDGE>& aEdges) const
585 {
586  for( auto rnNet : m_nets )
587  {
588  if( rnNet )
589  {
590  for( auto edge : rnNet->GetEdges() )
591  {
592  aEdges.push_back( edge );
593  }
594  }
595  }
596 }
597 
598 
599 const std::vector<BOARD_CONNECTED_ITEM*> CONNECTIVITY_DATA::GetConnectedItems(
600  const BOARD_CONNECTED_ITEM* aItem, const VECTOR2I& aAnchor, KICAD_T aTypes[] )
601 {
602  auto& entry = m_connAlgo->ItemEntry( aItem );
603  std::vector<BOARD_CONNECTED_ITEM* > rv;
604 
605  for( auto cnItem : entry.GetItems() )
606  {
607  for( auto anchor : cnItem->Anchors() )
608  {
609  if( anchor->Pos() == aAnchor )
610  {
611  for( int i = 0; aTypes[i] > 0; i++ )
612  {
613  if( cnItem->Valid() && cnItem->Parent()->Type() == aTypes[i] )
614  {
615  rv.push_back( cnItem->Parent() );
616  break;
617  }
618  }
619  }
620  }
621  }
622 
623  return rv;
624 }
625 
626 
628 {
629  if ( aNet < 0 || aNet >= (int) m_nets.size() )
630  {
631  return nullptr;
632  }
633 
634  return m_nets[ aNet ];
635 }
636 
637 
639 {
640  if (aItem->Type() == PCB_MODULE_T)
641  {
642  for ( auto pad : static_cast<MODULE*>( aItem )->Pads() )
643  {
644  m_connAlgo->MarkNetAsDirty( pad->GetNetCode() );
645  }
646  }
647  if (aItem->IsConnected() )
648  {
649  m_connAlgo->MarkNetAsDirty( static_cast<BOARD_CONNECTED_ITEM*>( aItem )->GetNetCode() );
650  }
651 }
652 
653 
655 {
656  m_progressReporter = aReporter;
657  m_connAlgo->SetProgressReporter( m_progressReporter );
658 }
659 
660 
661 const std::vector<CN_EDGE> CONNECTIVITY_DATA::GetRatsnestForComponent( MODULE* aComponent, bool aSkipInternalConnections )
662 {
663  std::set<int> nets;
664  std::set<D_PAD*> pads;
665  std::vector<CN_EDGE> edges;
666 
667  for( auto pad : aComponent->Pads() )
668  {
669  nets.insert( pad->GetNetCode() );
670  pads.insert( pad );
671  }
672 
673  for ( auto netcode : nets )
674  {
675  auto net = GetRatsnestForNet( netcode );
676 
677  for ( auto edge : net->GetEdges() )
678  {
679  auto srcNode = edge.GetSourceNode();
680  auto dstNode = edge.GetTargetNode();
681 
682  auto srcParent = static_cast<D_PAD*>( srcNode->Parent() );
683  auto dstParent = static_cast<D_PAD*>( dstNode->Parent() );
684 
685  bool srcFound = ( pads.find(srcParent) != pads.end() );
686  bool dstFound = ( pads.find(dstParent) != pads.end() );
687 
688  if ( srcFound && dstFound && !aSkipInternalConnections )
689  {
690  edges.push_back( edge );
691  }
692  else if ( srcFound || dstFound )
693  {
694  edges.push_back( edge );
695  }
696  }
697  }
698 
699  return edges;
700 }
double EuclideanNorm(const wxPoint &vector)
Euclidean norm of a 2D vector.
Definition: trigo.h:112
KICAD_T Type() const
Function Type()
Definition: base_struct.h:201
void Clear()
Function Clear() Erases the connectivity database.
Class ZONE_CONTAINER handles a list of polygons defining a copper zone.
Definition: class_zone.h:60
const std::vector< D_PAD * > GetConnectedPads(const BOARD_CONNECTED_ITEM *aItem) const
Class BOARD_ITEM is a base class for any item which can be embedded within the BOARD container class...
A progress reporter for use in multi-threaded environments.
std::shared_ptr< CN_CONNECTIVITY_ALGO > m_connAlgo
Class that computes missing connections on a PCB.
PROGRESS_REPORTER * m_progressReporter
class ZONE_CONTAINER, a zone area
Definition: typeinfo.h:102
bool Update(BOARD_ITEM *aItem)
Function Update() Updates the connectivity data for an item.
DLIST_ITERATOR_WRAPPER< D_PAD > Pads()
Definition: class_module.h:169
const std::vector< BOARD_CONNECTED_ITEM * > GetConnectedItems(const BOARD_CONNECTED_ITEM *aItem, const VECTOR2I &aAnchor, KICAD_T aTypes[])
void ComputeDynamicRatsnest(const std::vector< BOARD_ITEM * > &aItems)
Function ComputeDynamicRatsnest() Calculates the temporary dynamic ratsnest (i.e. ...
unsigned int GetNodeCount(int aNet=-1) const
class D_PAD, a pad in a footprint
Definition: typeinfo.h:90
void Show()
Print the elapsed time (in ms) to STDERR.
Definition: profile.h:93
void RecalculateRatsnest()
Function RecalculateRatsnest() Updates the ratsnest for the board.
void FindIsolatedCopperIslands(ZONE_CONTAINER *aZone, std::vector< int > &aIslands)
Function FindIsolatedCopperIslands() Searches for copper islands in zone aZone that are not connected...
The class PROF_COUNTER is a small class to help profiling.
Definition: profile.h:45
const std::vector< TRACK * > GetConnectedTracks(const BOARD_CONNECTED_ITEM *aItem) const
BOARD_CONNECTED_ITEM * b
Class BOARD_CONNECTED_ITEM is a base class derived from BOARD_ITEM for items that can be connected an...
std::vector< RN_DYNAMIC_LINE > m_dynamicRatsnest
VECTOR2I anchorB
KICAD_T
Enum KICAD_T is the set of class identification values, stored in EDA_ITEM::m_StructType.
Definition: typeinfo.h:78
class TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:95
class MODULE, a footprint
Definition: typeinfo.h:89
VECTOR2I anchorA
bool Valid() const
const std::vector< VECTOR2I > NearestUnconnectedTargets(const BOARD_CONNECTED_ITEM *aRef, const VECTOR2I &aPos, int aMaxCount=-1)
void PropagateNets()
Function PropagateNets() Propagates the net codes from the source pads to the tracks/vias.
unsigned int GetUnconnectedCount() const
Function GetUnconnectedCount() Returns the number of remaining edges in the ratsnest.
int GetNetCount() const
Function GetNetCount() Returns the total number of nets in the connectivity database.
int Net() const
void ClearDynamicRatsnest()
Function ClearDynamicRatsnest() Erases the temporary dynamic ratsnest (i.e.
void SetProgressReporter(PROGRESS_REPORTER *aReporter)
bool Remove(BOARD_ITEM *aItem)
Function Remove() Removes an item from the connectivity data.
void MarkItemNetAsDirty(BOARD_ITEM *aItem)
std::vector< RN_NET * > m_nets
bool Add(BOARD_ITEM *aItem)
Function Add() Adds an item to the connectivity data.
int GetNetCode() const
Function GetNetCode.
void BlockRatsnestItems(const std::vector< BOARD_ITEM * > &aItems)
RN_NET * GetRatsnestForNet(int aNet)
Function GetRatsnestForNet() Returns the ratsnest, expressed as a set of graph edges for a given net...
BOARD_CONNECTED_ITEM * a
BOARD_CONNECTED_ITEM * Parent() const
bool CheckConnectivity(std::vector< CN_DISJOINT_NET_ENTRY > &aReport)
Class BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:170
virtual bool IsConnected() const
Function IsConnected() Returns information if the object is derived from BOARD_CONNECTED_ITEM.
const std::vector< CN_EDGE > GetRatsnestForComponent(MODULE *aComponent, bool aSkipInternalConnections=false)
size_t i
Definition: json11.cpp:597
std::shared_ptr< CN_CLUSTER > CN_CLUSTER_PTR
std::shared_ptr< CN_ANCHOR > CN_ANCHOR_PTR
int net
void GetUnconnectedEdges(std::vector< CN_EDGE > &aEdges) const
void SetNoLine(bool aEnable)
Decides whether this node can be a ratsnest line target.
unsigned int GetPadCount(int aNet=-1) const
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:96
Class RN_NET Describes ratsnest for a single net.
Definition: ratsnest_data.h:59
void Build(BOARD *aBoard)
Function Build() Builds the connectivity database for the board aBoard.
void HideDynamicRatsnest()
Hides the temporary dynamic ratsnest lines.
void addRatsnestCluster(const std::shared_ptr< CN_CLUSTER > &aCluster)
const std::vector< BOARD_CONNECTED_ITEM * > GetNetItems(int aNetCode, const KICAD_T aTypes[]) const
Function GetNetItems() Returns the list of items that belong to a certain net.