KiCad PCB EDA Suite
pns_item.cpp
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-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 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 #include "pns_node.h"
23 #include "pns_item.h"
24 #include "pns_line.h"
25 #include "pns_router.h"
26 
28 
29 namespace PNS {
30 
31 bool ITEM::collideSimple( const ITEM* aOther, const NODE* aNode, bool aDifferentNetsOnly ) const
32 {
33  const ROUTER_IFACE* iface = ROUTER::GetInstance()->GetInterface();
34  const SHAPE* shapeA = Shape();
35  const SHAPE* holeA = Hole();
36  int lineWidthA = 0;
37  const SHAPE* shapeB = aOther->Shape();
38  const SHAPE* holeB = aOther->Hole();
39  int lineWidthB = 0;
40 
41  // Sadly collision routines ignore SHAPE_POLY_LINE widths so we have to pass them in as part
42  // of the clearance value.
43  if( m_kind == LINE_T )
44  lineWidthA = static_cast<const LINE*>( this )->Width() / 2;
45 
46  if( aOther->m_kind == LINE_T )
47  lineWidthB = static_cast<const LINE*>( aOther )->Width() / 2;
48 
49  // same nets? no collision!
50  if( aDifferentNetsOnly && m_net == aOther->m_net && m_net >= 0 && aOther->m_net >= 0 )
51  return false;
52 
53  // check if we are not on completely different layers first
54  if( !m_layers.Overlaps( aOther->m_layers ) )
55  return false;
56 
57  if( holeA || holeB )
58  {
59  int holeClearance = aNode->GetHoleClearance( this, aOther );
60 
61  if( holeA && holeA->Collide( shapeB, holeClearance + lineWidthB ) )
62  {
63  Mark( Marker() | MK_HOLE );
64  return true;
65  }
66 
67  if( holeB && holeB->Collide( shapeA, holeClearance + lineWidthA ) )
68  {
69  aOther->Mark( aOther->Marker() | MK_HOLE );
70  return true;
71  }
72 
73  if( holeA && holeB )
74  {
75  int holeToHoleClearance = aNode->GetHoleToHoleClearance( this, aOther );
76 
77  if( holeA->Collide( holeB, holeToHoleClearance ) )
78  {
79  Mark( Marker() | MK_HOLE );
80  aOther->Mark( aOther->Marker() | MK_HOLE );
81  return true;
82  }
83  }
84  }
85 
86  if( !aOther->Layers().IsMultilayer() && !iface->IsFlashedOnLayer( this, aOther->Layer()) )
87  return false;
88 
89  if( !Layers().IsMultilayer() && !iface->IsFlashedOnLayer( aOther, Layer()) )
90  return false;
91 
92  int clearance = aNode->GetClearance( this, aOther );
93  return shapeA->Collide( shapeB, clearance + lineWidthA + lineWidthB );
94 }
95 
96 
97 bool ITEM::Collide( const ITEM* aOther, const NODE* aNode, bool aDifferentNetsOnly ) const
98 {
99  if( collideSimple( aOther, aNode, aDifferentNetsOnly ) )
100  return true;
101 
102  // Special cases for "head" lines with vias attached at the end. Note that this does not
103  // support head-line-via to head-line-via collisions, but you can't route two independent
104  // tracks at once so it shouldn't come up.
105 
106  if( m_kind == LINE_T )
107  {
108  const LINE* line = static_cast<const LINE*>( this );
109 
110  if( line->EndsWithVia() && line->Via().collideSimple( aOther, aNode, aDifferentNetsOnly ) )
111  return true;
112  }
113 
114  if( aOther->m_kind == LINE_T )
115  {
116  const LINE* line = static_cast<const LINE*>( aOther );
117 
118  if( line->EndsWithVia() && line->Via().collideSimple( this, aNode, aDifferentNetsOnly ) )
119  return true;
120  }
121 
122  return false;
123 }
124 
125 
126 std::string ITEM::KindStr() const
127 {
128  switch( m_kind )
129  {
130  case ARC_T: return "arc";
131  case LINE_T: return "line";
132  case SEGMENT_T: return "segment";
133  case VIA_T: return "via";
134  case JOINT_T: return "joint";
135  case SOLID_T: return "solid";
136  case DIFF_PAIR_T: return "diff-pair";
137  default: return "unknown";
138  }
139 }
140 
141 
143 {
144 }
145 
146 }
VECTOR2_TRAITS< int >::extended_type extended_type
Definition: vector2d.h:76
Base class for PNS router board items.
Definition: pns_item.h:55
virtual const SHAPE * Hole() const
Definition: pns_item.h:203
virtual int Layer() const
Definition: pns_item.h:156
Keep the router "world" - i.e.
Definition: pns_node.h:144
virtual void Mark(int aMarker) const
Definition: pns_item.h:208
int GetHoleToHoleClearance(const ITEM *aA, const ITEM *aB) const
Return the pre-set worst case clearance between any pair of items.
Definition: pns_node.cpp:125
virtual ~ITEM()
Definition: pns_item.cpp:142
bool IsMultilayer() const
Definition: pns_layerset.h:77
bool Overlaps(const LAYER_RANGE &aOther) const
Definition: pns_layerset.h:67
LAYER_RANGE m_layers
Definition: pns_item.h:246
Represents a track on a PCB, connecting two non-trivial joints (that is, vias, pads,...
Definition: pns_line.h:60
int GetHoleClearance(const ITEM *aA, const ITEM *aB) const
Definition: pns_node.cpp:113
virtual bool Collide(const VECTOR2I &aP, int aClearance=0, int *aActual=nullptr, VECTOR2I *aLocation=nullptr) const
Check if the boundary of shape (this) lies closer to the point aP than aClearance,...
Definition: shape.h:165
bool EndsWithVia() const
Definition: pns_line.h:191
VECTOR2I::extended_type ecoord
Definition: pns_item.cpp:27
std::string KindStr() const
Returns the kind of the item, as string.
Definition: pns_item.cpp:126
int GetClearance(const ITEM *aA, const ITEM *aB) const
Definition: pns_node.cpp:101
virtual const SHAPE * Shape() const
Return the geometrical shape of the item.
Definition: pns_item.h:198
bool Collide(const ITEM *aOther, const NODE *aNode, bool aDifferentNetsOnly=true) const
Check for a collision (clearance violation) with between us and item aOther.
Definition: pns_item.cpp:97
An abstract shape on 2D plane.
Definition: shape.h:116
int m_net
Definition: pns_item.h:249
virtual bool IsFlashedOnLayer(const PNS::ITEM *aItem, int aLayer) const =0
PnsKind m_kind
Definition: pns_item.h:242
const VIA & Via() const
Definition: pns_line.h:196
Push and Shove diff pair dimensions (gap) settings dialog.
ROUTER_IFACE * GetInterface() const
Definition: pns_router.h:207
static ROUTER * GetInstance()
Definition: pns_router.cpp:78
const LAYER_RANGE & Layers() const
Definition: pns_item.h:152
virtual int Marker() const
Definition: pns_item.h:210
bool collideSimple(const ITEM *aOther, const NODE *aNode, bool aDifferentNetsOnly) const
Definition: pns_item.cpp:31