KiCad PCB EDA Suite
pns_via.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 "pns_via.h"
23#include "pns_node.h"
24#include "pns_utils.h"
25#include "pns_router.h"
26
27#include <geometry/shape_rect.h>
28#include <math/box2.h>
29
30namespace PNS {
31
32bool VIA::PushoutForce( NODE* aNode, const ITEM* aOther, VECTOR2I& aForce )
33{
34 int clearance = aNode->GetClearance( this, aOther );
35 VECTOR2I elementForces[4], force;
36 size_t nf = 0;
37
39 {
40 int holeClearance = aNode->GetHoleClearance( this, aOther );
41 int hole2holeClearance = aNode->GetHoleToHoleClearance( this, aOther );
42
43 if( aOther->Hole() )
44 {
45 aOther->Hole()->Collide( Shape(), holeClearance, &elementForces[nf++] );
46 aOther->Hole()->Collide( Hole(), hole2holeClearance, &elementForces[nf++] );
47 }
48
49 aOther->Shape()->Collide( Hole(), holeClearance, &elementForces[nf++] );
50 }
51
52 aOther->Shape()->Collide( Shape(), clearance, &elementForces[nf++] );
53
54 for( size_t i = 0; i < nf; i++ )
55 {
56 if( elementForces[i].SquaredEuclideanNorm() > force.SquaredEuclideanNorm() )
57 force = elementForces[i];
58 }
59
60 aForce = force;
61
62 return ( force != VECTOR2I( 0, 0 ) );
63}
64
65bool VIA::PushoutForce( NODE* aNode, const VECTOR2I& aDirection, VECTOR2I& aForce,
66 bool aSolidsOnly, int aMaxIterations )
67{
68 int iter = 0;
69 VIA mv( *this );
70 VECTOR2I totalForce;
71
72
73 while( iter < aMaxIterations )
74 {
75 NODE::OPT_OBSTACLE obs = aNode->CheckColliding( &mv, aSolidsOnly ? ITEM::SOLID_T
76 : ITEM::ANY_T );
77
78 if( !obs )
79 break;
80
81 if( iter > aMaxIterations / 2 )
82 {
83 VECTOR2I l = aDirection.Resize( m_diameter / 2 );
84 totalForce += l;
85 mv.SetPos( mv.Pos() + l );
86 }
87
88 VECTOR2I force;
89 bool collFound = PushoutForce( aNode, obs->m_item, force );
90
91 if( collFound )
92 {
93 totalForce += force;
94 mv.SetPos( mv.Pos() + force );
95 }
96
97 iter++;
98 }
99
100 if( iter == aMaxIterations )
101 return false;
102
103 aForce = totalForce;
104
105 return true;
106}
107
108
109const SHAPE_LINE_CHAIN VIA::Hull( int aClearance, int aWalkaroundThickness, int aLayer ) const
110{
111 int cl = ( aClearance + aWalkaroundThickness / 2 );
112 int width = m_diameter;
113
114 if( !ROUTER::GetInstance()->GetInterface()->IsFlashedOnLayer( this, aLayer ) )
115 width = m_hole.GetRadius() * 2;
116
117 // Chamfer = width * ( 1 - sqrt(2)/2 ) for equilateral octagon
118 return OctagonalHull( m_pos - VECTOR2I( width / 2, width / 2 ),
119 VECTOR2I( width, width ),
120 cl, ( 2 * cl + width ) * ( 1.0 - M_SQRT1_2 ) );
121}
122
123
124const SHAPE_LINE_CHAIN VIA::HoleHull( int aClearance, int aWalkaroundThickness, int aLayer ) const
125{
126 int cl = ( aClearance + aWalkaroundThickness / 2 );
127 int width = m_hole.GetRadius() * 2;
128
129 // Chamfer = width * ( 1 - sqrt(2)/2 ) for equilateral octagon
130 return OctagonalHull( m_pos - VECTOR2I( width / 2, width / 2 ), VECTOR2I( width, width ), cl,
131 ( 2 * cl + width ) * ( 1.0 - M_SQRT1_2 ) );
132}
133
134
136{
137 VIA* v = new VIA();
138
139 v->SetNet( Net() );
140 v->SetLayers( Layers() );
141 v->m_pos = m_pos;
143 v->m_drill = m_drill;
145 v->m_hole = SHAPE_CIRCLE( m_pos, m_drill / 2 );
146 v->m_rank = m_rank;
147 v->m_marker = m_marker;
148 v->m_viaType = m_viaType;
149 v->m_parent = m_parent;
150 v->m_isFree = m_isFree;
152
153 return v;
154}
155
156
157OPT_BOX2I VIA::ChangedArea( const VIA* aOther ) const
158{
159 if ( aOther->Pos() != Pos() )
160 {
161 BOX2I tmp = Shape()->BBox();
162 tmp.Merge( aOther->Shape()->BBox() );
163 return tmp;
164 }
165
166 return OPT_BOX2I();
167}
168
170{
171 VIA_HANDLE h;
172 h.pos = Pos();
173 h.layers = Layers();
174 h.net = Net();
175 h.valid = true;
176 return h;
177}
178
179}
OPT< BOX2I > OPT_BOX2I
Definition: box2.h:509
BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
Definition: box2.h:363
Base class for PNS router board items.
Definition: pns_item.h:56
void SetLayers(const LAYER_RANGE &aLayers)
Definition: pns_item.h:155
bool m_isVirtual
Definition: pns_item.h:258
virtual const SHAPE * Hole() const
Definition: pns_item.h:205
void SetNet(int aNet)
Definition: pns_item.h:151
virtual const SHAPE * Shape() const
Return the geometrical shape of the item.
Definition: pns_item.h:200
@ SOLID_T
Definition: pns_item.h:63
const LAYER_RANGE & Layers() const
Definition: pns_item.h:154
int m_marker
Definition: pns_item.h:255
int Net() const
Definition: pns_item.h:152
BOARD_ITEM * m_parent
Definition: pns_item.h:249
int m_rank
Definition: pns_item.h:256
Keep the router "world" - i.e.
Definition: pns_node.h:150
COLLISION_QUERY_SCOPE GetCollisionQueryScope() const
Definition: pns_node.h:415
int GetClearance(const ITEM *aA, const ITEM *aB, bool aUseClearanceEpsilon=true) const
Definition: pns_node.cpp:103
@ CQS_ALL_RULES
check all rules
Definition: pns_node.h:156
OPT_OBSTACLE CheckColliding(const ITEM *aItem, int aKindMask=ITEM::ANY_T)
Check if the item collides with anything else in the world, and if found, returns the obstacle.
Definition: pns_node.cpp:468
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:127
OPT< OBSTACLE > OPT_OBSTACLE
Definition: pns_node.h:160
int GetHoleClearance(const ITEM *aA, const ITEM *aB, bool aUseClearanceEpsilon=true) const
Definition: pns_node.cpp:115
virtual bool IsFlashedOnLayer(const PNS::ITEM *aItem, int aLayer) const =0
ROUTER_IFACE * GetInterface() const
Definition: pns_router.h:208
static ROUTER * GetInstance()
Definition: pns_router.cpp:78
VIA()
Definition: pns_via.h:52
OPT_BOX2I ChangedArea(const VIA *aOther) const
Definition: pns_via.cpp:157
int m_drill
Definition: pns_via.h:165
const VECTOR2I & Pos() const
Definition: pns_via.h:100
const SHAPE * Shape() const override
Return the geometrical shape of the item.
Definition: pns_via.h:136
const SHAPE_LINE_CHAIN HoleHull(int aClearance=0, int aWalkaroundThickness=0, int aLayer=-1) const override
Definition: pns_via.cpp:124
const VIA_HANDLE MakeHandle() const
Definition: pns_via.cpp:169
void SetPos(const VECTOR2I &aPos)
Definition: pns_via.h:102
int m_diameter
Definition: pns_via.h:164
VIATYPE m_viaType
Definition: pns_via.h:169
bool PushoutForce(NODE *aNode, const VECTOR2I &aDirection, VECTOR2I &aForce, bool aSolidsOnly=true, int aMaxIterations=10)
Definition: pns_via.cpp:65
VECTOR2I m_pos
Definition: pns_via.h:166
const SHAPE_LINE_CHAIN Hull(int aClearance=0, int aWalkaroundThickness=0, int aLayer=-1) const override
Definition: pns_via.cpp:109
bool m_isFree
Definition: pns_via.h:170
SHAPE_CIRCLE m_hole
Definition: pns_via.h:168
const SHAPE_CIRCLE * Hole() const override
Definition: pns_via.h:138
SHAPE_CIRCLE m_shape
Definition: pns_via.h:167
VIA * Clone() const override
Return a deep copy of the item.
Definition: pns_via.cpp:135
int GetRadius() const
Definition: shape_circle.h:108
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
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:178
virtual const BOX2I BBox(int aClearance=0) const =0
Compute a bounding box of the shape, with a margin of aClearance a collision.
extended_type SquaredEuclideanNorm() const
Compute the squared euclidean norm of the vector, which is defined as (x ** 2 + y ** 2).
Definition: vector2d.h:298
VECTOR2< T > Resize(T aNewLength) const
Return a vector of the same direction, but length specified in aNewLength.
Definition: vector2d.h:367
Push and Shove diff pair dimensions (gap) settings dialog.
const SHAPE_LINE_CHAIN OctagonalHull(const VECTOR2I &aP0, const VECTOR2I &aSize, int aClearance, int aChamfer)
Definition: pns_utils.cpp:36
VECTOR2I pos
Definition: pns_via.h:44
LAYER_RANGE layers
Definition: pns_via.h:45
VECTOR2< int > VECTOR2I
Definition: vector2d.h:607