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 <[email protected]>
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 <zone.h>
23 #include "pns_node.h"
24 #include "pns_item.h"
25 #include "pns_line.h"
26 #include "pns_router.h"
27 
29 
30 namespace PNS {
31 
32 bool ITEM::collideSimple( const ITEM* aOther, const NODE* aNode, bool aDifferentNetsOnly ) const
33 {
34  const ROUTER_IFACE* iface = ROUTER::GetInstance()->GetInterface();
35  const SHAPE* shapeA = Shape();
36  const SHAPE* holeA = Hole();
37  int lineWidthA = 0;
38  const SHAPE* shapeB = aOther->Shape();
39  const SHAPE* holeB = aOther->Hole();
40  int lineWidthB = 0;
41 
42  // Sadly collision routines ignore SHAPE_POLY_LINE widths so we have to pass them in as part
43  // of the clearance value.
44  if( m_kind == LINE_T )
45  lineWidthA = static_cast<const LINE*>( this )->Width() / 2;
46 
47  if( aOther->m_kind == LINE_T )
48  lineWidthB = static_cast<const LINE*>( aOther )->Width() / 2;
49 
50  // same nets? no collision!
51  if( aDifferentNetsOnly && m_net == aOther->m_net && m_net >= 0 && aOther->m_net >= 0 )
52  return false;
53 
54  // check if we are not on completely different layers first
55  if( !m_layers.Overlaps( aOther->m_layers ) )
56  return false;
57 
58  auto checkKeepout =
59  []( const ZONE* aKeepout, const BOARD_ITEM* aOther )
60  {
61  constexpr KICAD_T TRACK_TYPES[] = { PCB_ARC_T, PCB_TRACE_T, EOT };
62 
63  if( aKeepout->GetDoNotAllowTracks() && aOther->IsType( TRACK_TYPES ) )
64  return true;
65 
66  if( aKeepout->GetDoNotAllowVias() && aOther->Type() == PCB_VIA_T )
67  return true;
68 
69  if( aKeepout->GetDoNotAllowPads() && aOther->Type() == PCB_PAD_T )
70  return true;
71 
72  // Incomplete test, but better than nothing:
73  if( aKeepout->GetDoNotAllowFootprints() && aOther->Type() == PCB_PAD_T )
74  {
75  return !aKeepout->GetParentFootprint()
76  || aKeepout->GetParentFootprint() != aOther->GetParentFootprint();
77  }
78 
79  return false;
80  };
81 
82  const ZONE* zoneA = dynamic_cast<ZONE*>( Parent() );
83  const ZONE* zoneB = dynamic_cast<ZONE*>( aOther->Parent() );
84 
85  if( zoneA && aOther->Parent() && !checkKeepout( zoneA, aOther->Parent() ) )
86  return false;
87 
88  if( zoneB && Parent() && !checkKeepout( zoneB, Parent() ) )
89  return false;
90 
91  if( holeA || holeB )
92  {
93  int holeClearance = aNode->GetHoleClearance( this, aOther );
94 
95  if( holeA && holeA->Collide( shapeB, holeClearance + lineWidthB ) )
96  {
97  Mark( Marker() | MK_HOLE );
98  return true;
99  }
100 
101  if( holeB && holeB->Collide( shapeA, holeClearance + lineWidthA ) )
102  {
103  aOther->Mark( aOther->Marker() | MK_HOLE );
104  return true;
105  }
106 
107  if( holeA && holeB )
108  {
109  int holeToHoleClearance = aNode->GetHoleToHoleClearance( this, aOther );
110 
111  if( holeA->Collide( holeB, holeToHoleClearance ) )
112  {
113  Mark( Marker() | MK_HOLE );
114  aOther->Mark( aOther->Marker() | MK_HOLE );
115  return true;
116  }
117  }
118  }
119 
120  if( !aOther->Layers().IsMultilayer() && !iface->IsFlashedOnLayer( this, aOther->Layer()) )
121  return false;
122 
123  if( !Layers().IsMultilayer() && !iface->IsFlashedOnLayer( aOther, Layer()) )
124  return false;
125 
126  int clearance = aNode->GetClearance( this, aOther );
127  return shapeA->Collide( shapeB, clearance + lineWidthA + lineWidthB );
128 }
129 
130 
131 bool ITEM::Collide( const ITEM* aOther, const NODE* aNode, bool aDifferentNetsOnly ) const
132 {
133  if( collideSimple( aOther, aNode, aDifferentNetsOnly ) )
134  return true;
135 
136  // Special cases for "head" lines with vias attached at the end. Note that this does not
137  // support head-line-via to head-line-via collisions, but you can't route two independent
138  // tracks at once so it shouldn't come up.
139 
140  if( m_kind == LINE_T )
141  {
142  const LINE* line = static_cast<const LINE*>( this );
143 
144  if( line->EndsWithVia() && line->Via().collideSimple( aOther, aNode, aDifferentNetsOnly ) )
145  return true;
146  }
147 
148  if( aOther->m_kind == LINE_T )
149  {
150  const LINE* line = static_cast<const LINE*>( aOther );
151 
152  if( line->EndsWithVia() && line->Via().collideSimple( this, aNode, aDifferentNetsOnly ) )
153  return true;
154  }
155 
156  return false;
157 }
158 
159 
160 std::string ITEM::KindStr() const
161 {
162  switch( m_kind )
163  {
164  case ARC_T: return "arc";
165  case LINE_T: return "line";
166  case SEGMENT_T: return "segment";
167  case VIA_T: return "via";
168  case JOINT_T: return "joint";
169  case SOLID_T: return "solid";
170  case DIFF_PAIR_T: return "diff-pair";
171  default: return "unknown";
172  }
173 }
174 
175 
177 {
178 }
179 
180 }
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:205
virtual int Layer() const
Definition: pns_item.h:158
Keep the router "world" - i.e.
Definition: pns_node.h:148
bool GetDoNotAllowFootprints() const
Definition: zone.h:740
virtual void Mark(int aMarker) const
Definition: pns_item.h:210
int GetHoleToHoleClearance(const ITEM *aA, const ITEM *aB, bool aUseClearanceEpsilon=true) const
Return the pre-set worst case clearance between any pair of items.
Definition: pns_node.cpp:126
int GetClearance(const ITEM *aA, const ITEM *aB, bool aUseClearanceEpsilon=true) const
Definition: pns_node.cpp:102
virtual ~ITEM()
Definition: pns_item.cpp:176
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:49
bool IsMultilayer() const
Definition: pns_layerset.h:77
bool GetDoNotAllowVias() const
Definition: zone.h:737
class PCB_ARC, an arc track segment on a copper layer
Definition: typeinfo.h:97
bool Overlaps(const LAYER_RANGE &aOther) const
Definition: pns_layerset.h:67
LAYER_RANGE m_layers
Definition: pns_item.h:251
BOARD_ITEM * Parent() const
Definition: pns_item.h:149
class PAD, a pad in a footprint
Definition: typeinfo.h:89
Represents a track on a PCB, connecting two non-trivial joints (that is, vias, pads,...
Definition: pns_line.h:60
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
int GetHoleClearance(const ITEM *aA, const ITEM *aB, bool aUseClearanceEpsilon=true) const
Definition: pns_node.cpp:114
search types array terminator (End Of Types)
Definition: typeinfo.h:81
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition: typeinfo.h:77
bool EndsWithVia() const
Definition: pns_line.h:191
class PCB_TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:95
VECTOR2I::extended_type ecoord
Definition: pns_item.cpp:28
std::string KindStr() const
Returns the kind of the item, as string.
Definition: pns_item.cpp:160
bool GetDoNotAllowPads() const
Definition: zone.h:739
virtual const SHAPE * Shape() const
Return the geometrical shape of the item.
Definition: pns_item.h:200
bool GetDoNotAllowTracks() const
Definition: zone.h:738
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:131
Handle a list of polygons defining a copper zone.
Definition: zone.h:56
An abstract shape on 2D plane.
Definition: shape.h:116
int m_net
Definition: pns_item.h:254
virtual bool IsFlashedOnLayer(const PNS::ITEM *aItem, int aLayer) const =0
PnsKind m_kind
Definition: pns_item.h:247
class PCB_VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:96
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:208
static ROUTER * GetInstance()
Definition: pns_router.cpp:78
const LAYER_RANGE & Layers() const
Definition: pns_item.h:154
virtual int Marker() const
Definition: pns_item.h:212
bool collideSimple(const ITEM *aOther, const NODE *aNode, bool aDifferentNetsOnly) const
Definition: pns_item.cpp:32
BOARD_ITEM_CONTAINER * GetParentFootprint() const
Definition: board_item.cpp:191