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