KiCad PCB EDA Suite
pns_joint.h
Go to the documentation of this file.
1 /*
2  * KiRouter - a push-and-(sometimes-)shove PCB router
3  *
4  * Copyright (C) 2013-2014 CERN
5  * Copyright (C) 2016 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 modify it
9  * under the terms of the GNU General Public License as published by the
10  * Free Software Foundation, either version 3 of the License, or (at your
11  * option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License along
19  * with this program. If not, see <http://www.gnu.org/licenses/>.
20  */
21 
22 #ifndef __PNS_JOINT_H
23 #define __PNS_JOINT_H
24 
25 #include <vector>
26 
27 #include <math/vector2d.h>
28 
29 #include "pns_item.h"
30 #include "pns_segment.h"
31 #include "pns_itemset.h"
32 
33 namespace PNS {
34 
43 class JOINT : public ITEM
44 {
45 public:
47 
50  struct HASH_TAG
51  {
53  int net;
54  };
55 
57  {
58  std::size_t operator()( const JOINT::HASH_TAG& aP ) const
59  {
60  using std::size_t;
61  using std::hash;
62  using std::string;
63 
64  return ( (hash<int>()( aP.pos.x )
65  ^ (hash<int>()( aP.pos.y ) << 1) ) >> 1 )
66  ^ (hash<int>()( aP.net ) << 1);
67  }
68  };
69 
70  JOINT() :
71  ITEM( JOINT_T ), m_locked( false ) {}
72 
73  JOINT( const VECTOR2I& aPos, const LAYER_RANGE& aLayers, int aNet = -1 ) :
74  ITEM( JOINT_T )
75  {
76  m_tag.pos = aPos;
77  m_tag.net = aNet;
78  m_layers = aLayers;
79  m_locked = false;
80  }
81 
82  JOINT( const JOINT& aB ) :
83  ITEM( JOINT_T )
84  {
85  m_layers = aB.m_layers;
86  m_tag.pos = aB.m_tag.pos;
87  m_tag.net = aB.m_tag.net;
89  m_layers = aB.m_layers;
90  m_locked = aB.m_locked;
91  }
92 
93  ITEM* Clone( ) const override
94  {
95  assert( false );
96  return NULL;
97  }
98 
101  bool IsLineCorner() const
102  {
103  if( m_linkedItems.Size() != 2 || m_linkedItems.Count( SEGMENT_T | ARC_T ) != 2 )
104  return false;
105 
106  auto seg1 = static_cast<LINKED_ITEM*>( m_linkedItems[0] );
107  auto seg2 = static_cast<LINKED_ITEM*>( m_linkedItems[1] );
108 
109  // joints between segments of different widths are not considered trivial.
110  return seg1->Width() == seg2->Width();
111  }
112 
113  bool IsNonFanoutVia() const
114  {
115  int vias = m_linkedItems.Count( VIA_T );
116  int segs = m_linkedItems.Count( SEGMENT_T );
117  segs += m_linkedItems.Count( ARC_T );
118 
119  return ( m_linkedItems.Size() == 3 && vias == 1 && segs == 2 );
120  }
121 
122  bool IsStitchingVia() const
123  {
124  return ( m_linkedItems.Size() == 1 && m_linkedItems.Count( VIA_T ) == 1 );
125  }
126 
127  bool IsTraceWidthChange() const
128  {
129  if( m_linkedItems.Size() != 2 )
130  return false;
131 
132  if( m_linkedItems.Count( SEGMENT_T ) != 2)
133  return false;
134 
135  SEGMENT* seg1 = static_cast<SEGMENT*>( m_linkedItems[0] );
136  SEGMENT* seg2 = static_cast<SEGMENT*>( m_linkedItems[1] );
137 
138  return seg1->Width() != seg2->Width();
139  }
140 
142  void Link( ITEM* aItem )
143  {
144  if( m_linkedItems.Contains( aItem ) )
145  return;
146 
147  m_linkedItems.Add( aItem );
148  }
149 
152  bool Unlink( ITEM* aItem )
153  {
154  m_linkedItems.Erase( aItem );
155  return m_linkedItems.Size() == 0;
156  }
157 
160  LINKED_ITEM* NextSegment( ITEM* aCurrent ) const
161  {
162  if( !IsLineCorner() )
163  return NULL;
164 
165  return static_cast<LINKED_ITEM*>( m_linkedItems[m_linkedItems[0] == aCurrent ? 1 : 0] );
166  }
167 
168  VIA* Via()
169  {
170  for( ITEM* item : m_linkedItems.Items() )
171  {
172  if( item->OfKind( VIA_T ) )
173  return static_cast<VIA*>( item );
174  }
175 
176  return NULL;
177  }
178 
179 
181  const HASH_TAG& Tag() const
182  {
183  return m_tag;
184  }
185 
186  const VECTOR2I& Pos() const
187  {
188  return m_tag.pos;
189  }
190 
191  int Net() const
192  {
193  return m_tag.net;
194  }
195 
196  const LINKED_ITEMS& LinkList() const
197  {
198  return m_linkedItems.CItems();
199  }
200 
201  const ITEM_SET& CLinks() const
202  {
203  return m_linkedItems;
204  }
205 
207  {
208  return m_linkedItems;
209  }
210 
211  int LinkCount( int aMask = -1 ) const
212  {
213  return m_linkedItems.Count( aMask );
214  }
215 
216  void Dump() const;
217 
218  bool operator==( const JOINT& rhs ) const
219  {
220  return m_tag.pos == rhs.m_tag.pos && m_tag.net == rhs.m_tag.net;
221  }
222 
223  void Merge( const JOINT& aJoint )
224  {
225  if( !Overlaps( aJoint ) )
226  return;
227 
228  m_layers.Merge( aJoint.m_layers );
229 
230  if( aJoint.IsLocked() )
231  m_locked = true;
232 
233  for( ITEM* item : aJoint.LinkList() )
234  {
235  m_linkedItems.Add( item );
236  }
237  }
238 
239  bool Overlaps( const JOINT& rhs ) const
240  {
241  return m_tag.pos == rhs.m_tag.pos &&
242  m_tag.net == rhs.m_tag.net && m_layers.Overlaps( rhs.m_layers );
243  }
244 
245  void Lock( bool aLock = true )
246  {
247  m_locked = aLock;
248  }
249 
250  bool IsLocked() const
251  {
252  return m_locked;
253  }
254 
255 private:
258 
261 
263  bool m_locked;
264 };
265 
266 inline bool operator==( JOINT::HASH_TAG const& aP1, JOINT::HASH_TAG const& aP2 )
267 {
268  return aP1.pos == aP2.pos && aP1.net == aP2.net;
269 }
270 
271 }
272 
273 #endif // __PNS_JOINT_H
ITEM.
Definition: pns_item.h:53
int Count(int aKindMask=-1) const
Definition: pns_itemset.h:119
bool IsTraceWidthChange() const
Definition: pns_joint.h:127
bool Contains(ITEM *aItem) const
Definition: pns_itemset.h:193
bool Unlink(ITEM *aItem)
Unlinks a given board item from the joint (upon its removal from a NODE) Returns true if the joint be...
Definition: pns_joint.h:152
int Width() const override
Definition: pns_segment.h:78
LINKED_ITEM * NextSegment(ITEM *aCurrent) const
For trivial joints, returns the segment adjacent to (aCurrent).
Definition: pns_joint.h:160
ENTRIES & Items()
Definition: pns_itemset.h:140
bool IsLocked() const
Definition: pns_joint.h:250
bool Overlaps(const LAYER_RANGE &aOther) const
Definition: pns_layerset.h:68
LAYER_RANGE m_layers
Definition: pns_item.h:253
ITEM_SET m_linkedItems
list of items linked to this joint
Definition: pns_joint.h:260
void Lock(bool aLock=true)
Definition: pns_joint.h:245
std::vector< ENTRY > ENTRIES
Definition: pns_itemset.h:96
int Size() const
Definition: pns_itemset.h:165
void Erase(ITEM *aItem)
Definition: pns_itemset.h:199
int Net() const
Definition: pns_joint.h:191
void Add(const LINE &aLine)
Definition: pns_itemset.cpp:32
ITEM_SET & Links()
Definition: pns_joint.h:206
Joints are hashed by their position, layers and net.
Definition: pns_joint.h:50
JOINT(const VECTOR2I &aPos, const LAYER_RANGE &aLayers, int aNet=-1)
Definition: pns_joint.h:73
JOINT.
Definition: pns_joint.h:43
bool m_locked
locked (non-movable) flag
Definition: pns_joint.h:263
bool IsLineCorner() const
Returns true if the joint is a trivial line corner, connecting two segments of the same net,...
Definition: pns_joint.h:101
#define NULL
void Merge(const LAYER_RANGE &aOther)
Definition: pns_layerset.h:93
const HASH_TAG & Tag() const
trivial accessors
Definition: pns_joint.h:181
ITEM_SET::ENTRIES LINKED_ITEMS
Definition: pns_joint.h:46
const LINKED_ITEMS & LinkList() const
Definition: pns_joint.h:196
const ITEM_SET & CLinks() const
Definition: pns_joint.h:201
bool operator==(JOINT::HASH_TAG const &aP1, JOINT::HASH_TAG const &aP2)
Definition: pns_joint.h:266
bool operator==(const JOINT &rhs) const
Definition: pns_joint.h:218
std::size_t operator()(const JOINT::HASH_TAG &aP) const
Definition: pns_joint.h:58
JOINT(const JOINT &aB)
Definition: pns_joint.h:82
VIA * Via()
Definition: pns_joint.h:168
void Dump() const
Definition: pns_node.cpp:1115
HASH_TAG m_tag
hash tag for unordered_multimap
Definition: pns_joint.h:257
bool Overlaps(const JOINT &rhs) const
Definition: pns_joint.h:239
const ENTRIES & CItems() const
Definition: pns_itemset.h:141
void Merge(const JOINT &aJoint)
Definition: pns_joint.h:223
bool IsStitchingVia() const
Definition: pns_joint.h:122
ITEM * Clone() const override
Function Clone()
Definition: pns_joint.h:93
int LinkCount(int aMask=-1) const
Definition: pns_joint.h:211
const VECTOR2I & Pos() const
Definition: pns_joint.h:186
void Link(ITEM *aItem)
Links the joint to a given board item (when it's added to the NODE)
Definition: pns_joint.h:142
Push and Shove diff pair dimensions (gap) settings dialog.
bool IsNonFanoutVia() const
Definition: pns_joint.h:113
LAYER_RANGE.
Definition: pns_layerset.h:32