KiCad PCB EDA Suite
connectivity_algo.h
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) 2013-2017 CERN
5  * @author Maciej Suminski <maciej.suminski@cern.ch>
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 // #define CONNECTIVITY_DEBUG
27 
28 #ifndef __CONNECTIVITY_ALGO_H
29 #define __CONNECTIVITY_ALGO_H
30 
31 #include <class_board.h>
32 #include <class_pad.h>
33 #include <class_module.h>
34 #include <class_zone.h>
35 
38 
39 #include <memory>
40 #include <algorithm>
41 #include <functional>
42 #include <vector>
43 #include <deque>
44 #include <intrusive_list.h>
45 
46 #include <connectivity_data.h>
47 
48 class CN_ITEM;
49 class CN_CONNECTIVITY_ALGO_IMPL;
50 class CN_RATSNEST_NODES;
51 class CN_CLUSTER;
52 class BOARD;
54 class BOARD_ITEM;
55 class ZONE_CONTAINER;
56 class PROGRESS_REPORTER;
57 
58 class CN_ANCHOR
59 {
60 public:
62  {
63  m_item = nullptr;
64  }
65 
66  CN_ANCHOR( const VECTOR2I& aPos, CN_ITEM* aItem )
67  {
68  m_pos = aPos;
69  m_item = aItem;
70  assert( m_item );
71  }
72 
73  bool Valid() const;
74 
75 
76  CN_ITEM* Item() const
77  {
78  return m_item;
79  }
80 
82 
83  const VECTOR2I& Pos() const
84  {
85  return m_pos;
86  }
87 
88  bool IsDirty() const;
89 
91  inline int GetTag() const
92  {
93  return m_tag;
94  }
95 
97  inline void SetTag( int aTag )
98  {
99  m_tag = aTag;
100  }
101 
103  inline void SetNoLine( bool aEnable )
104  {
105  m_noline = aEnable;
106  }
107 
109  inline const bool& GetNoLine() const
110  {
111  return m_noline;
112  }
113 
114  inline void SetCluster( std::shared_ptr<CN_CLUSTER> aCluster )
115  {
116  m_cluster = aCluster;
117  }
118 
119  inline std::shared_ptr<CN_CLUSTER> GetCluster() const
120  {
121  return m_cluster;
122  }
123 
132  bool IsDangling() const;
133 
134  // Tag used for unconnected items.
135  static const int TAG_UNCONNECTED = -1;
136 
137 private:
140 
142  CN_ITEM* m_item = nullptr;
143 
145  int m_tag = -1;
146 
148  bool m_noline = false;
149 
151  std::shared_ptr<CN_CLUSTER> m_cluster;
152 };
153 
154 
155 typedef std::shared_ptr<CN_ANCHOR> CN_ANCHOR_PTR;
156 typedef std::vector<CN_ANCHOR_PTR> CN_ANCHORS;
157 
158 
159 class CN_EDGE
160 {
161 public:
162  CN_EDGE() {};
163  CN_EDGE( CN_ANCHOR_PTR aSource, CN_ANCHOR_PTR aTarget, int aWeight = 0 ) :
164  m_source( aSource ),
165  m_target( aTarget ),
166  m_weight( aWeight ) {}
167 
168  CN_ANCHOR_PTR GetSourceNode() const { return m_source; }
169  CN_ANCHOR_PTR GetTargetNode() const { return m_target; }
170  int GetWeight() const { return m_weight; }
171 
172  void SetSourceNode( const CN_ANCHOR_PTR& aNode ) { m_source = aNode; }
173  void SetTargetNode( const CN_ANCHOR_PTR& aNode ) { m_target = aNode; }
174  void SetWeight( unsigned int weight ) { m_weight = weight; }
175 
176  void SetVisible( bool aVisible )
177  {
178  m_visible = aVisible;
179  }
180 
181  bool IsVisible() const
182  {
183  return m_visible;
184  }
185 
186  const VECTOR2I GetSourcePos() const
187  {
188  return m_source->Pos();
189  }
190 
191  const VECTOR2I GetTargetPos() const
192  {
193  return m_target->Pos();
194  }
195 
196 private:
199  unsigned int m_weight = 0;
200  bool m_visible = true;
201 };
202 
203 
205 {
206 private:
207 
208  bool m_conflicting = false;
209  int m_originNet = 0;
210  CN_ITEM* m_originPad = nullptr;
211  std::vector<CN_ITEM*> m_items;
212 
213 public:
214  CN_CLUSTER();
215  ~CN_CLUSTER();
216 
217  bool HasValidNet() const
218  {
219  return m_originNet >= 0;
220  }
221 
222  int OriginNet() const
223  {
224  return m_originNet;
225  }
226 
227  wxString OriginNetName() const;
228 
229  bool Contains( const CN_ITEM* aItem );
230  bool Contains( const BOARD_CONNECTED_ITEM* aItem );
231  void Dump();
232 
233  int Size() const
234  {
235  return m_items.size();
236  }
237 
238  bool HasNet() const
239  {
240  return m_originNet >= 0;
241  }
242 
243  bool IsOrphaned() const
244  {
245  return m_originPad == nullptr;
246  }
247 
248  bool IsConflicting() const
249  {
250  return m_conflicting;
251  }
252 
253  void Add( CN_ITEM* item );
254 
255  using ITER = decltype(m_items)::iterator;
256 
257  ITER begin() { return m_items.begin(); };
258  ITER end() { return m_items.end(); };
259 };
260 
261 typedef std::shared_ptr<CN_CLUSTER> CN_CLUSTER_PTR;
262 
263 
264 // basic connectivity item
265 class CN_ITEM : public INTRUSIVE_LIST<CN_ITEM>
266 {
267 private:
269 
270  using CONNECTED_ITEMS = std::vector<CN_ITEM*>;
271 
274 
276 
278  bool m_visited;
279 
282 
284  bool m_valid;
285 
287  bool m_dirty;
288 
289 public:
290  void Dump();
291 
292  CN_ITEM( BOARD_CONNECTED_ITEM* aParent, bool aCanChangeNet, int aAnchorCount = 2 )
293  {
294  m_parent = aParent;
295  m_canChangeNet = aCanChangeNet;
296  m_visited = false;
297  m_valid = true;
298  m_dirty = true;
299  m_anchors.reserve( 2 );
300  }
301 
302  virtual ~CN_ITEM() {};
303 
305  {
306  m_anchors.emplace_back( std::make_shared<CN_ANCHOR>( aPos, this ) );
307  //printf("%p add %d\n", this, m_anchors.size() );
308  return m_anchors.back();
309  }
310 
312  {
313  return m_anchors;
314  }
315 
316  void SetValid( bool aValid )
317  {
318  m_valid = aValid;
319  }
320 
321  bool Valid() const
322  {
323  return m_valid;
324  }
325 
326  void SetDirty( bool aDirty )
327  {
328  m_dirty = aDirty;
329  }
330 
331  bool Dirty() const
332  {
333  return m_dirty;
334  }
335 
337  {
338  return m_parent;
339  }
340 
342  {
343  return m_connected;
344  }
345 
347  {
348  m_connected.clear();
349  }
350 
351  void SetVisited( bool aVisited )
352  {
353  m_visited = aVisited;
354  }
355 
356  bool Visited() const
357  {
358  return m_visited;
359  }
360 
361  bool CanChangeNet() const
362  {
363  return m_canChangeNet;
364  }
365 
366  static void Connect( CN_ITEM* a, CN_ITEM* b )
367  {
368  bool foundA = false, foundB = false;
369 
370  for( auto item : a->m_connected )
371  {
372  if( item == b )
373  {
374  foundA = true;
375  break;
376  }
377  }
378 
379  for( auto item : b->m_connected )
380  {
381  if( item == a )
382  {
383  foundB = true;
384  break;
385  }
386  }
387 
388  if( !foundA )
389  a->m_connected.push_back( b );
390 
391  if( !foundB )
392  b->m_connected.push_back( a );
393  }
394 
395  void RemoveInvalidRefs();
396 
397  virtual int AnchorCount() const;
398  virtual const VECTOR2I GetAnchor( int n ) const;
399 
400  int Net() const;
401 };
402 
403 typedef std::shared_ptr<CN_ITEM> CN_ITEM_PTR;
404 
405 
406 class CN_LIST
407 {
408 private:
409  bool m_dirty;
410  std::vector<CN_ANCHOR_PTR> m_anchors;
411  CN_ANCHORS m_layer_anchors[PCB_LAYER_ID_COUNT];
412 
413 protected:
414  std::vector<CN_ITEM*> m_items;
415 
416  void addAnchor( VECTOR2I pos, CN_ITEM* item )
417  {
418  CN_ANCHOR_PTR new_anchor = item->AddAnchor( pos );
419  m_anchors.push_back( new_anchor );
420 
421  for( int i = 0; i < PCB_LAYER_ID_COUNT; i++ )
422  {
423  if( ( item->Parent()->GetLayerSet() & LSET( 1, i ) ).any() )
424  m_layer_anchors[i].push_back( new_anchor );
425  }
426  }
427 
428 private:
429 
430  void sort()
431  {
432  if( m_dirty )
433  {
434  std::sort( m_anchors.begin(), m_anchors.end() );
435 
436  for( auto i = 0; i < PCB_LAYER_ID_COUNT; i++ )
437  {
438  std::sort( m_layer_anchors[i].begin(), m_layer_anchors[i].end() );
439  }
440 
441  m_dirty = false;
442  }
443  }
444 
445 public:
447  {
448  m_dirty = false;
449  }
450 
451  void Clear()
452  {
453  for( auto item : m_items )
454  delete item;
455 
456  m_items.clear();
457  }
458 
459  using ITER = decltype(m_items)::iterator;
460 
461  ITER begin() { return m_items.begin(); };
462  ITER end() { return m_items.end(); };
463 
464  CN_ITEM* operator[] ( int aIndex ) { return m_items[aIndex]; }
465 
466  std::vector<CN_ANCHOR_PTR>& Anchors() { return m_anchors; }
467 
468  template <class T>
469  void FindNearby( VECTOR2I aPosition, int aDistMax, T aFunc, LSET aLayers = LSET::AllLayersMask(), bool aDirtyOnly = false );
470 
471  template <class T>
472  void FindNearby( BOX2I aBBox, T aFunc, LSET aLayers = LSET::AllLayersMask(), bool aDirtyOnly = false );
473 
474  void SetDirty( bool aDirty = true )
475  {
476  m_dirty = aDirty;
477  }
478 
479  bool IsDirty() const
480  {
481  return m_dirty;
482  }
483 
485  {
486  for( auto& anchor : m_anchors )
487  anchor->Item()->ClearConnections();
488  }
489 
490  void RemoveInvalidItems( std::vector<CN_ITEM*>& aGarbage );
491 
493  {
494  for( auto item : m_items )
495  item->SetDirty( false );
496 
497  SetDirty( false );
498  }
499 
501  {
502  for( auto item : m_items )
503  item->SetDirty( true );
504 
505  SetDirty( true );
506  }
507 
508  int Size() const
509  {
510  return m_items.size();
511  }
512 };
513 
514 
515 class CN_PAD_LIST : public CN_LIST
516 {
517 public:
518  CN_ITEM* Add( D_PAD* pad )
519  {
520  auto item = new CN_ITEM( pad, false, 2 );
521 
522  addAnchor( pad->ShapePos(), item );
523  m_items.push_back( item );
524 
525  SetDirty();
526  return item;
527  }
528 };
529 
530 
531 class CN_TRACK_LIST : public CN_LIST
532 {
533 public:
534  CN_ITEM* Add( TRACK* track )
535  {
536  auto item = new CN_ITEM( track, true );
537 
538  m_items.push_back( item );
539 
540  addAnchor( track->GetStart(), item );
541  addAnchor( track->GetEnd(), item );
542  SetDirty();
543 
544  return item;
545  }
546 };
547 
548 
549 class CN_VIA_LIST : public CN_LIST
550 {
551 public:
552  CN_ITEM* Add( VIA* via )
553  {
554  auto item = new CN_ITEM( via, true );
555 
556  m_items.push_back( item );
557  addAnchor( via->GetStart(), item );
558  SetDirty();
559  return item;
560  }
561 };
562 
563 
564 class CN_ZONE : public CN_ITEM
565 {
566 public:
567  CN_ZONE( ZONE_CONTAINER* aParent, bool aCanChangeNet, int aSubpolyIndex ) :
568  CN_ITEM( aParent, aCanChangeNet ),
569  m_subpolyIndex( aSubpolyIndex )
570  {
571  SHAPE_LINE_CHAIN outline = aParent->GetFilledPolysList().COutline( aSubpolyIndex );
572 
573  outline.SetClosed( true );
574  outline.Simplify();
575 
576  m_cachedPoly.reset( new POLY_GRID_PARTITION( outline, 16 ) );
577  }
578 
579  int SubpolyIndex() const
580  {
581  return m_subpolyIndex;
582  }
583 
584  bool ContainsAnchor( const CN_ANCHOR_PTR anchor ) const
585  {
586  return ContainsPoint( anchor->Pos() );
587  }
588 
589  bool ContainsPoint( const VECTOR2I p ) const
590  {
591  auto zone = static_cast<ZONE_CONTAINER*> ( Parent() );
592  return m_cachedPoly->ContainsPoint( p, zone->GetMinThickness() );
593  }
594 
595  const BOX2I& BBox() const
596  {
597  return m_cachedPoly->BBox();
598  }
599 
600  virtual int AnchorCount() const override;
601  virtual const VECTOR2I GetAnchor( int n ) const override;
602 
603 private:
604  std::vector<VECTOR2I> m_testOutlinePoints;
605  std::unique_ptr<POLY_GRID_PARTITION> m_cachedPoly;
607 };
608 
609 
610 class CN_ZONE_LIST : public CN_LIST
611 {
612 public:
614 
615  const std::vector<CN_ITEM*> Add( ZONE_CONTAINER* zone )
616  {
617  const auto& polys = zone->GetFilledPolysList();
618 
619  std::vector<CN_ITEM*> rv;
620 
621  for( int j = 0; j < polys.OutlineCount(); j++ )
622  {
623  CN_ZONE* zitem = new CN_ZONE( zone, false, j );
624  const auto& outline = zone->GetFilledPolysList().COutline( j );
625 
626  for( int k = 0; k < outline.PointCount(); k++ )
627  addAnchor( outline.CPoint( k ), zitem );
628 
629  m_items.push_back( zitem );
630  rv.push_back( zitem );
631  SetDirty();
632  }
633 
634  return rv;
635  }
636 
637  template <class T>
638  void FindNearbyZones( BOX2I aBBox, T aFunc, bool aDirtyOnly = false );
639 };
640 
641 
642 template <class T>
643 void CN_LIST::FindNearby( BOX2I aBBox, T aFunc, LSET aLayers, bool aDirtyOnly )
644 {
645  sort();
646 
647  CN_ANCHORS *anchor_set = &m_anchors;
648  PCB_LAYER_ID layer = aLayers.ExtractLayer();
649 
650  if( layer > 0 )
651  anchor_set = &(m_layer_anchors[ layer ]);
652 
653  if( (*anchor_set).size() == 0 )
654  return;
655 
656  CN_ANCHOR_PTR lower_ptr = std::make_shared<CN_ANCHOR>
657  ( aBBox.GetPosition(), (*anchor_set)[0]->Item() );
658 
659  auto lower_it = std::lower_bound( anchor_set->begin(), anchor_set->end(), lower_ptr,
660  []( const CN_ANCHOR_PTR& a, const CN_ANCHOR_PTR& b ) -> bool
661  { return a->Pos().x < b->Pos().x; } );
662 
663  for( auto it = lower_it; it != anchor_set->end(); it++)
664  {
665  if( (*it)->Pos().x > aBBox.GetRight() )
666  break;
667 
668  if( (*it)->Valid() && ( !aDirtyOnly || (*it)->IsDirty() )
669  && aBBox.Contains( (*it)->Pos() ) )
670  aFunc( *it );
671  }
672 }
673 
674 
675 template <class T>
676 void CN_ZONE_LIST::FindNearbyZones( BOX2I aBBox, T aFunc, bool aDirtyOnly )
677 {
678  for( auto item : m_items )
679  {
680  auto zone = static_cast<CN_ZONE*>( item );
681 
682  if( aBBox.Intersects( zone->BBox() ) )
683  {
684  if( !aDirtyOnly || zone->Dirty() )
685  {
686  aFunc( zone );
687  }
688  }
689  }
690 }
691 
692 
693 template <class T>
694 void CN_LIST::FindNearby( VECTOR2I aPosition, int aDistMax, T aFunc, LSET aLayers, bool aDirtyOnly )
695 {
696  /* Search items in m_Candidates that position is <= aDistMax from aPosition
697  * (Rectilinear distance)
698  * m_Candidates is sorted by X then Y values, so binary search is made for the first
699  * element. Then a linear iteration is made to identify all element that are also
700  * in the correct y range.
701  */
702 
703  sort();
704 
705  CN_ANCHORS *anchor_set = &m_anchors;
706  PCB_LAYER_ID layer = aLayers.ExtractLayer();
707 
708  if( layer > 0 )
709  anchor_set = &(m_layer_anchors[ layer ]);
710 
711  if( (*anchor_set).size() == 0 )
712  return;
713 
714  CN_ANCHOR_PTR lower = std::make_shared<CN_ANCHOR>
715  ( aPosition - VECTOR2I( aDistMax, 0 ), (*anchor_set)[0]->Item() );
716 
717  auto lower_it = std::lower_bound( anchor_set->begin(), anchor_set->end(), lower,
718  []( const CN_ANCHOR_PTR& a, const CN_ANCHOR_PTR& b ) -> bool
719  { return a->Pos().x < b->Pos().x; } );
720 
721  for( auto it = lower_it; it != anchor_set->end(); it++ )
722  {
723  if( (*it)->Pos().x > aDistMax + aPosition.x )
724  break;
725 
726  if( (*it)->Valid() && std::abs( (*it)->Pos().y - aPosition.y ) < aDistMax
727  && ( !aDirtyOnly || (*it)->IsDirty() ) )
728  aFunc( *it );
729  }
730 }
731 
732 
734 {
735 public:
737  {
740  CSM_RATSNEST
741  };
742 
743  using CLUSTERS = std::vector<CN_CLUSTER_PTR>;
744 
745 private:
746 
747  bool m_lastSearchWithZones = false;
748 
750  {
751 public:
752  ITEM_MAP_ENTRY( CN_ITEM* aItem = nullptr )
753  {
754  if( aItem )
755  m_items.push_back( aItem );
756  }
757 
759  {
760  for( auto item : m_items )
761  {
762  item->SetValid( false );
763  }
764  }
765 
766  void Link( CN_ITEM* aItem )
767  {
768  m_items.push_back( aItem );
769  }
770 
771  const std::list<CN_ITEM*> GetItems() const
772  {
773  return m_items;
774  }
775 
776  std::list<CN_ITEM*> m_items;
777  };
778 
779 
784 
785  using ITEM_MAP_PAIR = std::pair <const BOARD_CONNECTED_ITEM*, ITEM_MAP_ENTRY>;
786 
787  std::unordered_map<const BOARD_CONNECTED_ITEM*, ITEM_MAP_ENTRY> m_itemMap;
788 
791  std::vector<bool> m_dirtyNets;
792  PROGRESS_REPORTER* m_progressReporter = nullptr;
793 
794  void searchConnections( bool aIncludeZones = false );
795 
796  void update();
797  void propagateConnections();
798 
799  template <class Container, class BItem>
800  void add( Container& c, BItem brditem )
801  {
802  auto item = c.Add( brditem );
803 
804  m_itemMap[ brditem ] = ITEM_MAP_ENTRY( item );
805  }
806 
807  bool addConnectedItem( BOARD_CONNECTED_ITEM* aItem );
808  bool isDirty() const;
809 
810  void markItemNetAsDirty( const BOARD_ITEM* aItem );
811 
812 public:
813 
816 
817  bool ItemExists( const BOARD_CONNECTED_ITEM* aItem )
818  {
819  return m_itemMap.find( aItem ) != m_itemMap.end();
820  }
821 
823  {
824  return m_itemMap[ aItem ];
825  }
826 
827  bool IsNetDirty( int aNet ) const
828  {
829  if( aNet < 0 )
830  return false;
831 
832  return m_dirtyNets[ aNet ];
833  }
834 
836  {
837  for( auto i = m_dirtyNets.begin(); i != m_dirtyNets.end(); ++i )
838  *i = false;
839  }
840 
841  void GetDirtyClusters( CLUSTERS& aClusters )
842  {
843  for( auto cl : m_ratsnestClusters )
844  {
845  int net = cl->OriginNet();
846 
847  if( net >= 0 && m_dirtyNets[net] )
848  aClusters.push_back( cl );
849  }
850  }
851 
852  int NetCount() const
853  {
854  return m_dirtyNets.size();
855  }
856 
857  void Build( BOARD* aBoard );
858  void Build( const std::vector<BOARD_ITEM*>& aItems );
859 
860  void Clear();
861 
862  bool Remove( BOARD_ITEM* aItem );
863  bool Add( BOARD_ITEM* aItem );
864 
865  const CLUSTERS SearchClusters( CLUSTER_SEARCH_MODE aMode, const KICAD_T aTypes[], int aSingleNet );
866  const CLUSTERS SearchClusters( CLUSTER_SEARCH_MODE aMode );
867 
868  void PropagateNets();
869  void FindIsolatedCopperIslands( ZONE_CONTAINER* aZone, std::vector<int>& aIslands );
870  void FindIsolatedCopperIslands( std::vector<CN_ZONE_ISOLATED_ISLAND_LIST>& aZones );
871 
872  bool CheckConnectivity( std::vector<CN_DISJOINT_NET_ENTRY>& aReport );
873 
874  const CLUSTERS& GetClusters();
875  int GetUnconnectedCount();
876 
877  CN_PAD_LIST& PadList() { return m_padList; }
878 
879  void ForEachAnchor( const std::function<void( CN_ANCHOR& )>& aFunc );
880  void ForEachItem( const std::function<void( CN_ITEM& )>& aFunc );
881 
882  void MarkNetAsDirty( int aNet );
883  void SetProgressReporter( PROGRESS_REPORTER* aReporter );
884 
885 };
886 
887 bool operator<( const CN_ANCHOR_PTR& a, const CN_ANCHOR_PTR& b );
888 
889 #endif
std::vector< CN_ITEM * > CONNECTED_ITEMS
std::vector< CN_ITEM * > m_items
Class ZONE_CONTAINER handles a list of polygons defining a copper zone.
Definition: class_zone.h:60
void SetSourceNode(const CN_ANCHOR_PTR &aNode)
CN_EDGE(CN_ANCHOR_PTR aSource, CN_ANCHOR_PTR aTarget, int aWeight=0)
decltype(m_items)::iterator ITER
BOARD_CONNECTED_ITEM * m_parent
void Link(CN_ITEM *aItem)
bool Valid() const
void addAnchor(VECTOR2I pos, CN_ITEM *item)
Class BOARD_ITEM is a base class for any item which can be embedded within the BOARD container class...
std::shared_ptr< CN_CLUSTER > m_cluster
Cluster to which the anchor belongs.
A progress reporter for use in multi-threaded environments.
std::vector< VECTOR2I > m_testOutlinePoints
CN_ITEM * Add(TRACK *track)
bool IsDirty() const
Class BOARD to handle a board.
bool Contains(const Vec &aPoint) const
Function Contains.
Definition: box2.h:139
std::vector< CN_ANCHOR_PTR > CN_ANCHORS
bool m_valid
valid flag, used to identify garbage items (we use lazy removal)
A lightweight intrusive list container
void ClearDirtyFlags()
void ClearConnections()
CN_ANCHOR_PTR m_target
std::pair< const BOARD_CONNECTED_ITEM *, ITEM_MAP_ENTRY > ITEM_MAP_PAIR
coord_type GetRight() const
Definition: box2.h:187
const bool & GetNoLine() const
Returns true if this node can be a target for ratsnest lines.
void SetVisited(bool aVisited)
BOARD_CONNECTED_ITEM * Parent() const
bool HasValidNet() const
bool ContainsAnchor(const CN_ANCHOR_PTR anchor) const
Classes to handle copper zones.
bool IsConflicting() const
CN_ANCHOR_PTR GetTargetNode() const
CN_ITEM * Item() const
static const int TAG_UNCONNECTED
void add(Container &c, BItem brditem)
ITEM_MAP_ENTRY(CN_ITEM *aItem=nullptr)
void ClearConnections()
void SetCluster(std::shared_ptr< CN_CLUSTER > aCluster)
CN_ANCHORS & Anchors()
VECTOR2< int > VECTOR2I
Definition: vector2d.h:589
#define abs(a)
Definition: auxiliary.h:84
Class BOARD_CONNECTED_ITEM is a base class derived from BOARD_ITEM for items that can be connected an...
std::unordered_map< const BOARD_CONNECTED_ITEM *, ITEM_MAP_ENTRY > m_itemMap
void SetDirty(bool aDirty=true)
const wxPoint & GetEnd() const
Definition: class_track.h:119
KICAD_T
Enum KICAD_T is the set of class identification values, stored in EDA_ITEM::m_StructType.
Definition: typeinfo.h:78
std::vector< bool > m_dirtyNets
void MarkAllAsDirty()
bool ContainsPoint(const VECTOR2I p) const
VECTOR2I m_pos
Position of the anchor.
PCB_LAYER_ID ExtractLayer() const
Find the first set PCB_LAYER_ID.
Definition: lset.cpp:612
void SetValid(bool aValid)
void FindNearbyZones(BOX2I aBBox, T aFunc, bool aDirtyOnly=false)
SHAPE_LINE_CHAIN & Simplify()
Function Simplify()
void MarkItemsAsInvalid()
bool IsDangling() const
has meaning only for tracks and vias.
std::vector< CN_ITEM * > m_items
void SetClosed(bool aClosed)
Function SetClosed()
bool m_visited
visited flag for the BFS scan
PCB_LAYER_ID
A quick note on layer IDs:
Class LSET is a set of PCB_LAYER_IDs.
std::list< CN_ITEM * > m_items
ITEM_MAP_ENTRY & ItemEntry(const BOARD_CONNECTED_ITEM *aItem)
int SubpolyIndex() const
bool Valid() const
CN_ANCHOR(const VECTOR2I &aPos, CN_ITEM *aItem)
const wxPoint & GetStart() const
Definition: class_track.h:122
bool IsNetDirty(int aNet) const
bool Visited() const
bool ItemExists(const BOARD_CONNECTED_ITEM *aItem)
bool m_dirty
dirty flag, used to identify recently added item not yet scanned into the connectivity search ...
decltype(m_items)::iterator ITER
const Vec & GetPosition() const
Definition: box2.h:182
virtual LSET GetLayerSet() const
Function GetLayerSet returns a "layer mask", which is a bitmap of all layers on which the TRACK segme...
int OriginNet() const
bool IsVisible() const
const std::list< CN_ITEM * > GetItems() const
void SetTargetNode(const CN_ANCHOR_PTR &aNode)
bool Intersects(const BOX2< Vec > &aRect) const
Function Intersects.
Definition: box2.h:224
const VECTOR2I GetTargetPos() const
std::shared_ptr< CN_ITEM > CN_ITEM_PTR
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
static LSET AllLayersMask()
Definition: lset.cpp:710
virtual ~CN_ITEM()
std::shared_ptr< CN_CLUSTER > CN_CLUSTER_PTR
void SetVisible(bool aVisible)
void SetTag(int aTag)
Sets tag, common identifier for connected nodes.
const CONNECTED_ITEMS & ConnectedItems() const
CN_ANCHOR_PTR AddAnchor(const VECTOR2I &aPos)
bool IsOrphaned() const
bool m_canChangeNet
can the net propagator modify the netcode?
CN_ITEM * Add(VIA *via)
const SHAPE_POLY_SET & GetFilledPolysList() const
Function GetFilledPolysList returns a reference to the list of filled polygons.
Definition: class_zone.h:534
std::vector< CN_ANCHOR_PTR > & Anchors()
Pad object description.
void SetDirty(bool aDirty)
const std::vector< CN_ITEM * > Add(ZONE_CONTAINER *zone)
int m_tag
Tag for quick connection resolution.
void FindNearby(VECTOR2I aPosition, int aDistMax, T aFunc, LSET aLayers=LSET::AllLayersMask(), bool aDirtyOnly=false)
std::unique_ptr< POLY_GRID_PARTITION > m_cachedPoly
bool operator<(const CN_ANCHOR_PTR &a, const CN_ANCHOR_PTR &b)
BOARD_CONNECTED_ITEM * Parent() const
CN_ZONE(ZONE_CONTAINER *aParent, bool aCanChangeNet, int aSubpolyIndex)
bool HasNet() const
std::vector< CN_ANCHOR_PTR > m_anchors
int GetTag() const
Returns tag, common identifier for connected nodes.
Class BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:169
CN_ANCHOR_PTR m_source
CN_ITEM * m_item
Item owning the anchor.
int GetWeight() const
Class SHAPE_LINE_CHAIN.
void SetWeight(unsigned int weight)
size_t i
Definition: json11.cpp:597
int Size() const
CN_ITEM(BOARD_CONNECTED_ITEM *aParent, bool aCanChangeNet, int aAnchorCount=2)
static void Connect(CN_ITEM *a, CN_ITEM *b)
void SetNoLine(bool aEnable)
Decides whether this node can be a ratsnest line target.
wxPoint ShapePos() const
Definition: class_pad.cpp:500
void GetDirtyClusters(CLUSTERS &aClusters)
CONNECTED_ITEMS m_connected
list of items physically connected (touching)
CN_PAD_LIST & PadList()
bool IsDirty() const
bool CanChangeNet() const
Module description (excepted pads)
CN_ANCHOR_PTR GetSourceNode() const
std::shared_ptr< CN_ANCHOR > CN_ANCHOR_PTR
Class POLY_GRID_PARTITION.
std::vector< CN_CLUSTER_PTR > CLUSTERS
std::shared_ptr< CN_CLUSTER > GetCluster() const
const VECTOR2I GetSourcePos() const
bool Dirty() const
bool m_noline
Whether it the node can be a target for ratsnest lines.
int Size() const
const VECTOR2I & Pos() const
CN_ANCHORS m_anchors
CN_ITEM * Add(D_PAD *pad)
const BOX2I & BBox() const