KiCad PCB EDA Suite
Loading...
Searching...
No Matches
pcad_pad.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2007, 2008 Lubo Racko <[email protected]>
5 * Copyright (C) 2007, 2008, 2012-2013 Alexander Lunev <[email protected]>
6 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 */
21
22#include <pcad/pcad_pad.h>
23#include <pcad/pcad_pad_shape.h>
24
25#include <board.h>
26#include <footprint.h>
27#include <pad.h>
28#include <pcb_track.h>
29#include <trigo.h>
30#include <xnode.h>
31
32#include <wx/string.h>
33
34namespace PCAD2KICAD {
35
36
37PCAD_PAD::PCAD_PAD( PCAD_CALLBACKS* aCallbacks, BOARD* aBoard ) :
38 PCAD_PCB_COMPONENT( aCallbacks, aBoard )
39{
40 m_ObjType = wxT( 'P' );
41 m_Number = 0;
42 m_Hole = 0;
43 m_IsHolePlated = true;
44 m_defaultPinDes = wxEmptyString;
45}
46
47
49{
50 int i;
51
52 for( i = 0; i < (int) m_Shapes.GetCount(); i++ )
53 delete m_Shapes[i];
54}
55
56
57void PCAD_PAD::Parse( XNODE* aNode, const wxString& aDefaultUnits,
58 const wxString& aActualConversion )
59{
60 XNODE* lNode;
61 XNODE* cNode;
62 long num;
63 wxString propValue, str, emsg;
64 PCAD_PAD_SHAPE* padShape;
65
67 lNode = FindNode( aNode, wxT( "padNum" ) );
68
69 if( lNode )
70 {
71 lNode->GetNodeContent().ToLong( &num );
72 m_Number = (int) num;
73 }
74
75 lNode = FindNode( aNode, wxT( "padStyleRef" ) );
76
77 if( lNode )
78 {
79 lNode->GetAttribute( wxT( "Name" ), &propValue );
80 propValue.Trim( false );
81 m_Name.text = propValue;
82 }
83
84 lNode = FindNode( aNode, wxT( "pt" ) );
85
86 if( lNode )
87 {
88 SetPosition( lNode->GetNodeContent(), aDefaultUnits, &m_PositionX, &m_PositionY,
89 aActualConversion );
90 }
91
92 lNode = FindNode( aNode, wxT( "rotation" ) );
93
94 if( lNode )
95 {
96 str = lNode->GetNodeContent();
97 str.Trim( false );
99 }
100
101 lNode = FindNode( aNode, wxT( "netNameRef" ) );
102
103 if( lNode )
104 {
105 lNode->GetAttribute( wxT( "Name" ), &propValue );
106 propValue.Trim( false );
107 propValue.Trim( true );
108 m_Net = propValue;
110 }
111
112 lNode = FindNode( aNode, wxT( "defaultPinDes" ) );
113
114 if( lNode )
115 {
116 lNode->GetAttribute( wxT( "Name" ), &propValue );
117
118 //propValue.Trim( false );
119 m_defaultPinDes = propValue;
120 }
121
122 lNode = aNode;
123
124 while( lNode && lNode->GetName() != wxT( "www.lura.sk" ) )
125 lNode = lNode->GetParent();
126
127 lNode = FindNode( lNode, wxT( "library" ) );
128
129 if ( !lNode )
130 THROW_IO_ERROR( wxT( "Unable to find library section" ) );
131
132 lNode = FindNode( lNode, wxT( "padStyleDef" ) );
133
134 while( lNode )
135 {
136 lNode->GetAttribute( wxT( "Name" ), &propValue );
137
138 if( propValue.IsSameAs( m_Name.text, false) )
139 break;
140
141 lNode = lNode->GetNext();
142 }
143
144 if ( !lNode )
145 THROW_IO_ERROR( wxString::Format( wxT( "Unable to find padStyleDef " ) + m_Name.text ) );
146
147 cNode = FindNode( lNode, wxT( "holeDiam" ) );
148
149 if( cNode )
150 SetWidth( cNode->GetNodeContent(), aDefaultUnits, &m_Hole, aActualConversion );
151
152 if( FindNodeGetContent( lNode, wxT( "isHolePlated" ) ).IsSameAs( wxT( "False" ), false ) )
153 m_IsHolePlated = false;
154
155 cNode = FindNode( lNode, wxT( "padShape" ) );
156
157 while( cNode )
158 {
159 if( cNode->GetName().IsSameAs( wxT( "padShape" ), false ) )
160 {
161 // we support only Pads on specific layers......
162 // we do not support pads on "Plane", "NonSignal" , "Signal" ... layerr
163 if( FindNode( cNode, wxT( "layerNumRef" ) ) )
164 {
165 padShape = new PCAD_PAD_SHAPE( m_callbacks, m_board );
166 padShape->Parse( cNode, aDefaultUnits, aActualConversion );
167 m_Shapes.Add( padShape );
168 }
169 }
170
171 cNode = cNode->GetNext();
172 }
173}
174
175
177{
178 int i;
179
181
182 if( m_ObjType == wxT( 'P' ) )
184
185 for( i = 0; i < (int)m_Shapes.GetCount(); i++ )
186 m_Shapes[i]->m_KiCadLayer = m_board->FlipLayer( m_Shapes[i]->m_KiCadLayer );
187}
188
189
190void PCAD_PAD::AddToFootprint( FOOTPRINT* aFootprint, const EDA_ANGLE& aRotation,
191 bool aEncapsulatedPad )
192{
193 PCAD_PAD_SHAPE* padShape;
194 wxString padShapeName = wxT( "Ellipse" );
195 PAD_ATTRIB padType;
196 int i;
197 int width = 0;
198 int height = 0;
199
200 PAD* pad = new PAD( aFootprint );
201
202 if( !m_IsHolePlated && m_Hole )
203 {
204 // mechanical hole
206 pad->SetAttribute( PAD_ATTRIB::NPTH );
207
208 pad->SetDrillShape( PAD_DRILL_SHAPE::CIRCLE );
209 pad->SetDrillSize( VECTOR2I( m_Hole, m_Hole ) );
211
212 // Mounting Hole: Solder Mask Margin from Top Layer Width size.
213 // Used the default zone clearance (simplify)
214 if( m_Shapes.GetCount() && m_Shapes[0]->m_Shape.IsSameAs( wxT( "MtHole" ), false ) )
215 {
216 int sm_margin = ( m_Shapes[0]->m_Width - m_Hole ) / 2;
217 pad->SetLocalSolderMaskMargin( sm_margin );
218 pad->SetLocalClearance( sm_margin + pcbIUScale.mmToIU( 0.254 ) );
219 }
220
221 pad->SetLayerSet( LSET::AllCuMask() | LSET( { B_Mask, F_Mask } ) );
222 }
223 else
224 {
225 ( m_Hole ) ? padType = PAD_ATTRIB::PTH : padType = PAD_ATTRIB::SMD;
226
227 // form layer mask
228 for( i = 0; i < (int) m_Shapes.GetCount(); i++ )
229 {
230 padShape = m_Shapes[i];
231
232 if( padShape->m_Width > 0 && padShape->m_Height > 0 )
233 {
234 if( padShape->m_KiCadLayer == F_Cu ||
235 padShape->m_KiCadLayer == B_Cu )
236 {
237 padShapeName = padShape->m_Shape;
238 width = padShape->m_Width;
239 height = padShape->m_Height;
240
241 // assume this is SMD pad
242 if( padShape->m_KiCadLayer == F_Cu )
243 pad->SetLayerSet( LSET( { F_Cu, F_Paste, F_Mask } ) );
244 else
245 pad->SetLayerSet( LSET( { B_Cu, B_Paste, B_Mask } ) );
246
247 break;
248 }
249 }
250 }
251
252 if( width == 0 || height == 0 )
253 {
254 delete pad;
255 return;
256 }
257
258 if( padType == PAD_ATTRIB::PTH )
259 // actually this is a thru-hole pad
260 pad->SetLayerSet( LSET::AllCuMask() | LSET( { B_Mask, F_Mask } ) );
261
262 pad->SetNumber( m_Name.text );
263
264 if( padShapeName.IsSameAs( wxT( "Oval" ), false )
265 || padShapeName.IsSameAs( wxT( "Ellipse" ), false )
266 || padShapeName.IsSameAs( wxT( "MtHole" ), false ) )
267 {
268 if( width != height )
270 else
272 }
273 else if( padShapeName.IsSameAs( wxT( "Rect" ), false ) )
274 {
276 }
277 else if( padShapeName.IsSameAs( wxT( "RndRect" ), false ) )
278 {
280 }
281 else if( padShapeName.IsSameAs( wxT( "Polygon" ), false ) )
282 {
283 pad->SetShape( PADSTACK::ALL_LAYERS, PAD_SHAPE::RECTANGLE ); // approximation
284 }
285
286 pad->SetSize( PADSTACK::ALL_LAYERS, VECTOR2I( width, height ) );
287 pad->SetDelta( PADSTACK::ALL_LAYERS, VECTOR2I( 0, 0 ) );
288 pad->SetOrientation( m_Rotation + aRotation );
289
290 pad->SetDrillShape( PAD_DRILL_SHAPE::CIRCLE );
291 pad->SetOffset( PADSTACK::ALL_LAYERS, VECTOR2I( 0, 0 ) );
292 pad->SetDrillSize( VECTOR2I( m_Hole, m_Hole ) );
293
294 pad->SetAttribute( padType );
295
296 // Set the proper net code
297 NETINFO_ITEM* netinfo = m_board->FindNet( m_Net );
298
299 if( netinfo == nullptr ) // I believe this should not happen, but just in case
300 {
301 // It is a new net
302 netinfo = new NETINFO_ITEM( m_board, m_Net );
303 m_board->Add( netinfo );
304 }
305
306 pad->SetNetCode( netinfo->GetNetCode() );
307 }
308
309 if( !aEncapsulatedPad )
310 {
312 RotatePoint( padpos, aFootprint->GetOrientation() );
313 pad->SetPosition( padpos + aFootprint->GetPosition() );
314 }
315
316 aFootprint->Add( pad );
317}
318
319
321{
322 PCAD_PAD_SHAPE* padShape;
323 int i;
324 int width = 0;
325 int height = 0;
326
327 if( m_ObjType == wxT( 'V' ) ) // via
328 {
329 // choose one of the shapes
330 for( i = 0; i < (int) m_Shapes.GetCount(); i++ )
331 {
332 padShape = m_Shapes[i];
333
334 if( padShape->m_Width > 0 && padShape->m_Height > 0 )
335 {
336 if( padShape->m_KiCadLayer == F_Cu
337 || padShape->m_KiCadLayer == B_Cu )
338 {
339 width = padShape->m_Width;
340 height = padShape->m_Height;
341
342 break;
343 }
344 }
345 }
346
347 if( width == 0 || height == 0 )
348 return;
349
351 {
352 PCB_VIA* via = new PCB_VIA( m_board );
353 m_board->Add( via );
354
355 via->SetPosition( VECTOR2I( m_PositionX, m_PositionY ) );
356 via->SetEnd( VECTOR2I( m_PositionX, m_PositionY ) );
357
358 via->SetWidth( PADSTACK::ALL_LAYERS, height );
359 via->SetViaType( VIATYPE::THROUGH );
360 via->SetLayerPair( F_Cu, B_Cu );
361 via->SetDrill( m_Hole );
362
363 via->SetLayer( m_KiCadLayer );
364 via->SetNetCode( m_NetCode );
365 }
366 }
367 else // pad
368 {
369 if( !aFootprint )
370 {
371 aFootprint = new FOOTPRINT( m_board );
372 m_board->Add( aFootprint, ADD_MODE::APPEND );
373 aFootprint->SetPosition( VECTOR2I( m_PositionX, m_PositionY ) );
374 }
375
376 m_Name.text = m_defaultPinDes;
377
378 AddToFootprint( aFootprint, ANGLE_0, true );
379 }
380}
381
382} // namespace PCAD2KICAD
constexpr EDA_IU_SCALE pcbIUScale
Definition base_units.h:121
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:372
void SetPosition(const VECTOR2I &aPos) override
EDA_ANGLE GetOrientation() const
Definition footprint.h:406
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
VECTOR2I GetPosition() const override
Definition footprint.h:403
LSET is a set of PCB_LAYER_IDs.
Definition lset.h:37
static LSET AllCuMask(int aCuLayerCount)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition lset.cpp:595
Handle the data for a net.
Definition netinfo.h:46
int GetNetCode() const
Definition netinfo.h:94
static constexpr PCB_LAYER_ID ALL_LAYERS
! Temporary layer identifier to identify code that is not padstack-aware
Definition padstack.h:177
Definition pad.h:61
virtual void Parse(XNODE *aNode, const wxString &aDefaultUnits, const wxString &aActualConversion)
void AddToFootprint(FOOTPRINT *aFootprint, const EDA_ANGLE &aRotation, bool aEncapsulatedPad)
Definition pcad_pad.cpp:190
PCAD_PAD_SHAPES_ARRAY m_Shapes
Definition pcad_pad.h:53
PCAD_PAD(PCAD_CALLBACKS *aCallbacks, BOARD *aBoard)
Definition pcad_pad.cpp:37
void AddToBoard(FOOTPRINT *aFootprint=nullptr) override
Definition pcad_pad.cpp:320
virtual void Flip() override
Definition pcad_pad.cpp:176
wxString m_defaultPinDes
Definition pcad_pad.h:56
virtual void Parse(XNODE *aNode, const wxString &aDefaultUnits, const wxString &aActualConversion)
Definition pcad_pad.cpp:57
int GetNetCode(const wxString &aNetName) const
PCAD_PCB_COMPONENT(PCAD_CALLBACKS *aCallbacks, BOARD *aBoard)
An extension of wxXmlNode that can format its contents as KiCad-style s-expressions.
Definition xnode.h:67
XNODE * GetParent() const
Definition xnode.h:107
XNODE * GetNext() const
Definition xnode.h:102
static constexpr EDA_ANGLE ANGLE_0
Definition eda_angle.h:411
@ TENTHS_OF_A_DEGREE_T
Definition eda_angle.h:30
#define THROW_IO_ERROR(msg)
macro which captures the "call site" values of FILE_, __FUNCTION & LINE
bool IsCopperLayer(int aLayerId)
Test whether a layer is a copper layer.
Definition layer_ids.h:675
@ F_Paste
Definition layer_ids.h:100
@ B_Mask
Definition layer_ids.h:94
@ B_Cu
Definition layer_ids.h:61
@ F_Mask
Definition layer_ids.h:93
@ B_Paste
Definition layer_ids.h:101
@ F_Cu
Definition layer_ids.h:60
int StrToInt1Units(const wxString &aStr)
void SetWidth(const wxString &aStr, const wxString &aDefaultMeasurementUnit, int *aWidth, const wxString &aActualConversion)
XNODE * FindNode(XNODE *aChild, const wxString &aTag)
void SetPosition(const wxString &aStr, const wxString &aDefaultMeasurementUnit, int *aX, int *aY, const wxString &aActualConversion)
wxString FindNodeGetContent(XNODE *aChild, const wxString &aTag)
PAD_ATTRIB
The set of pad shapes, used with PAD::{Set,Get}Attribute().
Definition padstack.h:97
@ NPTH
like PAD_PTH, but not plated mechanical use only, no connection allowed
Definition padstack.h:103
@ SMD
Smd pad, appears on the solder paste layer (default)
Definition padstack.h:99
@ PTH
Plated through hole pad.
Definition padstack.h:98
@ ROUNDRECT
Definition padstack.h:57
@ RECTANGLE
Definition padstack.h:54
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.
Definition trigo.cpp:225
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683