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 #include <boost/functional/hash.hpp>
27 
28 #include <math/vector2d.h>
29 
30 #include "pns_item.h"
31 #include "pns_segment.h"
32 #include "pns_itemset.h"
33 
34 namespace PNS {
35 
44 class JOINT : public ITEM
45 {
46 public:
48 
51  struct HASH_TAG
52  {
54  int net;
55  };
56 
57  JOINT() :
58  ITEM( JOINT_T ), m_locked( false ) {}
59 
60  JOINT( const VECTOR2I& aPos, const LAYER_RANGE& aLayers, int aNet = -1 ) :
61  ITEM( JOINT_T )
62  {
63  m_tag.pos = aPos;
64  m_tag.net = aNet;
65  m_layers = aLayers;
66  m_locked = false;
67  }
68 
69  JOINT( const JOINT& aB ) :
70  ITEM( JOINT_T )
71  {
72  m_layers = aB.m_layers;
73  m_tag.pos = aB.m_tag.pos;
74  m_tag.net = aB.m_tag.net;
76  m_layers = aB.m_layers;
77  m_locked = aB.m_locked;
78  }
79 
80  ITEM* Clone( ) const override
81  {
82  assert( false );
83  return NULL;
84  }
85 
88  bool IsLineCorner() const
89  {
90  if( m_linkedItems.Size() != 2 || m_linkedItems.Count( SEGMENT_T ) != 2 )
91  return false;
92 
93  SEGMENT* seg1 = static_cast<SEGMENT*>( m_linkedItems[0] );
94  SEGMENT* seg2 = static_cast<SEGMENT*>( m_linkedItems[1] );
95 
96  // joints between segments of different widths are not considered trivial.
97  return seg1->Width() == seg2->Width();
98  }
99 
100  bool IsNonFanoutVia() const
101  {
102  int vias = m_linkedItems.Count( VIA_T );
103  int segs = m_linkedItems.Count( SEGMENT_T );
104 
105  return ( m_linkedItems.Size() == 3 && vias == 1 && segs == 2 );
106  }
107 
108  bool IsTraceWidthChange() const
109  {
110  if( m_linkedItems.Size() != 2 )
111  return false;
112 
113  if( m_linkedItems.Count( SEGMENT_T ) != 2)
114  return false;
115 
116  SEGMENT* seg1 = static_cast<SEGMENT*>( m_linkedItems[0] );
117  SEGMENT* seg2 = static_cast<SEGMENT*>( m_linkedItems[1] );
118 
119  return seg1->Width() != seg2->Width();
120  }
121 
123  void Link( ITEM* aItem )
124  {
125  if( m_linkedItems.Contains( aItem ) )
126  return;
127 
128  m_linkedItems.Add( aItem );
129  }
130 
133  bool Unlink( ITEM* aItem )
134  {
135  m_linkedItems.Erase( aItem );
136  return m_linkedItems.Size() == 0;
137  }
138 
141  SEGMENT* NextSegment( SEGMENT* aCurrent ) const
142  {
143  if( !IsLineCorner() )
144  return NULL;
145 
146  return static_cast<SEGMENT*>( m_linkedItems[m_linkedItems[0] == aCurrent ? 1 : 0] );
147  }
148 
149  VIA* Via()
150  {
151  for( ITEM* item : m_linkedItems.Items() )
152  {
153  if( item->OfKind( VIA_T ) )
154  return static_cast<VIA*>( item );
155  }
156 
157  return NULL;
158  }
159 
160 
162  const HASH_TAG& Tag() const
163  {
164  return m_tag;
165  }
166 
167  const VECTOR2I& Pos() const
168  {
169  return m_tag.pos;
170  }
171 
172  int Net() const
173  {
174  return m_tag.net;
175  }
176 
177  const LINKED_ITEMS& LinkList() const
178  {
179  return m_linkedItems.CItems();
180  }
181 
182  const ITEM_SET& CLinks() const
183  {
184  return m_linkedItems;
185  }
186 
188  {
189  return m_linkedItems;
190  }
191 
192  int LinkCount( int aMask = -1 ) const
193  {
194  return m_linkedItems.Count( aMask );
195  }
196 
197  void Dump() const;
198 
199  bool operator==( const JOINT& rhs ) const
200  {
201  return m_tag.pos == rhs.m_tag.pos && m_tag.net == rhs.m_tag.net;
202  }
203 
204  void Merge( const JOINT& aJoint )
205  {
206  if( !Overlaps( aJoint ) )
207  return;
208 
209  m_layers.Merge( aJoint.m_layers );
210 
211  if( aJoint.IsLocked() )
212  m_locked = true;
213 
214  for( ITEM* item : aJoint.LinkList() )
215  {
216  m_linkedItems.Add( item );
217  }
218  }
219 
220  bool Overlaps( const JOINT& rhs ) const
221  {
222  return m_tag.pos == rhs.m_tag.pos &&
223  m_tag.net == rhs.m_tag.net && m_layers.Overlaps( rhs.m_layers );
224  }
225 
226  void Lock( bool aLock = true )
227  {
228  m_locked = aLock;
229  }
230 
231  bool IsLocked() const
232  {
233  return m_locked;
234  }
235 
236 private:
239 
242 
244  bool m_locked;
245 };
246 
247 inline bool operator==( JOINT::HASH_TAG const& aP1, JOINT::HASH_TAG const& aP2 )
248 {
249  return aP1.pos == aP2.pos && aP1.net == aP2.net;
250 }
251 
252 inline std::size_t hash_value( JOINT::HASH_TAG const& aP )
253 {
254  std::size_t seed = 0;
255  boost::hash_combine( seed, aP.pos.x );
256  boost::hash_combine( seed, aP.pos.y );
257  boost::hash_combine( seed, aP.net );
258 
259  return seed;
260 }
261 
262 }
263 
264 #endif // __PNS_JOINT_H
Class ITEM.
Definition: pns_item.h:53
const ITEM_SET & CLinks() const
Definition: pns_joint.h:182
bool IsLineCorner() const
Returns true if the joint is a trivial line corner, connecting two segments of the same net...
Definition: pns_joint.h:88
const ENTRIES & CItems() const
Definition: pns_itemset.h:138
bool Overlaps(const JOINT &rhs) const
Definition: pns_joint.h:220
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:133
bool IsTraceWidthChange() const
Definition: pns_joint.h:108
ENTRIES & Items()
Definition: pns_itemset.h:137
LAYER_RANGE m_layers
Definition: pns_item.h:350
ITEM_SET m_linkedItems
list of items linked to this joint
Definition: pns_joint.h:241
void Lock(bool aLock=true)
Definition: pns_joint.h:226
std::vector< ENTRY > ENTRIES
Definition: pns_itemset.h:96
void Erase(ITEM *aItem)
Definition: pns_itemset.h:196
void Add(const LINE &aLine)
Definition: pns_itemset.cpp:32
std::size_t hash_value(JOINT::HASH_TAG const &aP)
Definition: pns_joint.h:252
ITEM_SET & Links()
Definition: pns_joint.h:187
Joints are hashed by their position, layers and net.
Definition: pns_joint.h:51
JOINT(const VECTOR2I &aPos, const LAYER_RANGE &aLayers, int aNet=-1)
Definition: pns_joint.h:60
Class JOINT.
Definition: pns_joint.h:44
bool m_locked
locked (non-movable) flag
Definition: pns_joint.h:244
bool IsNonFanoutVia() const
Definition: pns_joint.h:100
int LinkCount(int aMask=-1) const
Definition: pns_joint.h:192
void Merge(const LAYER_RANGE &aOther)
Definition: pns_layerset.h:93
void Dump() const
Definition: pns_node.cpp:1056
SEGMENT * NextSegment(SEGMENT *aCurrent) const
For trivial joints, returns the segment adjacent to (aCurrent).
Definition: pns_joint.h:141
bool Contains(ITEM *aItem) const
Definition: pns_itemset.h:190
bool IsLocked() const
Definition: pns_joint.h:231
int Width() const
Definition: pns_segment.h:88
ITEM_SET::ENTRIES LINKED_ITEMS
Definition: pns_joint.h:47
bool Overlaps(const LAYER_RANGE &aOther) const
Definition: pns_layerset.h:68
bool operator==(JOINT::HASH_TAG const &aP1, JOINT::HASH_TAG const &aP2)
Definition: pns_joint.h:247
JOINT(const JOINT &aB)
Definition: pns_joint.h:69
VIA * Via()
Definition: pns_joint.h:149
HASH_TAG m_tag
hash tag for unordered_multimap
Definition: pns_joint.h:238
const VECTOR2I & Pos() const
Definition: pns_joint.h:167
bool operator==(const JOINT &rhs) const
Definition: pns_joint.h:199
void Merge(const JOINT &aJoint)
Definition: pns_joint.h:204
const HASH_TAG & Tag() const
trivial accessors
Definition: pns_joint.h:162
ITEM * Clone() const override
Function Clone()
Definition: pns_joint.h:80
int Size() const
Definition: pns_itemset.h:162
void Link(ITEM *aItem)
Links the joint to a given board item (when it's added to the NODE)
Definition: pns_joint.h:123
const LINKED_ITEMS & LinkList() const
Definition: pns_joint.h:177
int Net() const
Definition: pns_joint.h:172
Push and Shove diff pair dimensions (gap) settings dialog.
int Count(int aKindMask=-1) const
Definition: pns_itemset.h:119
Class LAYER_RANGE.
Definition: pns_layerset.h:32