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 
31 #include <connectivity_data.h>
32 #include <connectivity_algo.h>
33 #include <ratsnest_data.h>
34 
36 {
37  m_connAlgo.reset( new CN_CONNECTIVITY_ALGO );
38  m_progressReporter = nullptr;
39 }
40 
41 
43 {
44  Clear();
45 }
46 
47 
49 {
50  m_connAlgo->Add( aItem );
51  return true;
52 }
53 
54 
56 {
57  m_connAlgo->Remove( aItem );
58  return true;
59 }
60 
61 
63 {
64  m_connAlgo->Remove( aItem );
65  m_connAlgo->Add( aItem );
66  return true;
67 }
68 
69 
71 {
72  m_connAlgo.reset( new CN_CONNECTIVITY_ALGO );
73  m_connAlgo->Build( aBoard );
75 }
76 
77 
78 void CONNECTIVITY_DATA::Build( const std::vector<BOARD_ITEM*>& aItems )
79 {
80  m_connAlgo.reset( new CN_CONNECTIVITY_ALGO );
81  m_connAlgo->Build( aItems );
82 
84 }
85 
86 
88 {
89  #ifdef PROFILE
90  PROF_COUNTER rnUpdate( "update-ratsnest" );
91  #endif
92 
93  size_t numDirty = std::count_if( m_nets.begin() + 1, m_nets.end(), [] ( RN_NET* aNet )
94  { return aNet->IsDirty(); } );
95 
96  std::atomic<size_t> nextNet( 1 );
97  std::atomic<size_t> threadsFinished( 0 );
98 
99  // We don't want to spin up a new thread for fewer than two nets (overhead costs)
100  size_t parallelThreadCount = std::min<size_t>(
101  std::max<size_t>( std::thread::hardware_concurrency(), 2 ),
102  numDirty / 2 );
103 
104  for( size_t ii = 0; ii < parallelThreadCount; ++ii )
105  {
106  std::thread t = std::thread( [&nextNet, &threadsFinished, this]()
107  {
108  for( size_t i = nextNet.fetch_add( 1 ); i < m_nets.size(); i = nextNet.fetch_add( 1 ) )
109  {
110  if( m_nets[i]->IsDirty() )
111  m_nets[i]->Update();
112  }
113 
114  threadsFinished++;
115  } );
116 
117  t.detach();
118  }
119 
120  // Finalize the ratsnest threads
121  while( threadsFinished < parallelThreadCount )
122  std::this_thread::sleep_for( std::chrono::milliseconds( 1 ) );
123 
124  #ifdef PROFILE
125  rnUpdate.Show();
126  #endif /* PROFILE */
127 }
128 
129 
130 void CONNECTIVITY_DATA::addRatsnestCluster( const std::shared_ptr<CN_CLUSTER>& aCluster )
131 {
132  auto rnNet = m_nets[ aCluster->OriginNet() ];
133 
134  rnNet->AddCluster( aCluster );
135 }
136 
137 
139 {
140  m_connAlgo->PropagateNets();
141 
142  int lastNet = m_connAlgo->NetCount();
143 
144  if( lastNet >= (int) m_nets.size() )
145  {
146  unsigned int prevSize = m_nets.size();
147  m_nets.resize( lastNet + 1 );
148 
149  for( unsigned int i = prevSize; i < m_nets.size(); i++ )
150  m_nets[i] = new RN_NET;
151  }
152 
153  auto clusters = m_connAlgo->GetClusters();
154 
155  int dirtyNets = 0;
156 
157  for( int net = 0; net < lastNet; net++ )
158  {
159  if( m_connAlgo->IsNetDirty( net ) )
160  {
161  m_nets[net]->Clear();
162  dirtyNets++;
163  }
164  }
165 
166  for( auto c : clusters )
167  {
168  int net = c->OriginNet();
169 
170  if( m_connAlgo->IsNetDirty( net ) )
171  {
172  addRatsnestCluster( c );
173  }
174  }
175 
176  m_connAlgo->ClearDirtyFlags();
177 
178  updateRatsnest();
179 }
180 
181 
182 void CONNECTIVITY_DATA::BlockRatsnestItems( const std::vector<BOARD_ITEM*>& aItems )
183 {
184  std::vector<BOARD_CONNECTED_ITEM*> citems;
185 
186  for( auto item : aItems )
187  {
188  if( item->Type() == PCB_MODULE_T )
189  {
190  for( auto pad : static_cast<MODULE*>(item)->Pads() )
191  citems.push_back( pad );
192  }
193  else
194  {
195  citems.push_back( static_cast<BOARD_CONNECTED_ITEM*>(item) );
196  }
197  }
198 
199  for( auto item : citems )
200  {
201  if ( m_connAlgo->ItemExists( item ) )
202  {
203  auto& entry = m_connAlgo->ItemEntry( item );
204 
205  for( auto cnItem : entry.GetItems() )
206  {
207  for( auto anchor : cnItem->Anchors() )
208  anchor->SetNoLine( true );
209  }
210  }
211  }
212 }
213 
214 
216 {
217  return m_connAlgo->NetCount();
218 }
219 
220 
222  std::vector<int>& aIslands )
223 {
224  m_connAlgo->FindIsolatedCopperIslands( aZone, aIslands );
225 }
226 
227 void CONNECTIVITY_DATA::FindIsolatedCopperIslands( std::vector<CN_ZONE_ISOLATED_ISLAND_LIST>& aZones )
228 {
229  m_connAlgo->FindIsolatedCopperIslands( aZones );
230 }
231 
232 int CONNECTIVITY_DATA::countRelevantItems( const std::vector<BOARD_ITEM*>& aItems )
233 {
234  int n = 0;
235 
236  for( const auto item : aItems )
237  {
238  switch( item->Type() )
239  {
240  case PCB_TRACE_T:
241  case PCB_PAD_T:
242  case PCB_ZONE_AREA_T:
243  case PCB_MODULE_T:
244  case PCB_VIA_T:
245  n++;
246  break;
247 
248  default:
249  break;
250  }
251  }
252 
253  return n;
254 }
255 
256 
257 void CONNECTIVITY_DATA::ComputeDynamicRatsnest( const std::vector<BOARD_ITEM*>& aItems )
258 {
259  if( countRelevantItems( aItems ) == 0 )
260  {
261  m_dynamicRatsnest.clear();
262  return ;
263  }
264 
266  m_dynamicConnectivity->Build( aItems );
267 
268  m_dynamicRatsnest.clear();
269 
270  BlockRatsnestItems( aItems );
271 
272  for( unsigned int nc = 1; nc < m_dynamicConnectivity->m_nets.size(); nc++ )
273  {
274  auto dynNet = m_dynamicConnectivity->m_nets[nc];
275 
276  if( dynNet->GetNodeCount() != 0 )
277  {
278  auto ourNet = m_nets[nc];
279  CN_ANCHOR_PTR nodeA, nodeB;
280 
281  if( ourNet->NearestBicoloredPair( *dynNet, nodeA, nodeB ) )
282  {
283  RN_DYNAMIC_LINE l;
284  l.a = nodeA->Pos();
285  l.b = nodeB->Pos();
286  l.netCode = nc;
287 
288  m_dynamicRatsnest.push_back( l );
289  }
290  }
291  }
292 
293  for( auto net : m_dynamicConnectivity->m_nets )
294  {
295  if( !net )
296  continue;
297 
298  const auto& edges = net->GetUnconnected();
299 
300  if( edges.empty() )
301  continue;
302 
303  for( const auto& edge : edges )
304  {
305  const auto& nodeA = edge.GetSourceNode();
306  const auto& nodeB = edge.GetTargetNode();
307  RN_DYNAMIC_LINE l;
308 
309  l.a = nodeA->Pos();
310  l.b = nodeB->Pos();
311  l.netCode = 0;
312  m_dynamicRatsnest.push_back( l );
313  }
314  }
315 }
316 
317 
319 {
320  m_connAlgo->ForEachAnchor( [] ( CN_ANCHOR& anchor ) { anchor.SetNoLine( false ); } );
322 }
323 
324 
326 {
327  m_dynamicConnectivity.reset();
328  m_dynamicRatsnest.clear();
329 }
330 
331 
333 {
334  m_connAlgo->PropagateNets();
335 }
336 
337 
339 {
340  unsigned int unconnected = 0;
341 
342  for( auto net : m_nets )
343  {
344  if( !net )
345  continue;
346 
347  const auto& edges = net->GetUnconnected();
348 
349  if( edges.empty() )
350  continue;
351 
352  unconnected += edges.size();
353  }
354 
355  return unconnected;
356 }
357 
358 
360 {
361  for( auto net : m_nets )
362  delete net;
363 
364  m_nets.clear();
365 }
366 
367 
368 const std::vector<BOARD_CONNECTED_ITEM*> CONNECTIVITY_DATA::GetConnectedItems(
369  const BOARD_CONNECTED_ITEM* aItem,
370  const KICAD_T aTypes[] ) const
371 {
372  std::vector<BOARD_CONNECTED_ITEM*> rv;
373  const auto clusters = m_connAlgo->SearchClusters( CN_CONNECTIVITY_ALGO::CSM_CONNECTIVITY_CHECK,
374  aTypes, aItem->GetNetCode() );
375 
376  for( auto cl : clusters )
377  {
378  if( cl->Contains( aItem ) )
379  {
380  for( const auto item : *cl )
381  {
382  if( item->Valid() )
383  rv.push_back( item->Parent() );
384  }
385  }
386  }
387 
388  return rv;
389 }
390 
391 
392 const std::vector<BOARD_CONNECTED_ITEM*> CONNECTIVITY_DATA::GetNetItems( int aNetCode,
393  const KICAD_T aTypes[] ) const
394 {
395  std::set<BOARD_CONNECTED_ITEM*> items;
396  std::vector<BOARD_CONNECTED_ITEM*> rv;
397 
398  m_connAlgo->ForEachItem( [&items, aNetCode, &aTypes] ( CN_ITEM& aItem )
399  {
400  if( aItem.Valid() && ( aItem.Net() == aNetCode ) )
401  {
402  KICAD_T itemType = aItem.Parent()->Type();
403 
404  for( int i = 0; aTypes[i] > 0; ++i )
405  {
406  wxASSERT( aTypes[i] < MAX_STRUCT_TYPE_ID );
407 
408  if( itemType == aTypes[i] )
409  {
410  items.insert( aItem.Parent() );
411  break;
412  }
413  }
414  }
415  } );
416 
417  std::copy( items.begin(), items.end(), std::back_inserter( rv ) );
418 
419  return rv;
420 }
421 
422 
423 bool CONNECTIVITY_DATA::CheckConnectivity( std::vector<CN_DISJOINT_NET_ENTRY>& aReport )
424 {
426 
427  for( auto net : m_nets )
428  {
429  if( net )
430  {
431  for( const auto& edge : net->GetEdges() )
432  {
434  ent.net = edge.GetSourceNode()->Parent()->GetNetCode();
435  ent.a = edge.GetSourceNode()->Parent();
436  ent.b = edge.GetTargetNode()->Parent();
437  ent.anchorA = edge.GetSourceNode()->Pos();
438  ent.anchorB = edge.GetTargetNode()->Pos();
439  aReport.push_back( ent );
440  }
441  }
442  }
443 
444  return aReport.empty();
445 }
446 
447 
448 const std::vector<TRACK*> CONNECTIVITY_DATA::GetConnectedTracks( const BOARD_CONNECTED_ITEM* aItem )
449 const
450 {
451  auto& entry = m_connAlgo->ItemEntry( aItem );
452 
453  std::set<TRACK*> tracks;
454  std::vector<TRACK*> rv;
455 
456  for( auto citem : entry.GetItems() )
457  {
458  for( auto connected : citem->ConnectedItems() )
459  {
460  if( connected->Valid() && ( connected->Parent()->Type() == PCB_TRACE_T || connected->Parent()->Type() == PCB_VIA_T ) )
461  tracks.insert( static_cast<TRACK*> ( connected->Parent() ) );
462  }
463  }
464 
465  std::copy( tracks.begin(), tracks.end(), std::back_inserter( rv ) );
466  return rv;
467 }
468 
469 
471  std::set<D_PAD*>* pads ) const
472 {
473  for( auto citem : m_connAlgo->ItemEntry( aItem ).GetItems() )
474  {
475  for( auto connected : citem->ConnectedItems() )
476  {
477  if( connected->Valid() && connected->Parent()->Type() == PCB_PAD_T )
478  pads->insert( static_cast<D_PAD*> ( connected->Parent() ) );
479  }
480  }
481 }
482 
483 
484 const std::vector<D_PAD*> CONNECTIVITY_DATA::GetConnectedPads( const BOARD_CONNECTED_ITEM* aItem )
485 const
486 {
487  std::set<D_PAD*> pads;
488  std::vector<D_PAD*> rv;
489 
490  GetConnectedPads( aItem, &pads );
491 
492  std::copy( pads.begin(), pads.end(), std::back_inserter( rv ) );
493  return rv;
494 }
495 
496 
497 unsigned int CONNECTIVITY_DATA::GetNodeCount( int aNet ) const
498 {
499  int sum = 0;
500 
501  if( aNet < 0 ) // Node count for all nets
502  {
503  for( const auto& net : m_nets )
504  sum += net->GetNodeCount();
505  }
506  else if( aNet < (int) m_nets.size() )
507  {
508  sum = m_nets[aNet]->GetNodeCount();
509  }
510 
511  return sum;
512 }
513 
514 
515 unsigned int CONNECTIVITY_DATA::GetPadCount( int aNet ) const
516 {
517  int n = 0;
518 
519  for( auto pad : m_connAlgo->ItemList() )
520  {
521  if( !pad->Valid() || pad->Parent()->Type() != PCB_PAD_T)
522  continue;
523 
524  auto dpad = static_cast<D_PAD*>( pad->Parent() );
525 
526  if( aNet < 0 || aNet == dpad->GetNetCode() )
527  {
528  n++;
529  }
530  }
531 
532  return n;
533 }
534 
535 
537  const BOARD_CONNECTED_ITEM* aRef,
538  const VECTOR2I& aPos,
539  int aNet )
540 {
541  CN_CLUSTER_PTR refCluster;
542  int refNet = -1;
543 
544  if( aRef )
545  refNet = aRef->GetNetCode();
546 
547  if( aNet >= 0 )
548  refNet = aNet;
549 
550  if( aRef )
551  {
552  for( auto cl : m_connAlgo->GetClusters() )
553  {
554  if( cl->Contains( aRef ) )
555  {
556  refCluster = cl;
557  break;
558  }
559  }
560  }
561 
562  std::set <VECTOR2I> anchors;
563 
564  for( auto cl : m_connAlgo->GetClusters() )
565  {
566  if( cl != refCluster )
567  {
568  for( auto item : *cl )
569  {
570  if( item->Valid() && item->Parent()->GetNetCode() == refNet
571  && item->Parent()->Type() != PCB_ZONE_AREA_T )
572  {
573  for( auto anchor : item->Anchors() )
574  {
575  anchors.insert( anchor->Pos() );
576  }
577  }
578  }
579  }
580  }
581 
582 
583  std::vector<VECTOR2I> rv;
584 
585  std::copy( anchors.begin(), anchors.end(), std::back_inserter( rv ) );
586  std::sort( rv.begin(), rv.end(), [aPos] ( const VECTOR2I& a, const VECTOR2I& b )
587  {
588  auto da = (a - aPos).EuclideanNorm();
589  auto db = (b - aPos).EuclideanNorm();
590 
591  return da < db;
592  } );
593 
594  return rv;
595 }
596 
597 
598 void CONNECTIVITY_DATA::GetUnconnectedEdges( std::vector<CN_EDGE>& aEdges) const
599 {
600  for( auto rnNet : m_nets )
601  {
602  if( rnNet )
603  {
604  for( auto edge : rnNet->GetEdges() )
605  {
606  aEdges.push_back( edge );
607  }
608  }
609  }
610 }
611 
612 
613 const std::vector<BOARD_CONNECTED_ITEM*> CONNECTIVITY_DATA::GetConnectedItems(
614  const BOARD_CONNECTED_ITEM* aItem, const VECTOR2I& aAnchor, KICAD_T aTypes[] )
615 {
616  auto& entry = m_connAlgo->ItemEntry( aItem );
617  std::vector<BOARD_CONNECTED_ITEM* > rv;
618 
619  for( auto cnItem : entry.GetItems() )
620  {
621  for( auto anchor : cnItem->Anchors() )
622  {
623  if( anchor->Pos() == aAnchor )
624  {
625  for( int i = 0; aTypes[i] > 0; i++ )
626  {
627  if( cnItem->Valid() && cnItem->Parent()->Type() == aTypes[i] )
628  {
629  rv.push_back( cnItem->Parent() );
630  break;
631  }
632  }
633  }
634  }
635  }
636 
637  return rv;
638 }
639 
640 
642 {
643  if ( aNet < 0 || aNet >= (int) m_nets.size() )
644  {
645  return nullptr;
646  }
647 
648  return m_nets[ aNet ];
649 }
650 
651 
653 {
654  if (aItem->Type() == PCB_MODULE_T)
655  {
656  for ( auto pad : static_cast<MODULE*>( aItem )->Pads() )
657  {
658  m_connAlgo->MarkNetAsDirty( pad->GetNetCode() );
659  }
660  }
661  if (aItem->IsConnected() )
662  {
663  m_connAlgo->MarkNetAsDirty( static_cast<BOARD_CONNECTED_ITEM*>( aItem )->GetNetCode() );
664  }
665 }
666 
667 
669 {
670  m_progressReporter = aReporter;
671  m_connAlgo->SetProgressReporter( m_progressReporter );
672 }
673 
674 
675 const std::vector<CN_EDGE> CONNECTIVITY_DATA::GetRatsnestForComponent( MODULE* aComponent, bool aSkipInternalConnections )
676 {
677  std::set<int> nets;
678  std::set<D_PAD*> pads;
679  std::vector<CN_EDGE> edges;
680 
681  for( auto pad : aComponent->Pads() )
682  {
683  nets.insert( pad->GetNetCode() );
684  pads.insert( pad );
685  }
686 
687  for ( auto netcode : nets )
688  {
689  auto net = GetRatsnestForNet( netcode );
690 
691  for ( auto edge : net->GetEdges() )
692  {
693  auto srcNode = edge.GetSourceNode();
694  auto dstNode = edge.GetTargetNode();
695 
696  auto srcParent = static_cast<D_PAD*>( srcNode->Parent() );
697  auto dstParent = static_cast<D_PAD*>( dstNode->Parent() );
698 
699  bool srcFound = ( pads.find(srcParent) != pads.end() );
700  bool dstFound = ( pads.find(dstParent) != pads.end() );
701 
702  if ( srcFound && dstFound && !aSkipInternalConnections )
703  {
704  edges.push_back( edge );
705  }
706  else if ( srcFound || dstFound )
707  {
708  edges.push_back( edge );
709  }
710  }
711  }
712 
713  return edges;
714 }
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:198
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.
std::shared_ptr< CN_CLUSTER > CN_CLUSTER_PTR
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.
int countRelevantItems(const std::vector< BOARD_ITEM * > &aItems)
void MarkItemNetAsDirty(BOARD_ITEM *aItem)
std::unique_ptr< CONNECTIVITY_DATA > m_dynamicConnectivity
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
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
std::shared_ptr< CN_ANCHOR > CN_ANCHOR_PTR
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.