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-2020 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( aCommit );
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( const 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( const auto& item : citems )
212  {
213  if ( m_connAlgo->ItemExists( item ) )
214  {
215  auto& entry = m_connAlgo->ItemEntry( item );
216 
217  for( const 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_ARC_T || aItem->Type() == PCB_ZONE_AREA_T ||
252  aItem->Type() == PCB_MODULE_T || 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::vector<BOARD_CONNECTED_ITEM*> items;
387  items.reserve( 32 );
388 
389  std::bitset<MAX_STRUCT_TYPE_ID> type_bits;
390 
391  for( unsigned int i = 0; aTypes[i] != EOT; ++i )
392  {
393  wxASSERT( aTypes[i] < MAX_STRUCT_TYPE_ID );
394  type_bits.set( aTypes[i] );
395  }
396 
397  m_connAlgo->ForEachItem( [&]( CN_ITEM& aItem ) {
398  if( aItem.Valid() && ( aItem.Net() == aNetCode ) && type_bits[aItem.Parent()->Type()] )
399  items.push_back( aItem.Parent() );
400  } );
401 
402  std::sort( items.begin(), items.end() );
403  items.erase( std::unique( items.begin(), items.end() ), items.end() );
404  return items;
405 }
406 
407 
408 bool CONNECTIVITY_DATA::CheckConnectivity( std::vector<CN_DISJOINT_NET_ENTRY>& aReport )
409 {
411 
412  for( auto net : m_nets )
413  {
414  if( net )
415  {
416  for( const auto& edge : net->GetEdges() )
417  {
419  ent.net = edge.GetSourceNode()->Parent()->GetNetCode();
420  ent.a = edge.GetSourceNode()->Parent();
421  ent.b = edge.GetTargetNode()->Parent();
422  ent.anchorA = edge.GetSourceNode()->Pos();
423  ent.anchorB = edge.GetTargetNode()->Pos();
424  aReport.push_back( ent );
425  }
426  }
427  }
428 
429  return aReport.empty();
430 }
431 
432 
433 const std::vector<TRACK*> CONNECTIVITY_DATA::GetConnectedTracks( const BOARD_CONNECTED_ITEM* aItem )
434 const
435 {
436  auto& entry = m_connAlgo->ItemEntry( aItem );
437 
438  std::set<TRACK*> tracks;
439  std::vector<TRACK*> rv;
440 
441  for( auto citem : entry.GetItems() )
442  {
443  for( auto connected : citem->ConnectedItems() )
444  {
445  if( connected->Valid() &&
446  ( connected->Parent()->Type() == PCB_TRACE_T ||
447  connected->Parent()->Type() == PCB_VIA_T ||
448  connected->Parent()->Type() == PCB_ARC_T ) )
449  tracks.insert( static_cast<TRACK*> ( connected->Parent() ) );
450  }
451  }
452 
453  std::copy( tracks.begin(), tracks.end(), std::back_inserter( rv ) );
454  return rv;
455 }
456 
457 
459  std::set<D_PAD*>* pads ) const
460 {
461  for( auto citem : m_connAlgo->ItemEntry( aItem ).GetItems() )
462  {
463  for( auto connected : citem->ConnectedItems() )
464  {
465  if( connected->Valid() && connected->Parent()->Type() == PCB_PAD_T )
466  pads->insert( static_cast<D_PAD*> ( connected->Parent() ) );
467  }
468  }
469 }
470 
471 
472 const std::vector<D_PAD*> CONNECTIVITY_DATA::GetConnectedPads( const BOARD_CONNECTED_ITEM* aItem )
473 const
474 {
475  std::set<D_PAD*> pads;
476  std::vector<D_PAD*> rv;
477 
478  GetConnectedPads( aItem, &pads );
479 
480  std::copy( pads.begin(), pads.end(), std::back_inserter( rv ) );
481  return rv;
482 }
483 
484 
485 unsigned int CONNECTIVITY_DATA::GetNodeCount( int aNet ) const
486 {
487  int sum = 0;
488 
489  if( aNet < 0 ) // Node count for all nets
490  {
491  for( const auto& net : m_nets )
492  sum += net->GetNodeCount();
493  }
494  else if( aNet < (int) m_nets.size() )
495  {
496  sum = m_nets[aNet]->GetNodeCount();
497  }
498 
499  return sum;
500 }
501 
502 
503 unsigned int CONNECTIVITY_DATA::GetPadCount( int aNet ) const
504 {
505  int n = 0;
506 
507  for( auto&& pad : m_connAlgo->ItemList() )
508  {
509  if( !pad->Valid() || pad->Parent()->Type() != PCB_PAD_T)
510  continue;
511 
512  auto dpad = static_cast<D_PAD*>( pad->Parent() );
513 
514  if( aNet < 0 || aNet == dpad->GetNetCode() )
515  {
516  n++;
517  }
518  }
519 
520  return n;
521 }
522 
523 
525  const BOARD_CONNECTED_ITEM* aRef,
526  const VECTOR2I& aPos,
527  int aNet )
528 {
529  CN_CLUSTER_PTR refCluster;
530  int refNet = -1;
531 
532  if( aRef )
533  refNet = aRef->GetNetCode();
534 
535  if( aNet >= 0 )
536  refNet = aNet;
537 
538  if( aRef )
539  {
540  for( auto cl : m_connAlgo->GetClusters() )
541  {
542  if( cl->Contains( aRef ) )
543  {
544  refCluster = cl;
545  break;
546  }
547  }
548  }
549 
550  std::set <VECTOR2I> anchors;
551 
552  for( auto cl : m_connAlgo->GetClusters() )
553  {
554  if( cl != refCluster )
555  {
556  for( auto item : *cl )
557  {
558  if( item->Valid() && item->Parent()->GetNetCode() == refNet
559  && item->Parent()->Type() != PCB_ZONE_AREA_T )
560  {
561  for( auto anchor : item->Anchors() )
562  {
563  anchors.insert( anchor->Pos() );
564  }
565  }
566  }
567  }
568  }
569 
570 
571  std::vector<VECTOR2I> rv;
572 
573  std::copy( anchors.begin(), anchors.end(), std::back_inserter( rv ) );
574  std::sort( rv.begin(), rv.end(), [aPos] ( const VECTOR2I& a, const VECTOR2I& b )
575  {
576  auto da = (a - aPos).EuclideanNorm();
577  auto db = (b - aPos).EuclideanNorm();
578 
579  return da < db;
580  } );
581 
582  return rv;
583 }
584 
585 
586 void CONNECTIVITY_DATA::GetUnconnectedEdges( std::vector<CN_EDGE>& aEdges) const
587 {
588  for( auto rnNet : m_nets )
589  {
590  if( rnNet )
591  {
592  for( const auto& edge : rnNet->GetEdges() )
593  {
594  aEdges.push_back( edge );
595  }
596  }
597  }
598 }
599 
600 
602 {
603  auto items = GetConnectivityAlgo()->ItemEntry( aTrack ).GetItems();
604 
605  // Not in the connectivity system. This is a bug!
606  if( items.empty() )
607  {
608  wxFAIL_MSG( "track not in connectivity system" );
609  return false;
610  }
611 
612  CN_ITEM* citem = items.front();
613 
614  if( !citem->Valid() )
615  return false;
616 
617  for( const std::shared_ptr<CN_ANCHOR>& anchor : citem->Anchors() )
618  {
619  if( anchor->IsDangling() )
620  {
621  *aPos = (wxPoint) anchor->Pos();
622  return true;
623  }
624  }
625 
626  return false;
627 }
628 
629 
630 const std::vector<BOARD_CONNECTED_ITEM*> CONNECTIVITY_DATA::GetConnectedItems(
631  const BOARD_CONNECTED_ITEM* aItem, const VECTOR2I& aAnchor, KICAD_T aTypes[] )
632 {
633  auto& entry = m_connAlgo->ItemEntry( aItem );
634  std::vector<BOARD_CONNECTED_ITEM* > rv;
635 
636  for( auto cnItem : entry.GetItems() )
637  {
638  for( auto anchor : cnItem->Anchors() )
639  {
640  if( anchor->Pos() == aAnchor )
641  {
642  for( int i = 0; aTypes[i] > 0; i++ )
643  {
644  if( cnItem->Valid() && cnItem->Parent()->Type() == aTypes[i] )
645  {
646  rv.push_back( cnItem->Parent() );
647  break;
648  }
649  }
650  }
651  }
652  }
653 
654  return rv;
655 }
656 
657 
659 {
660  if ( aNet < 0 || aNet >= (int) m_nets.size() )
661  {
662  return nullptr;
663  }
664 
665  return m_nets[ aNet ];
666 }
667 
668 
670 {
671  if (aItem->Type() == PCB_MODULE_T)
672  {
673  for ( auto pad : static_cast<MODULE*>( aItem )->Pads() )
674  {
675  m_connAlgo->MarkNetAsDirty( pad->GetNetCode() );
676  }
677  }
678  if (aItem->IsConnected() )
679  {
680  m_connAlgo->MarkNetAsDirty( static_cast<BOARD_CONNECTED_ITEM*>( aItem )->GetNetCode() );
681  }
682 }
683 
684 
686 {
687  m_progressReporter = aReporter;
688  m_connAlgo->SetProgressReporter( m_progressReporter );
689 }
690 
691 
692 const std::vector<CN_EDGE> CONNECTIVITY_DATA::GetRatsnestForComponent( MODULE* aComponent, bool aSkipInternalConnections )
693 {
694  std::set<int> nets;
695  std::set<const D_PAD*> pads;
696  std::vector<CN_EDGE> edges;
697 
698  for( auto pad : aComponent->Pads() )
699  {
700  nets.insert( pad->GetNetCode() );
701  pads.insert( pad );
702  }
703 
704  for( const auto& netcode : nets )
705  {
706  const auto& net = GetRatsnestForNet( netcode );
707 
708  for( const auto& edge : net->GetEdges() )
709  {
710  auto srcNode = edge.GetSourceNode();
711  auto dstNode = edge.GetTargetNode();
712 
713  auto srcParent = static_cast<const D_PAD*>( srcNode->Parent() );
714  auto dstParent = static_cast<const D_PAD*>( dstNode->Parent() );
715 
716  bool srcFound = ( pads.find(srcParent) != pads.end() );
717  bool dstFound = ( pads.find(dstParent) != pads.end() );
718 
719  if ( srcFound && dstFound && !aSkipInternalConnections )
720  {
721  edges.push_back( edge );
722  }
723  else if ( srcFound || dstFound )
724  {
725  edges.push_back( edge );
726  }
727  }
728  }
729 
730  return edges;
731 }
732 
733 
double EuclideanNorm(const wxPoint &vector)
Euclidean norm of a 2D vector.
Definition: trigo.h:128
const std::vector< TRACK * > GetConnectedTracks(const BOARD_CONNECTED_ITEM *aItem) const
void Clear()
Function Clear() Erases the connectivity database.
ZONE_CONTAINER handles a list of polygons defining a copper zone.
Definition: class_zone.h:60
int GetNetCode() const
Function GetNetCode.
unsigned int GetNodeCount(int aNet=-1) const
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
std::shared_ptr< CN_CONNECTIVITY_ALGO > GetConnectivityAlgo() const
class ZONE_CONTAINER, a zone area
Definition: typeinfo.h:102
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.
void RecalculateRatsnest(BOARD_COMMIT *aCommit=nullptr)
Function RecalculateRatsnest() Updates the ratsnest for the board.
PADS & 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.
class ARC, an arc track segment on a copper layer
Definition: typeinfo.h:98
class D_PAD, a pad in a footprint
Definition: typeinfo.h:90
BOARD_CONNECTED_ITEM * Parent() const
void FindIsolatedCopperIslands(ZONE_CONTAINER *aZone, std::vector< int > &aIslands)
Function FindIsolatedCopperIslands() Searches for copper islands in zone aZone that are not connected...
CN_ANCHORS & Anchors()
The class PROF_COUNTER is a small class to help profiling.
Definition: profile.h:44
BOARD_CONNECTED_ITEM * b
BOARD_CONNECTED_ITEM is a base class derived from BOARD_ITEM for items that can be connected and have...
std::vector< RN_DYNAMIC_LINE > m_dynamicRatsnest
int Net() const
VECTOR2I anchorB
search types array terminator (End Of Types)
Definition: typeinfo.h:82
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:96
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)
BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:181
const std::vector< CN_EDGE > GetRatsnestForComponent(MODULE *aComponent, bool aSkipInternalConnections=false)
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:97
RN_NET Describes ratsnest for a single net.
Definition: ratsnest_data.h:59
void Show(std::ostream &aStream=std::cerr)
Print the elapsed time (in a suitable unit) to a stream.
Definition: profile.h:99
bool TestTrackEndpointDangling(TRACK *aTrack, wxPoint *aPos)
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:197