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_rtree.h>
47 #include <connectivity_data.h>
48 
49 class CN_ITEM;
50 class CN_CONNECTIVITY_ALGO_IMPL;
51 class CN_RATSNEST_NODES;
52 class CN_CLUSTER;
53 class BOARD;
55 class BOARD_ITEM;
56 class ZONE_CONTAINER;
57 class PROGRESS_REPORTER;
58 
59 class CN_ANCHOR
60 {
61 public:
63  {
64  m_item = nullptr;
65  }
66 
67  CN_ANCHOR( const VECTOR2I& aPos, CN_ITEM* aItem )
68  {
69  m_pos = aPos;
70  m_item = aItem;
71  assert( m_item );
72  }
73 
74  bool Valid() const;
75 
76 
77  CN_ITEM* Item() const
78  {
79  return m_item;
80  }
81 
83 
84  const VECTOR2I& Pos() const
85  {
86  return m_pos;
87  }
88 
89  bool IsDirty() const;
90 
92  inline int GetTag() const
93  {
94  return m_tag;
95  }
96 
98  inline void SetTag( int aTag )
99  {
100  m_tag = aTag;
101  }
102 
104  inline void SetNoLine( bool aEnable )
105  {
106  m_noline = aEnable;
107  }
108 
110  inline const bool& GetNoLine() const
111  {
112  return m_noline;
113  }
114 
115  inline void SetCluster( std::shared_ptr<CN_CLUSTER> aCluster )
116  {
117  m_cluster = aCluster;
118  }
119 
120  inline std::shared_ptr<CN_CLUSTER> GetCluster() const
121  {
122  return m_cluster;
123  }
124 
133  bool IsDangling() const;
134 
135  // Tag used for unconnected items.
136  static const int TAG_UNCONNECTED = -1;
137 
138 private:
141 
143  CN_ITEM* m_item = nullptr;
144 
146  int m_tag = -1;
147 
149  bool m_noline = false;
150 
152  std::shared_ptr<CN_CLUSTER> m_cluster;
153 };
154 
155 
156 typedef std::shared_ptr<CN_ANCHOR> CN_ANCHOR_PTR;
157 typedef std::vector<CN_ANCHOR_PTR> CN_ANCHORS;
158 
159 
160 class CN_EDGE
161 {
162 public:
163  CN_EDGE() {};
164  CN_EDGE( CN_ANCHOR_PTR aSource, CN_ANCHOR_PTR aTarget, int aWeight = 0 ) :
165  m_source( aSource ),
166  m_target( aTarget ),
167  m_weight( aWeight ) {}
168 
169  CN_ANCHOR_PTR GetSourceNode() const { return m_source; }
170  CN_ANCHOR_PTR GetTargetNode() const { return m_target; }
171  int GetWeight() const { return m_weight; }
172 
173  void SetSourceNode( const CN_ANCHOR_PTR& aNode ) { m_source = aNode; }
174  void SetTargetNode( const CN_ANCHOR_PTR& aNode ) { m_target = aNode; }
175  void SetWeight( unsigned int weight ) { m_weight = weight; }
176 
177  void SetVisible( bool aVisible )
178  {
179  m_visible = aVisible;
180  }
181 
182  bool IsVisible() const
183  {
184  return m_visible;
185  }
186 
187  const VECTOR2I GetSourcePos() const
188  {
189  return m_source->Pos();
190  }
191 
192  const VECTOR2I GetTargetPos() const
193  {
194  return m_target->Pos();
195  }
196 
197 private:
200  unsigned int m_weight = 0;
201  bool m_visible = true;
202 };
203 
204 
206 {
207 private:
208 
209  bool m_conflicting = false;
210  int m_originNet = 0;
211  CN_ITEM* m_originPad = nullptr;
212  std::vector<CN_ITEM*> m_items;
213 
214 public:
215  CN_CLUSTER();
216  ~CN_CLUSTER();
217 
218  bool HasValidNet() const
219  {
220  return m_originNet >= 0;
221  }
222 
223  int OriginNet() const
224  {
225  return m_originNet;
226  }
227 
228  wxString OriginNetName() const;
229 
230  bool Contains( const CN_ITEM* aItem );
231  bool Contains( const BOARD_CONNECTED_ITEM* aItem );
232  void Dump();
233 
234  int Size() const
235  {
236  return m_items.size();
237  }
238 
239  bool HasNet() const
240  {
241  return m_originNet >= 0;
242  }
243 
244  bool IsOrphaned() const
245  {
246  return m_originPad == nullptr;
247  }
248 
249  bool IsConflicting() const
250  {
251  return m_conflicting;
252  }
253 
254  void Add( CN_ITEM* item );
255 
256  using ITER = decltype(m_items)::iterator;
257 
258  ITER begin() { return m_items.begin(); };
259  ITER end() { return m_items.end(); };
260 };
261 
262 typedef std::shared_ptr<CN_CLUSTER> CN_CLUSTER_PTR;
263 
264 
265 // basic connectivity item
266 class CN_ITEM : public INTRUSIVE_LIST<CN_ITEM>
267 {
268 private:
270 
271  using CONNECTED_ITEMS = std::vector<CN_ITEM*>;
272 
275 
277 
279  bool m_visited;
280 
283 
285  bool m_valid;
286 
287 protected:
289  bool m_dirty;
290 
293 
294 public:
295  void Dump();
296 
297  CN_ITEM( BOARD_CONNECTED_ITEM* aParent, bool aCanChangeNet, int aAnchorCount = 2 )
298  {
299  m_parent = aParent;
300  m_canChangeNet = aCanChangeNet;
301  m_visited = false;
302  m_valid = true;
303  m_dirty = true;
304  m_anchors.reserve( 2 );
305  }
306 
307  virtual ~CN_ITEM() {};
308 
309  void AddAnchor( const VECTOR2I& aPos )
310  {
311  m_anchors.emplace_back( std::make_unique<CN_ANCHOR>( aPos, this ) );
312  }
313 
315  {
316  return m_anchors;
317  }
318 
319  void SetValid( bool aValid )
320  {
321  m_valid = aValid;
322  }
323 
324  bool Valid() const
325  {
326  return m_valid;
327  }
328 
329  void SetDirty( bool aDirty )
330  {
331  m_dirty = aDirty;
332  }
333 
334  bool Dirty() const
335  {
336  return m_dirty;
337  }
338 
339  const BOX2I BBox()
340  {
341  if( m_dirty )
342  {
343  EDA_RECT box = m_parent->GetBoundingBox();
344  m_bbox = BOX2I( box.GetPosition(), box.GetSize() );
345  }
346  return m_bbox;
347  }
348 
350  {
351  return m_parent;
352  }
353 
355  {
356  return m_connected;
357  }
358 
360  {
361  m_connected.clear();
362  }
363 
364  void SetVisited( bool aVisited )
365  {
366  m_visited = aVisited;
367  }
368 
369  bool Visited() const
370  {
371  return m_visited;
372  }
373 
374  bool CanChangeNet() const
375  {
376  return m_canChangeNet;
377  }
378 
379  static void Connect( CN_ITEM* a, CN_ITEM* b )
380  {
381  bool foundA = false, foundB = false;
382 
383  for( auto item : a->m_connected )
384  {
385  if( item == b )
386  {
387  foundA = true;
388  break;
389  }
390  }
391 
392  for( auto item : b->m_connected )
393  {
394  if( item == a )
395  {
396  foundB = true;
397  break;
398  }
399  }
400 
401  if( !foundA )
402  a->m_connected.push_back( b );
403 
404  if( !foundB )
405  b->m_connected.push_back( a );
406  }
407 
408  void RemoveInvalidRefs();
409 
410  virtual int AnchorCount() const;
411  virtual const VECTOR2I GetAnchor( int n ) const;
412 
413  int Net() const;
414 };
415 
416 typedef std::shared_ptr<CN_ITEM> CN_ITEM_PTR;
417 
418 
419 class CN_LIST
420 {
421 private:
422  bool m_dirty;
424 
426 
427 protected:
428  std::vector<CN_ITEM*> m_items;
429 
430  void addItemtoTree( CN_ITEM* item )
431  {
432  m_index.Insert( item );
433  }
434 
435 public:
437  {
438  m_dirty = false;
439  m_hasInvalid = false;
440  }
441 
442  void Clear()
443  {
444  for( auto item : m_items )
445  delete item;
446 
447  m_items.clear();
448  m_index.RemoveAll();
449  }
450 
451  using ITER = decltype(m_items)::iterator;
452 
453  ITER begin() { return m_items.begin(); };
454  ITER end() { return m_items.end(); };
455 
456  CN_ITEM* operator[] ( int aIndex ) { return m_items[aIndex]; }
457 
458  template <class T>
459  void FindNearby( CN_ITEM *aItem, T aFunc );
460 
461  void SetHasInvalid( bool aInvalid = true )
462  {
463  m_hasInvalid = aInvalid;
464  }
465 
466  void SetDirty( bool aDirty = true )
467  {
468  m_dirty = aDirty;
469  }
470 
471  bool IsDirty() const
472  {
473  return m_dirty;
474  }
475 
476  void RemoveInvalidItems( std::vector<CN_ITEM*>& aGarbage );
477 
479  {
480  for( auto item : m_items )
481  item->SetDirty( false );
482 
483  SetDirty( false );
484  }
485 
487  {
488  for( auto item : m_items )
489  item->SetDirty( true );
490 
491  SetDirty( true );
492  }
493 
494  int Size() const
495  {
496  return m_items.size();
497  }
498 
499  CN_ITEM* Add( D_PAD* pad )
500  {
501  auto item = new CN_ITEM( pad, false, 2 );
502  item->AddAnchor( pad->ShapePos() );
503  addItemtoTree( item );
504  m_items.push_back( item );
505  SetDirty();
506  return item;
507  }
508 
509  CN_ITEM* Add( TRACK* track )
510  {
511  auto item = new CN_ITEM( track, true );
512  m_items.push_back( item );
513  item->AddAnchor( track->GetStart() );
514  item->AddAnchor( track->GetEnd() );
515  addItemtoTree( item );
516  SetDirty();
517  return item;
518  }
519 
520  CN_ITEM* Add( VIA* via )
521  {
522  auto item = new CN_ITEM( via, true );
523 
524  m_items.push_back( item );
525  item->AddAnchor( via->GetStart() );
526  addItemtoTree( item );
527  SetDirty();
528  return item;
529  }
530 };
531 
532 
533 class CN_ZONE : public CN_ITEM
534 {
535 public:
536  CN_ZONE( ZONE_CONTAINER* aParent, bool aCanChangeNet, int aSubpolyIndex ) :
537  CN_ITEM( aParent, aCanChangeNet ),
538  m_subpolyIndex( aSubpolyIndex )
539  {
540  SHAPE_LINE_CHAIN outline = aParent->GetFilledPolysList().COutline( aSubpolyIndex );
541 
542  outline.SetClosed( true );
543  outline.Simplify();
544 
545  m_cachedPoly.reset( new POLY_GRID_PARTITION( outline, 16 ) );
546  }
547 
548  int SubpolyIndex() const
549  {
550  return m_subpolyIndex;
551  }
552 
553  bool ContainsAnchor( const CN_ANCHOR_PTR anchor ) const
554  {
555  return ContainsPoint( anchor->Pos() );
556  }
557 
558  bool ContainsPoint( const VECTOR2I p ) const
559  {
560  auto zone = static_cast<ZONE_CONTAINER*> ( Parent() );
561  return m_cachedPoly->ContainsPoint( p, zone->GetMinThickness() );
562  }
563 
564  const BOX2I& BBox()
565  {
566  if( m_dirty )
567  m_bbox = m_cachedPoly->BBox();
568 
569  return m_bbox;
570  }
571 
572  virtual int AnchorCount() const override;
573  virtual const VECTOR2I GetAnchor( int n ) const override;
574 
575 private:
576  std::vector<VECTOR2I> m_testOutlinePoints;
577  std::unique_ptr<POLY_GRID_PARTITION> m_cachedPoly;
579 };
580 
581 
582 class CN_ZONE_LIST : public CN_LIST
583 {
584 public:
586 
587  const std::vector<CN_ITEM*> Add( ZONE_CONTAINER* zone )
588  {
589  const auto& polys = zone->GetFilledPolysList();
590 
591  std::vector<CN_ITEM*> rv;
592 
593  for( int j = 0; j < polys.OutlineCount(); j++ )
594  {
595  CN_ZONE* zitem = new CN_ZONE( zone, false, j );
596  const auto& outline = zone->GetFilledPolysList().COutline( j );
597 
598  for( int k = 0; k < outline.PointCount(); k++ )
599  zitem->AddAnchor( outline.CPoint( k ) );
600 
601  m_items.push_back( zitem );
602  addItemtoTree( zitem );
603  rv.push_back( zitem );
604  SetDirty();
605  }
606 
607  return rv;
608  }
609 
610  template <class T>
611  void FindNearbyZones( BOX2I aBBox, T aFunc, bool aDirtyOnly = false );
612 };
613 
614 
615 template <class T>
616 void CN_ZONE_LIST::FindNearbyZones( BOX2I aBBox, T aFunc, bool aDirtyOnly )
617 {
618  for( auto item : m_items )
619  {
620  auto zone = static_cast<CN_ZONE*>( item );
621 
622  if( aBBox.Intersects( zone->BBox() ) )
623  {
624  if( !aDirtyOnly || zone->Dirty() )
625  {
626  aFunc( zone );
627  }
628  }
629  }
630 }
631 
632 template <class T>
633 void CN_LIST::FindNearby( CN_ITEM *aItem, T aFunc )
634 {
635  m_index.Query( aItem->BBox(), aFunc );
636 }
637 
639 {
640 public:
642  {
645  CSM_RATSNEST
646  };
647 
648  using CLUSTERS = std::vector<CN_CLUSTER_PTR>;
649 
650 private:
651 
653  {
654 public:
655  ITEM_MAP_ENTRY( CN_ITEM* aItem = nullptr )
656  {
657  if( aItem )
658  m_items.push_back( aItem );
659  }
660 
662  {
663  for( auto item : m_items )
664  {
665  item->SetValid( false );
666  }
667  }
668 
669  void Link( CN_ITEM* aItem )
670  {
671  m_items.push_back( aItem );
672  }
673 
674  const std::list<CN_ITEM*> GetItems() const
675  {
676  return m_items;
677  }
678 
679  std::list<CN_ITEM*> m_items;
680  };
681 
682  std::mutex m_listLock;
685 
686  using ITEM_MAP_PAIR = std::pair <const BOARD_CONNECTED_ITEM*, ITEM_MAP_ENTRY>;
687 
688  std::unordered_map<const BOARD_CONNECTED_ITEM*, ITEM_MAP_ENTRY> m_itemMap;
689 
692  std::vector<bool> m_dirtyNets;
693  PROGRESS_REPORTER* m_progressReporter = nullptr;
694 
695  void searchConnections();
696 
697  void update();
698  void propagateConnections();
699 
700  template <class Container, class BItem>
701  void add( Container& c, BItem brditem )
702  {
703  auto item = c.Add( brditem );
704 
705  m_itemMap[ brditem ] = ITEM_MAP_ENTRY( item );
706  }
707 
708  bool addConnectedItem( BOARD_CONNECTED_ITEM* aItem );
709  bool isDirty() const;
710 
711  void markItemNetAsDirty( const BOARD_ITEM* aItem );
712 
713 public:
714 
717 
718  bool ItemExists( const BOARD_CONNECTED_ITEM* aItem )
719  {
720  return m_itemMap.find( aItem ) != m_itemMap.end();
721  }
722 
724  {
725  return m_itemMap[ aItem ];
726  }
727 
728  bool IsNetDirty( int aNet ) const
729  {
730  if( aNet < 0 )
731  return false;
732 
733  return m_dirtyNets[ aNet ];
734  }
735 
737  {
738  for( auto i = m_dirtyNets.begin(); i != m_dirtyNets.end(); ++i )
739  *i = false;
740  }
741 
742  void GetDirtyClusters( CLUSTERS& aClusters )
743  {
744  for( auto cl : m_ratsnestClusters )
745  {
746  int net = cl->OriginNet();
747 
748  if( net >= 0 && m_dirtyNets[net] )
749  aClusters.push_back( cl );
750  }
751  }
752 
753  int NetCount() const
754  {
755  return m_dirtyNets.size();
756  }
757 
758  void Build( BOARD* aBoard );
759  void Build( const std::vector<BOARD_ITEM*>& aItems );
760 
761  void Clear();
762 
763  bool Remove( BOARD_ITEM* aItem );
764  bool Add( BOARD_ITEM* aItem );
765 
766  const CLUSTERS SearchClusters( CLUSTER_SEARCH_MODE aMode, const KICAD_T aTypes[], int aSingleNet );
767  const CLUSTERS SearchClusters( CLUSTER_SEARCH_MODE aMode );
768 
769  void PropagateNets();
770  void FindIsolatedCopperIslands( ZONE_CONTAINER* aZone, std::vector<int>& aIslands );
771 
778  void FindIsolatedCopperIslands( std::vector<CN_ZONE_ISOLATED_ISLAND_LIST>& aZones );
779 
780  bool CheckConnectivity( std::vector<CN_DISJOINT_NET_ENTRY>& aReport );
781 
782  const CLUSTERS& GetClusters();
783  int GetUnconnectedCount();
784 
785  CN_LIST& ItemList() { return m_itemList; }
786 
787  void ForEachAnchor( const std::function<void( CN_ANCHOR& )>& aFunc );
788  void ForEachItem( const std::function<void( CN_ITEM& )>& aFunc );
789 
790  void MarkNetAsDirty( int aNet );
791  void SetProgressReporter( PROGRESS_REPORTER* aReporter );
792 
793 };
794 
795 bool operator<( const CN_ANCHOR_PTR& a, const CN_ANCHOR_PTR& b );
796 
797 
801 class CN_VISITOR {
802 
803 public:
804 
805  CN_VISITOR( CN_ITEM* aItem, std::mutex* aListLock ) :
806  m_item( aItem ),
807  m_listLock( aListLock )
808  {}
809 
810  bool operator()( CN_ITEM* aCandidate );
811 
812 protected:
813 
814  void checkZoneItemConnection( CN_ZONE* aZone, CN_ITEM* aItem );
815 
816  void checkZoneZoneConnection( CN_ZONE* aZoneA, CN_ZONE* aZoneB );
817 
820 
822  std::mutex* m_listLock;
823 
824 };
825 
826 #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)
virtual const EDA_RECT GetBoundingBox() const
Function GetBoundingBox returns the orthogonal, bounding box of this object for display purposes...
BOX2< VECTOR2I > BOX2I
Definition: box2.h:468
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)
void SetHasInvalid(bool aInvalid=true)
bool Valid() const
CN_ITEM * Add(TRACK *track)
Class BOARD_ITEM is a base class for any item which can be embedded within the BOARD container class...
const wxSize GetSize() const
Definition: eda_rect.h:101
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
bool IsDirty() const
Class BOARD to handle a board.
std::vector< CN_ANCHOR_PTR > CN_ANCHORS
void addItemtoTree(CN_ITEM *item)
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
const BOX2I & BBox()
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)
const BOX2I BBox()
void SetCluster(std::shared_ptr< CN_CLUSTER > aCluster)
CN_ANCHORS & Anchors()
void Insert(T aItem)
Function Insert() Inserts an item into the tree.
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)
void RemoveAll()
Function RemoveAll() Removes all items from the RTree.
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
CN_ITEM * Add(VIA *via)
void MarkAllAsDirty()
bool ContainsPoint(const VECTOR2I p) const
VECTOR2I m_pos
Position of the anchor.
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::mutex * m_listLock
the mutex protecting our connection list
std::vector< CN_ITEM * > m_items
void SetClosed(bool aClosed)
Function SetClosed()
bool m_visited
visited flag for the BFS scan
CN_ITEM * Add(D_PAD *pad)
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
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
CN_VISITOR(CN_ITEM *aItem, std::mutex *aListLock)
std::shared_ptr< CN_ITEM > CN_ITEM_PTR
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
virtual ~CN_ITEM()
std::shared_ptr< CN_CLUSTER > CN_CLUSTER_PTR
BOX2I m_bbox
bounding box for the item
void SetVisible(bool aVisible)
void SetTag(int aTag)
Sets tag, common identifier for connected nodes.
const CONNECTED_ITEMS & ConnectedItems() const
bool IsOrphaned() const
bool m_canChangeNet
can the net propagator modify the netcode?
const SHAPE_POLY_SET & GetFilledPolysList() const
Function GetFilledPolysList returns a reference to the list of filled polygons.
Definition: class_zone.h:534
const wxPoint GetPosition() const
Definition: eda_rect.h:113
Pad object description.
void SetDirty(bool aDirty)
const std::vector< CN_ITEM * > Add(ZONE_CONTAINER *zone)
int m_tag
Tag for quick connection resolution.
std::unique_ptr< POLY_GRID_PARTITION > m_cachedPoly
void AddAnchor(const VECTOR2I &aPos)
void FindNearby(CN_ITEM *aItem, T aFunc)
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
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.
Struct CN_VISTOR.
int GetWeight() const
Class SHAPE_LINE_CHAIN.
void SetWeight(unsigned int weight)
size_t i
Definition: json11.cpp:597
int Size() const
Class EDA_RECT handles the component boundary box.
Definition: eda_rect.h:44
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)
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.
CN_ITEM * m_item
the item we are looking for connections to
std::vector< CN_CLUSTER_PTR > CLUSTERS
void Query(const BOX2I &aBounds, Visitor &aVisitor)
Function Query() Executes a function object aVisitor for each item whose bounding box intersects with...
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_RTREE< CN_ITEM * > m_index
CN_ANCHORS m_anchors