KiCad PCB EDA Suite
pcb_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 <developer@lura.sk>
5  * Copyright (C) 2007, 2008, 2012-2013 Alexander Lunev <al.lunev@yahoo.com>
6  * Copyright (C) 2012 KiCad Developers, see CHANGELOG.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, you may find one here:
20  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21  * or you may search the http://www.gnu.org website for the version 2 license,
22  * or you may write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24  */
25 
30 #include <wx/wx.h>
31 #include <wx/config.h>
32 #include <trigo.h>
33 
34 #include <pcb_pad.h>
35 
36 namespace PCAD2KICAD {
37 
38 PCB_PAD::PCB_PAD( PCB_CALLBACKS* aCallbacks, BOARD* aBoard ) : 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  {
54  delete m_shapes[i];
55  }
56 }
57 
58 
59 void PCB_PAD::Parse( XNODE* aNode,
60  const wxString& aDefaultMeasurementUnit,
61  const wxString& aActualConversion )
62 {
63  XNODE* lNode, *cNode;
64  long num;
65  wxString propValue, str, emsg;
66  PCB_PAD_SHAPE* padShape;
67 
68  m_rotation = 0;
69  lNode = FindNode( aNode, wxT( "padNum" ) );
70 
71  if( lNode )
72  {
73  lNode->GetNodeContent().ToLong( &num );
74  m_number = (int) num;
75  }
76 
77  lNode = FindNode( aNode, wxT( "padStyleRef" ) );
78 
79  if( lNode )
80  {
81  lNode->GetAttribute( wxT( "Name" ), &propValue );
82  propValue.Trim( false );
83  m_name.text = propValue;
84  }
85 
86  lNode = FindNode( aNode, wxT( "pt" ) );
87 
88  if( lNode )
89  SetPosition( lNode->GetNodeContent(), aDefaultMeasurementUnit,
90  &m_positionX, &m_positionY, aActualConversion );
91 
92  lNode = FindNode( aNode, wxT( "rotation" ) );
93 
94  if( lNode )
95  {
96  str = lNode->GetNodeContent();
97  str.Trim( false );
98  m_rotation = StrToInt1Units( str );
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  //propValue.Trim( false );
118  m_defaultPinDes = propValue;
119  }
120 
121  lNode = aNode;
122 
123  while( lNode && lNode->GetName() != wxT( "www.lura.sk" ) )
124  lNode = lNode->GetParent();
125 
126  lNode = FindNode( lNode, wxT( "library" ) );
127  if ( !lNode )
128  THROW_IO_ERROR( wxT( "Unable to find library section" ) );
129 
130  lNode = FindNode( lNode, wxT( "padStyleDef" ) );
131 
132  while( lNode )
133  {
134  lNode->GetAttribute( wxT( "Name" ), &propValue );
135 
136  if( propValue.IsSameAs( m_name.text, false) )
137  break;
138 
139  lNode = lNode->GetNext();
140  }
141 
142  if ( !lNode )
143  THROW_IO_ERROR( wxString::Format( wxT( "Unable to find padStyleDef " ) + m_name.text ) );
144 
145  cNode = FindNode( lNode, wxT( "holeDiam" ) );
146 
147  if( cNode )
148  SetWidth( cNode->GetNodeContent(), aDefaultMeasurementUnit, &m_hole, aActualConversion );
149 
150  if( FindNodeGetContent( lNode, wxT( "isHolePlated" ) ) == wxT( "False" ) )
151  m_isHolePlated = false;
152 
153  cNode = FindNode( lNode, wxT( "padShape" ) );
154 
155  while( cNode )
156  {
157  if( cNode->GetName() == wxT( "padShape" ) )
158  {
159  // we support only Pads on specific layers......
160  // we do not support pads on "Plane", "NonSignal" , "Signal" ... layerr
161  if( FindNode( cNode, wxT( "layerNumRef" ) ) )
162  {
163  padShape = new PCB_PAD_SHAPE( m_callbacks, m_board );
164  padShape->Parse( cNode, aDefaultMeasurementUnit, aActualConversion );
165  m_shapes.Add( padShape );
166  }
167  }
168 
169  cNode = cNode->GetNext();
170  }
171 }
172 
173 
175 {
176  int i;
177 
179 
180  if( m_objType == wxT( 'P' ) )
182 
183  for( i = 0; i < (int)m_shapes.GetCount(); i++ )
185 }
186 
187 
188 void PCB_PAD::AddToModule( MODULE* aModule, int aRotation, bool aEncapsulatedPad )
189 {
190  PCB_PAD_SHAPE* padShape;
191  wxString padShapeName = wxT( "Ellipse" );
192  PAD_ATTR_T padType;
193  int i;
194  int width = 0;
195  int height = 0;
196 
197  D_PAD* pad = new D_PAD( aModule );
198 
199  if( !m_isHolePlated && m_hole )
200  {
201  // mechanical hole
202  pad->SetShape( PAD_SHAPE_CIRCLE );
204 
206  pad->SetDrillSize( wxSize( m_hole, m_hole ) );
207  pad->SetSize( wxSize( m_hole, m_hole ) );
208 
209  // Mounting Hole: Solder Mask Margin from Top Layer Width size.
210  // Used the default zone clearance (simplify)
211  if( m_shapes.GetCount() && m_shapes[0]->m_shape == wxT( "MtHole" ) )
212  {
213  int sm_margin = ( m_shapes[0]->m_width - m_hole ) / 2;
214  pad->SetLocalSolderMaskMargin( sm_margin );
215  pad->SetLocalClearance( sm_margin + Millimeter2iu( 0.254 ) );
216  }
217 
218  pad->SetLayerSet( LSET::AllCuMask() | LSET( 2, B_Mask, F_Mask ) );
219  }
220  else
221  {
222  ( m_hole ) ? padType = PAD_ATTRIB_STANDARD : padType = PAD_ATTRIB_SMD;
223 
224  // form layer mask
225  for( i = 0; i < (int) m_shapes.GetCount(); i++ )
226  {
227  padShape = m_shapes[i];
228 
229  if( padShape->m_width > 0 && padShape->m_height > 0 )
230  {
231  if( padShape->m_KiCadLayer == F_Cu ||
232  padShape->m_KiCadLayer == B_Cu )
233  {
234  padShapeName = padShape->m_shape;
235  width = padShape->m_width;
236  height = padShape->m_height;
237 
238  // assume this is SMD pad
239  if( padShape->m_KiCadLayer == F_Cu )
240  pad->SetLayerSet( LSET( 3, F_Cu, F_Paste, F_Mask ) );
241  else
242  pad->SetLayerSet( LSET( 3, B_Cu, B_Paste, B_Mask ) );
243  break;
244  }
245  }
246  }
247 
248  if( width == 0 || height == 0 )
249  {
250  delete pad;
251  return;
252  }
253 
254  if( padType == PAD_ATTRIB_STANDARD )
255  // actually this is a thru-hole pad
256  pad->SetLayerSet( LSET::AllCuMask() | LSET( 2, B_Mask, F_Mask ) );
257 
258  pad->SetName( m_name.text );
259 
260  if( padShapeName == wxT( "Oval" )
261  || padShapeName == wxT( "Ellipse" )
262  || padShapeName == wxT( "MtHole" ) )
263  {
264  if( width != height )
265  pad->SetShape( PAD_SHAPE_OVAL );
266  else
267  pad->SetShape( PAD_SHAPE_CIRCLE );
268  }
269  else if( padShapeName == wxT( "Rect" )
270  || padShapeName == wxT( "RndRect" ) )
271  pad->SetShape( PAD_SHAPE_RECT );
272  else if( padShapeName == wxT( "Polygon" ) )
273  pad->SetShape( PAD_SHAPE_RECT ); // approximation
274 
275  pad->SetSize( wxSize( width, height ) );
276  pad->SetDelta( wxSize( 0, 0 ) );
277  pad->SetOrientation( m_rotation + aRotation );
278 
280  pad->SetOffset( wxPoint( 0, 0 ) );
281  pad->SetDrillSize( wxSize( m_hole, m_hole ) );
282 
283  pad->SetAttribute( padType );
284 
285  // Set the proper net code
286  NETINFO_ITEM* netinfo = m_board->FindNet( m_net );
287  if( netinfo == NULL ) // I believe this should not happen, but just in case
288  {
289  // It is a new net
290  netinfo = new NETINFO_ITEM( m_board, m_net );
291  m_board->Add( netinfo );
292  }
293 
294  pad->SetNetCode( netinfo->GetNet() );
295  }
296 
297  if( !aEncapsulatedPad )
298  {
299  // pad's "Position" is not relative to the module's,
300  // whereas Pos0 is relative to the module's but is the unrotated coordinate.
301  wxPoint padpos( m_positionX, m_positionY );
302  pad->SetPos0( padpos );
303  RotatePoint( &padpos, aModule->GetOrientation() );
304  pad->SetPosition( padpos + aModule->GetPosition() );
305  }
306 
307  aModule->PadsList().PushBack( pad );
308 }
309 
310 
312 {
313  PCB_PAD_SHAPE* padShape;
314  int i;
315  int width = 0;
316  int height = 0;
317 
318  if( m_objType == wxT( 'V' ) ) // via
319  {
320  // choose one of the shapes
321  for( i = 0; i < (int) m_shapes.GetCount(); i++ )
322  {
323  padShape = m_shapes[i];
324 
325  if( padShape->m_width > 0 && padShape->m_height > 0 )
326  {
327  if( padShape->m_KiCadLayer == F_Cu
328  || padShape->m_KiCadLayer == B_Cu )
329  {
330  width = padShape->m_width;
331  height = padShape->m_height;
332 
333  break;
334  }
335  }
336  }
337 
338  if( width == 0 || height == 0 )
339  return;
340 
341  if( IsCopperLayer( m_KiCadLayer ) )
342  {
343  VIA* via = new VIA( m_board );
344  m_board->m_Track.Append( via );
345 
346  via->SetTimeStamp( 0 );
347 
350 
351  via->SetWidth( height );
352  via->SetViaType( VIA_THROUGH );
353  via->SetLayerPair( F_Cu, B_Cu );
354  via->SetDrill( m_hole );
355 
356  via->SetLayer( m_KiCadLayer );
357  via->SetNetCode( m_netCode );
358  }
359  }
360  else // pad
361  {
362  MODULE* module = new MODULE( m_board );
363  m_board->Add( module, ADD_APPEND );
364 
366 
368  AddToModule( module, 0, true );
369 
370  }
371 }
372 
373 } // namespace PCAD2KICAD
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Function AllCuMask returns a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:673
void SetViaType(VIATYPE_T aViaType)
Definition: class_track.h:459
like PAD_STANDARD, but not plated mechanical use only, no connection allowed
Definition: pad_shapes.h:65
PAD_ATTR_T
Enum PAD_ATTR_T is the set of pad shapes, used with D_PAD::{Set,Get}Attribute() The double name is fo...
Definition: pad_shapes.h:58
void SetPosition(const wxPoint &aPoint) override
Definition: class_track.h:431
virtual void SetLayer(PCB_LAYER_ID aLayer)
Function SetLayer sets the layer this item is on.
void SetPosition(wxString aStr, const wxString &aDefaultMeasurementUnit, int *aX, int *aY, const wxString &aActualConversion)
void SetEnd(const wxPoint &aEnd)
Definition: class_track.h:118
void AddToBoard() override
Definition: pcb_pad.cpp:311
void Append(T *aNewElement)
Function Append adds aNewElement to the end of the list.
Definition: dlist.h:177
PCB_LAYER_ID FlipLayer(PCB_LAYER_ID aLayerId, int aCopperLayersCount)
Function FlippedLayerNumber.
Definition: lset.cpp:472
Smd pad, appears on the solder paste layer (default)
Definition: pad_shapes.h:61
virtual void Parse(XNODE *aNode, const wxString &aDefaultMeasurementUnit, const wxString &aActualConversion)
void SetWidth(wxString aStr, const wxString &aDefaultMeasurementUnit, int *aWidth, const wxString &aActualConversion)
void SetPosition(const wxPoint &aPos) override
Definition: class_pad.h:219
PCB_PAD(PCB_CALLBACKS *aCallbacks, BOARD *aBoard)
Definition: pcb_pad.cpp:38
void SetDrillSize(const wxSize &aSize)
Definition: class_pad.h:274
virtual void Parse(XNODE *aNode, const wxString &aDefaultMeasurementUnit, const wxString &aActualConversion)
Definition: pcb_pad.cpp:59
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:216
void AddToModule(MODULE *aModule) override
Definition: pcb_pad.h:55
const string & str
Definition: json11.cpp:596
void SetWidth(int aWidth)
Definition: class_track.h:115
XNODE * GetParent() const
Definition: xnode.h:73
void PushBack(T *aNewElement)
Function PushBack puts aNewElement at the end of the list sequence.
Definition: dlist.h:250
Class LSET is a set of PCB_LAYER_IDs.
void SetName(const wxString &aName)
Set the pad name (sometimes called pad number, although it can be an array reference like AA12)...
Definition: class_pad.h:182
double GetOrientation() const
Definition: class_module.h:187
void SetPos0(const wxPoint &aPos)
Definition: class_pad.h:262
wxString FindNodeGetContent(XNODE *aChild, const wxString &aTag)
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_INSERT) override
Adds an item to the container.
wxString m_defaultPinDes
Definition: pcb_pad.h:63
void SetSize(const wxSize &aSize)
Definition: class_pad.h:268
bool SetNetCode(int aNetCode, bool aNoAssert=false)
Function SetNetCode sets net using a net code.
void SetLayerPair(PCB_LAYER_ID aTopLayer, PCB_LAYER_ID aBottomLayer)
Function SetLayerPair For a via m_Layer contains the top layer, the other layer is in m_BottomLayer...
void SetPosition(const wxPoint &aPos) override
int GetNet() const
Function GetNet.
Definition: netinfo.h:227
virtual void Flip() override
Definition: pcb_pad.cpp:174
void SetAttribute(PAD_ATTR_T aAttribute)
Definition: class_pad.cpp:392
void SetLocalClearance(int aClearance)
Definition: class_pad.h:414
Class XNODE holds an XML or S-expression element.
Definition: xnode.h:43
void SetLayerSet(LSET aLayerMask)
Definition: class_pad.h:401
Class NETINFO_ITEM handles the data for a net.
Definition: netinfo.h:69
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
void SetDrillShape(PAD_DRILL_SHAPE_T aDrillShape)
Definition: class_pad.h:386
Class BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:169
void SetLocalSolderMaskMargin(int aMargin)
Definition: class_pad.h:411
size_t i
Definition: json11.cpp:597
void SetDrill(int aDrill)
Function SetDrill sets the drill value for vias.
Definition: class_track.h:466
Usual pad.
Definition: pad_shapes.h:60
XNODE * FindNode(XNODE *aChild, const wxString &aTag)
NETINFO_ITEM * FindNet(int aNetcode) const
Function FindNet searches for a net with the given netcode.
void SetShape(PAD_SHAPE_T aShape)
Definition: class_pad.h:217
void SetOrientation(double aAngle)
Function SetOrientation sets the rotation angle of the pad.
Definition: class_pad.cpp:401
bool IsCopperLayer(LAYER_NUM aLayerId)
Function IsCopperLayer tests whether a layer is a copper layer.
PCB_CALLBACKS * m_callbacks
Definition: pcb_component.h:78
PCB_PAD_SHAPES_ARRAY m_shapes
Definition: pcb_pad.h:46
int GetNetCode(wxString aNetName)
Definition: pcb_component.h:75
DLIST< D_PAD > & PadsList()
Definition: class_module.h:161
DLIST< TRACK > m_Track
Definition: class_board.h:246
XNODE * GetNext() const
Definition: xnode.h:68
void SetOffset(const wxPoint &aOffset)
Definition: class_pad.h:277
int StrToInt1Units(const wxString &aStr)
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38
const wxPoint GetPosition() const override
Definition: class_module.h:182
void SetDelta(const wxSize &aSize)
Definition: class_pad.h:271
void SetTimeStamp(timestamp_t aNewTimeStamp)
Definition: base_struct.h:214