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/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, bool aSkipRatsnest )
46  : m_skipRatsnest( aSkipRatsnest )
47 {
48  Build( aItems );
49  m_progressReporter = nullptr;
50 }
51 
52 
54 {
55  Clear();
56 }
57 
58 
60 {
61  m_connAlgo->Add( aItem );
62  return true;
63 }
64 
65 
67 {
68  m_connAlgo->Remove( aItem );
69  return true;
70 }
71 
72 
74 {
75  m_connAlgo->Remove( aItem );
76  m_connAlgo->Add( aItem );
77  return true;
78 }
79 
80 
82 {
83  m_connAlgo.reset( new CN_CONNECTIVITY_ALGO );
84  m_connAlgo->Build( aBoard );
86 }
87 
88 
89 void CONNECTIVITY_DATA::Build( const std::vector<BOARD_ITEM*>& aItems )
90 {
91  m_connAlgo.reset( new CN_CONNECTIVITY_ALGO );
92  m_connAlgo->Build( aItems );
93 
95 }
96 
97 
99 {
100  #ifdef PROFILE
101  PROF_COUNTER rnUpdate( "update-ratsnest" );
102  #endif
103  std::vector<RN_NET*> dirty_nets;
104 
105  // Start with net 1 as net 0 is reserved for not-connected
106  // Nets without nodes are also ignored
107  std::copy_if( m_nets.begin() + 1, m_nets.end(), std::back_inserter( dirty_nets ),
108  [] ( RN_NET* aNet ) { return aNet->IsDirty() && aNet->GetNodeCount() > 0; } );
109 
110  // We don't want to spin up a new thread for fewer than 8 nets (overhead costs)
111  size_t parallelThreadCount = std::min<size_t>( std::thread::hardware_concurrency(),
112  ( dirty_nets.size() + 7 ) / 8 );
113 
114  std::atomic<size_t> nextNet( 0 );
115  std::vector<std::future<size_t>> returns( parallelThreadCount );
116 
117  auto update_lambda = [&nextNet, &dirty_nets]() -> size_t
118  {
119  for( size_t i = nextNet++; i < dirty_nets.size(); i = nextNet++ )
120  dirty_nets[i]->Update();
121 
122  return 1;
123  };
124 
125  if( parallelThreadCount == 1 )
126  update_lambda();
127  else
128  {
129  for( size_t ii = 0; ii < parallelThreadCount; ++ii )
130  returns[ii] = std::async( std::launch::async, update_lambda );
131 
132  // Finalize the ratsnest threads
133  for( size_t ii = 0; ii < parallelThreadCount; ++ii )
134  returns[ii].wait();
135  }
136 
137  #ifdef PROFILE
138  rnUpdate.Show();
139  #endif /* PROFILE */
140 }
141 
142 
143 void CONNECTIVITY_DATA::addRatsnestCluster( const std::shared_ptr<CN_CLUSTER>& aCluster )
144 {
145  auto rnNet = m_nets[ aCluster->OriginNet() ];
146 
147  rnNet->AddCluster( aCluster );
148 }
149 
150 
152 {
153  m_connAlgo->PropagateNets( aCommit );
154 
155  int lastNet = m_connAlgo->NetCount();
156 
157  if( lastNet >= (int) m_nets.size() )
158  {
159  unsigned int prevSize = m_nets.size();
160  m_nets.resize( lastNet + 1 );
161 
162  for( unsigned int i = prevSize; i < m_nets.size(); i++ )
163  m_nets[i] = new RN_NET;
164  }
165 
166  auto clusters = m_connAlgo->GetClusters();
167 
168  int dirtyNets = 0;
169 
170  for( int net = 0; net < lastNet; net++ )
171  {
172  if( m_connAlgo->IsNetDirty( net ) )
173  {
174  m_nets[net]->Clear();
175  dirtyNets++;
176  }
177  }
178 
179  for( const auto& c : clusters )
180  {
181  int net = c->OriginNet();
182 
183  // Don't add intentionally-kept zone islands to the ratsnest
184  if( c->IsOrphaned() && c->Size() == 1 )
185  {
186  if( dynamic_cast<CN_ZONE*>( *c->begin() ) )
187  continue;
188  }
189 
190  if( m_connAlgo->IsNetDirty( net ) )
191  {
192  addRatsnestCluster( c );
193  }
194  }
195 
196  m_connAlgo->ClearDirtyFlags();
197 
198  if( !m_skipRatsnest )
199  updateRatsnest();
200 }
201 
202 
203 void CONNECTIVITY_DATA::BlockRatsnestItems( const std::vector<BOARD_ITEM*>& aItems )
204 {
205  std::vector<BOARD_CONNECTED_ITEM*> citems;
206 
207  for( auto item : aItems )
208  {
209  if( item->Type() == PCB_MODULE_T )
210  {
211  for( auto pad : static_cast<MODULE*>(item)->Pads() )
212  citems.push_back( pad );
213  }
214  else
215  {
216  if( auto citem = dynamic_cast<BOARD_CONNECTED_ITEM*>( item ) )
217  citems.push_back( citem );
218  }
219  }
220 
221  for( const auto& item : citems )
222  {
223  if ( m_connAlgo->ItemExists( item ) )
224  {
225  auto& entry = m_connAlgo->ItemEntry( item );
226 
227  for( const auto& cnItem : entry.GetItems() )
228  {
229  for( auto anchor : cnItem->Anchors() )
230  anchor->SetNoLine( true );
231  }
232  }
233  }
234 }
235 
236 
238 {
239  return m_connAlgo->NetCount();
240 }
241 
242 
244  std::vector<int>& aIslands )
245 {
246  // TODO(JE) ZONES
247 #if 0
248  m_connAlgo->FindIsolatedCopperIslands( aZone, aIslands );
249 #endif
250 }
251 
252 void CONNECTIVITY_DATA::FindIsolatedCopperIslands( std::vector<CN_ZONE_ISOLATED_ISLAND_LIST>& aZones )
253 {
254  m_connAlgo->FindIsolatedCopperIslands( aZones );
255 }
256 
257 
258 void CONNECTIVITY_DATA::ComputeDynamicRatsnest( const std::vector<BOARD_ITEM*>& aItems )
259 {
260  m_dynamicRatsnest.clear();
261 
262  if( std::none_of( aItems.begin(), aItems.end(), []( const BOARD_ITEM* aItem )
263  { return( aItem->Type() == PCB_TRACE_T || aItem->Type() == PCB_PAD_T ||
264  aItem->Type() == PCB_ARC_T || aItem->Type() == PCB_ZONE_AREA_T ||
265  aItem->Type() == PCB_MODULE_T || aItem->Type() == PCB_VIA_T ); } ) )
266  {
267  return ;
268  }
269 
270  CONNECTIVITY_DATA connData( aItems, true );
271  BlockRatsnestItems( aItems );
272 
273  for( unsigned int nc = 1; nc < connData.m_nets.size(); nc++ )
274  {
275  auto dynNet = connData.m_nets[nc];
276 
277  if( dynNet->GetNodeCount() != 0 )
278  {
279  auto ourNet = m_nets[nc];
280  CN_ANCHOR_PTR nodeA, nodeB;
281 
282  if( ourNet->NearestBicoloredPair( *dynNet, nodeA, nodeB ) )
283  {
284  RN_DYNAMIC_LINE l;
285  l.a = nodeA->Pos();
286  l.b = nodeB->Pos();
287  l.netCode = nc;
288 
289  m_dynamicRatsnest.push_back( l );
290  }
291  }
292  }
293 
294  const auto& edges = GetRatsnestForItems( aItems );
295 
296  for( const auto& edge : edges )
297  {
298  const auto& nodeA = edge.GetSourceNode();
299  const auto& nodeB = edge.GetTargetNode();
300  RN_DYNAMIC_LINE l;
301 
302  // Use the parents' positions
303  l.a = nodeA->Parent()->GetPosition();
304  l.b = nodeB->Parent()->GetPosition();
305  l.netCode = 0;
306  m_dynamicRatsnest.push_back( l );
307  }
308 }
309 
310 
312 {
313  m_connAlgo->ForEachAnchor( [] ( CN_ANCHOR& anchor ) { anchor.SetNoLine( false ); } );
315 }
316 
317 
319 {
320  m_dynamicRatsnest.clear();
321 }
322 
323 
325 {
326  m_connAlgo->PropagateNets();
327 }
328 
330  std::vector<KICAD_T> aTypes ) const
331 {
332  CN_CONNECTIVITY_ALGO::ITEM_MAP_ENTRY &entry = m_connAlgo->ItemEntry( aItem );
333 
334  for( auto citem : entry.GetItems() )
335  {
336  for( auto connected : citem->ConnectedItems() )
337  {
338  if( connected->Valid() && connected->Layers().Overlaps( aLayer )
339  && ( aTypes.empty()
340  || std::count( aTypes.begin(), aTypes.end(),
341  connected->Parent()->Type() ) > 0 ) )
342  return true;
343  }
344  }
345 
346  return false;
347 }
348 
349 
351 {
352  unsigned int unconnected = 0;
353 
354  for( auto net : m_nets )
355  {
356  if( !net )
357  continue;
358 
359  const auto& edges = net->GetUnconnected();
360 
361  if( edges.empty() )
362  continue;
363 
364  unconnected += edges.size();
365  }
366 
367  return unconnected;
368 }
369 
370 
372 {
373  for( auto net : m_nets )
374  delete net;
375 
376  m_nets.clear();
377 }
378 
379 
380 const std::vector<BOARD_CONNECTED_ITEM*> CONNECTIVITY_DATA::GetConnectedItems(
381  const BOARD_CONNECTED_ITEM* aItem,
382  const KICAD_T aTypes[],
383  bool aIgnoreNetcodes ) const
384 {
385  std::vector<BOARD_CONNECTED_ITEM*> rv;
386  const auto clusters = m_connAlgo->SearchClusters(
387  aIgnoreNetcodes ?
390  aIgnoreNetcodes ? -1 : aItem->GetNetCode() );
391 
392  for( auto cl : clusters )
393  {
394  if( cl->Contains( aItem ) )
395  {
396  for( const auto item : *cl )
397  {
398  if( item->Valid() )
399  rv.push_back( item->Parent() );
400  }
401  }
402  }
403 
404  return rv;
405 }
406 
407 
408 const std::vector<BOARD_CONNECTED_ITEM*> CONNECTIVITY_DATA::GetNetItems( int aNetCode,
409  const KICAD_T aTypes[] ) const
410 {
411  std::vector<BOARD_CONNECTED_ITEM*> items;
412  items.reserve( 32 );
413 
414  std::bitset<MAX_STRUCT_TYPE_ID> type_bits;
415 
416  for( unsigned int i = 0; aTypes[i] != EOT; ++i )
417  {
418  wxASSERT( aTypes[i] < MAX_STRUCT_TYPE_ID );
419  type_bits.set( aTypes[i] );
420  }
421 
422  m_connAlgo->ForEachItem( [&]( CN_ITEM& aItem ) {
423  if( aItem.Valid() && ( aItem.Net() == aNetCode ) && type_bits[aItem.Parent()->Type()] )
424  items.push_back( aItem.Parent() );
425  } );
426 
427  std::sort( items.begin(), items.end() );
428  items.erase( std::unique( items.begin(), items.end() ), items.end() );
429  return items;
430 }
431 
432 
433 bool CONNECTIVITY_DATA::CheckConnectivity( std::vector<CN_DISJOINT_NET_ENTRY>& aReport )
434 {
436 
437  for( auto net : m_nets )
438  {
439  if( net )
440  {
441  for( const auto& edge : net->GetEdges() )
442  {
444  ent.net = edge.GetSourceNode()->Parent()->GetNetCode();
445  ent.a = edge.GetSourceNode()->Parent();
446  ent.b = edge.GetTargetNode()->Parent();
447  ent.anchorA = edge.GetSourceNode()->Pos();
448  ent.anchorB = edge.GetTargetNode()->Pos();
449  aReport.push_back( ent );
450  }
451  }
452  }
453 
454  return aReport.empty();
455 }
456 
457 
458 const std::vector<TRACK*> CONNECTIVITY_DATA::GetConnectedTracks( const BOARD_CONNECTED_ITEM* aItem )
459 const
460 {
461  auto& entry = m_connAlgo->ItemEntry( aItem );
462 
463  std::set<TRACK*> tracks;
464  std::vector<TRACK*> rv;
465 
466  for( auto citem : entry.GetItems() )
467  {
468  for( auto connected : citem->ConnectedItems() )
469  {
470  if( connected->Valid() &&
471  ( connected->Parent()->Type() == PCB_TRACE_T ||
472  connected->Parent()->Type() == PCB_VIA_T ||
473  connected->Parent()->Type() == PCB_ARC_T ) )
474  tracks.insert( static_cast<TRACK*> ( connected->Parent() ) );
475  }
476  }
477 
478  std::copy( tracks.begin(), tracks.end(), std::back_inserter( rv ) );
479  return rv;
480 }
481 
482 
484  std::set<D_PAD*>* pads ) const
485 {
486  for( auto citem : m_connAlgo->ItemEntry( aItem ).GetItems() )
487  {
488  for( auto connected : citem->ConnectedItems() )
489  {
490  if( connected->Valid() && connected->Parent()->Type() == PCB_PAD_T )
491  pads->insert( static_cast<D_PAD*> ( connected->Parent() ) );
492  }
493  }
494 }
495 
496 
497 const std::vector<D_PAD*> CONNECTIVITY_DATA::GetConnectedPads( const BOARD_CONNECTED_ITEM* aItem )
498 const
499 {
500  std::set<D_PAD*> pads;
501  std::vector<D_PAD*> rv;
502 
503  GetConnectedPads( aItem, &pads );
504 
505  std::copy( pads.begin(), pads.end(), std::back_inserter( rv ) );
506  return rv;
507 }
508 
509 
510 unsigned int CONNECTIVITY_DATA::GetNodeCount( int aNet ) const
511 {
512  int sum = 0;
513 
514  if( aNet < 0 ) // Node count for all nets
515  {
516  for( const auto& net : m_nets )
517  sum += net->GetNodeCount();
518  }
519  else if( aNet < (int) m_nets.size() )
520  {
521  sum = m_nets[aNet]->GetNodeCount();
522  }
523 
524  return sum;
525 }
526 
527 
528 unsigned int CONNECTIVITY_DATA::GetPadCount( int aNet ) const
529 {
530  int n = 0;
531 
532  for( auto&& pad : m_connAlgo->ItemList() )
533  {
534  if( !pad->Valid() || pad->Parent()->Type() != PCB_PAD_T)
535  continue;
536 
537  auto dpad = static_cast<D_PAD*>( pad->Parent() );
538 
539  if( aNet < 0 || aNet == dpad->GetNetCode() )
540  {
541  n++;
542  }
543  }
544 
545  return n;
546 }
547 
548 
549 void CONNECTIVITY_DATA::GetUnconnectedEdges( std::vector<CN_EDGE>& aEdges) const
550 {
551  for( auto rnNet : m_nets )
552  {
553  if( rnNet )
554  {
555  for( const auto& edge : rnNet->GetEdges() )
556  {
557  aEdges.push_back( edge );
558  }
559  }
560  }
561 }
562 
563 
565 {
566  auto items = GetConnectivityAlgo()->ItemEntry( aTrack ).GetItems();
567 
568  // Not in the connectivity system. This is a bug!
569  if( items.empty() )
570  {
571  wxFAIL_MSG( "track not in connectivity system" );
572  return false;
573  }
574 
575  CN_ITEM* citem = items.front();
576 
577  if( !citem->Valid() )
578  return false;
579 
580  for( const std::shared_ptr<CN_ANCHOR>& anchor : citem->Anchors() )
581  {
582  if( anchor->IsDangling() )
583  {
584  if( aPos )
585  *aPos = static_cast<wxPoint>( anchor->Pos() );
586 
587  return true;
588  }
589  }
590 
591  return false;
592 }
593 
594 
595 const std::vector<BOARD_CONNECTED_ITEM*> CONNECTIVITY_DATA::GetConnectedItems(
596  const BOARD_CONNECTED_ITEM* aItem, const VECTOR2I& aAnchor, KICAD_T aTypes[] )
597 {
598  auto& entry = m_connAlgo->ItemEntry( aItem );
599  std::vector<BOARD_CONNECTED_ITEM* > rv;
600 
601  for( auto cnItem : entry.GetItems() )
602  {
603  for( auto anchor : cnItem->Anchors() )
604  {
605  if( anchor->Pos() == aAnchor )
606  {
607  for( int i = 0; aTypes[i] > 0; i++ )
608  {
609  if( cnItem->Valid() && cnItem->Parent()->Type() == aTypes[i] )
610  {
611  rv.push_back( cnItem->Parent() );
612  break;
613  }
614  }
615  }
616  }
617  }
618 
619  return rv;
620 }
621 
622 
624 {
625  if ( aNet < 0 || aNet >= (int) m_nets.size() )
626  {
627  return nullptr;
628  }
629 
630  return m_nets[ aNet ];
631 }
632 
633 
635 {
636  if (aItem->Type() == PCB_MODULE_T)
637  {
638  for ( auto pad : static_cast<MODULE*>( aItem )->Pads() )
639  {
640  m_connAlgo->MarkNetAsDirty( pad->GetNetCode() );
641  }
642  }
643  if (aItem->IsConnected() )
644  {
645  m_connAlgo->MarkNetAsDirty( static_cast<BOARD_CONNECTED_ITEM*>( aItem )->GetNetCode() );
646  }
647 }
648 
649 
651 {
652  m_progressReporter = aReporter;
653  m_connAlgo->SetProgressReporter( m_progressReporter );
654 }
655 
656 
657 const std::vector<CN_EDGE> CONNECTIVITY_DATA::GetRatsnestForItems( std::vector<BOARD_ITEM*> aItems )
658 {
659  std::set<int> nets;
660  std::vector<CN_EDGE> edges;
661  std::set<BOARD_CONNECTED_ITEM*> item_set;
662 
663  for( auto item : aItems )
664  {
665  if( item->Type() == PCB_MODULE_T )
666  {
667  auto component = static_cast<MODULE*>( item );
668 
669  for( auto pad : component->Pads() )
670  {
671  nets.insert( pad->GetNetCode() );
672  item_set.insert( pad );
673  }
674  }
675  else if( auto conn_item = dyn_cast<BOARD_CONNECTED_ITEM*>( item ) )
676  {
677  item_set.insert( conn_item );
678  nets.insert( conn_item->GetNetCode() );
679  }
680  }
681 
682  for( const auto& netcode : nets )
683  {
684  const auto& net = GetRatsnestForNet( netcode );
685 
686  for( const auto& edge : net->GetEdges() )
687  {
688  auto srcNode = edge.GetSourceNode();
689  auto dstNode = edge.GetTargetNode();
690 
691  auto srcParent = srcNode->Parent();
692  auto dstParent = dstNode->Parent();
693 
694  bool srcFound = ( item_set.find(srcParent) != item_set.end() );
695  bool dstFound = ( item_set.find(dstParent) != item_set.end() );
696 
697  if ( srcFound && dstFound )
698  edges.push_back( edge );
699  }
700  }
701 
702  return edges;
703 }
704 
705 
706 const std::vector<CN_EDGE> CONNECTIVITY_DATA::GetRatsnestForComponent( MODULE* aComponent, bool aSkipInternalConnections )
707 {
708  std::set<int> nets;
709  std::set<const D_PAD*> pads;
710  std::vector<CN_EDGE> edges;
711 
712  for( auto pad : aComponent->Pads() )
713  {
714  nets.insert( pad->GetNetCode() );
715  pads.insert( pad );
716  }
717 
718  for( const auto& netcode : nets )
719  {
720  const auto& net = GetRatsnestForNet( netcode );
721 
722  for( const auto& edge : net->GetEdges() )
723  {
724  auto srcNode = edge.GetSourceNode();
725  auto dstNode = edge.GetTargetNode();
726 
727  auto srcParent = static_cast<const D_PAD*>( srcNode->Parent() );
728  auto dstParent = static_cast<const D_PAD*>( dstNode->Parent() );
729 
730  bool srcFound = ( pads.find(srcParent) != pads.end() );
731  bool dstFound = ( pads.find(dstParent) != pads.end() );
732 
733  if ( srcFound && dstFound && !aSkipInternalConnections )
734  {
735  edges.push_back( edge );
736  }
737  else if ( srcFound || dstFound )
738  {
739  edges.push_back( edge );
740  }
741  }
742  }
743 
744  return edges;
745 }
746 
747 
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:61
int GetNetCode() const
Function GetNetCode.
bool IsConnectedOnLayer(const BOARD_CONNECTED_ITEM *aItem, int aLayer, std::vector< KICAD_T > aTypes={}) const
unsigned int GetNodeCount(int aNet=-1) const
bool TestTrackEndpointDangling(TRACK *aTrack, wxPoint *aPos=nullptr)
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
const std::list< CN_ITEM * > GetItems() const
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:173
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
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:184
const std::vector< CN_EDGE > GetRatsnestForComponent(MODULE *aComponent, bool aSkipInternalConnections=false)
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:61
void Show(std::ostream &aStream=std::cerr)
Print the elapsed time (in a suitable unit) to a stream.
Definition: profile.h:99
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< CN_EDGE > GetRatsnestForItems(const std::vector< BOARD_ITEM * > aItems)
bool Valid() const
KICAD_T Type() const
Function Type()
Definition: base_struct.h:193