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, wxString aDefaultMeasurementUnit,
60  wxString aActualConversion )
61 {
62  XNODE* lNode, *cNode;
63  long num;
64  wxString propValue, str, emsg;
65  PCB_PAD_SHAPE* padShape;
66 
67  m_rotation = 0;
68  lNode = FindNode( aNode, wxT( "padNum" ) );
69 
70  if( lNode )
71  {
72  lNode->GetNodeContent().ToLong( &num );
73  m_number = (int) num;
74  }
75 
76  lNode = FindNode( aNode, wxT( "padStyleRef" ) );
77 
78  if( lNode )
79  {
80  lNode->GetAttribute( wxT( "Name" ), &propValue );
81  propValue.Trim( false );
82  m_name.text = propValue;
83  }
84 
85  lNode = FindNode( aNode, wxT( "pt" ) );
86 
87  if( lNode )
88  SetPosition( lNode->GetNodeContent(), aDefaultMeasurementUnit,
89  &m_positionX, &m_positionY, aActualConversion );
90 
91  lNode = FindNode( aNode, wxT( "rotation" ) );
92 
93  if( lNode )
94  {
95  str = lNode->GetNodeContent();
96  str.Trim( false );
97  m_rotation = StrToInt1Units( str );
98  }
99 
100  lNode = FindNode( aNode, wxT( "netNameRef" ) );
101 
102  if( lNode )
103  {
104  lNode->GetAttribute( wxT( "Name" ), &propValue );
105  propValue.Trim( false );
106  propValue.Trim( true );
107  m_net = propValue;
109  }
110 
111  lNode = FindNode( aNode, wxT( "defaultPinDes" ) );
112 
113  if( lNode )
114  {
115  lNode->GetAttribute( wxT( "Name" ), &propValue );
116  //propValue.Trim( false );
117  m_defaultPinDes = propValue;
118  }
119 
120  lNode = aNode;
121 
122  while( lNode && lNode->GetName() != wxT( "www.lura.sk" ) )
123  lNode = lNode->GetParent();
124 
125  lNode = FindNode( lNode, wxT( "library" ) );
126  if ( !lNode )
127  THROW_IO_ERROR( wxT( "Unable to find library section" ) );
128 
129  lNode = FindNode( lNode, wxT( "padStyleDef" ) );
130 
131  while( lNode )
132  {
133  lNode->GetAttribute( wxT( "Name" ), &propValue );
134 
135  if( propValue.IsSameAs( m_name.text, false) )
136  break;
137 
138  lNode = lNode->GetNext();
139  }
140 
141  if ( !lNode )
142  THROW_IO_ERROR( wxString::Format( wxT( "Unable to find padStyleDef " ) + m_name.text ) );
143 
144  cNode = FindNode( lNode, wxT( "holeDiam" ) );
145 
146  if( cNode )
147  SetWidth( cNode->GetNodeContent(), aDefaultMeasurementUnit, &m_hole, aActualConversion );
148 
149  if( FindNodeGetContent( lNode, wxT( "isHolePlated" ) ) == wxT( "False" ) )
150  m_isHolePlated = false;
151 
152  cNode = FindNode( lNode, wxT( "padShape" ) );
153 
154  while( cNode )
155  {
156  if( cNode->GetName() == wxT( "padShape" ) )
157  {
158  // we support only Pads on specific layers......
159  // we do not support pads on "Plane", "NonSignal" , "Signal" ... layerr
160  if( FindNode( cNode, wxT( "layerNumRef" ) ) )
161  {
162  padShape = new PCB_PAD_SHAPE( m_callbacks, m_board );
163  padShape->Parse( cNode, aDefaultMeasurementUnit, aActualConversion );
164  m_shapes.Add( padShape );
165  }
166  }
167 
168  cNode = cNode->GetNext();
169  }
170 }
171 
172 
174 {
175  int i;
176 
178 
179  if( m_objType == wxT( 'P' ) )
181 
182  for( i = 0; i < (int)m_shapes.GetCount(); i++ )
184 }
185 
186 
187 void PCB_PAD::AddToModule( MODULE* aModule, int aRotation, bool aEncapsulatedPad )
188 {
189  PCB_PAD_SHAPE* padShape;
190  wxString padShapeName = wxT( "Ellipse" );
191  PAD_ATTR_T padType;
192  int i;
193  int width = 0;
194  int height = 0;
195 
196  D_PAD* pad = new D_PAD( aModule );
197 
198  if( !m_isHolePlated && m_hole )
199  {
200  // mechanical hole
201  pad->SetShape( PAD_SHAPE_CIRCLE );
203 
205  pad->SetDrillSize( wxSize( m_hole, m_hole ) );
206  pad->SetSize( wxSize( m_hole, m_hole ) );
207 
208  pad->SetLayerSet( LSET::AllCuMask() | LSET( 2, B_Mask, F_Mask ) );
209  }
210  else
211  {
212  ( m_hole ) ? padType = PAD_ATTRIB_STANDARD : padType = PAD_ATTRIB_SMD;
213 
214  // form layer mask
215  for( i = 0; i < (int) m_shapes.GetCount(); i++ )
216  {
217  padShape = m_shapes[i];
218 
219  if( padShape->m_width > 0 && padShape->m_height > 0 )
220  {
221  if( padShape->m_KiCadLayer == F_Cu ||
222  padShape->m_KiCadLayer == B_Cu )
223  {
224  padShapeName = padShape->m_shape;
225  width = padShape->m_width;
226  height = padShape->m_height;
227 
228  // assume this is SMD pad
229  if( padShape->m_KiCadLayer == F_Cu )
230  pad->SetLayerSet( LSET( 3, F_Cu, F_Paste, F_Mask ) );
231  else
232  pad->SetLayerSet( LSET( 3, B_Cu, B_Paste, B_Mask ) );
233  break;
234  }
235  }
236  }
237 
238  if( width == 0 || height == 0 )
239  {
240  delete pad;
241  return;
242  }
243 
244  if( padType == PAD_ATTRIB_STANDARD )
245  // actually this is a thru-hole pad
246  pad->SetLayerSet( LSET::AllCuMask() | LSET( 2, B_Mask, F_Mask ) );
247 
248  pad->SetPadName( m_name.text );
249 
250  if( padShapeName == wxT( "Oval" )
251  || padShapeName == wxT( "Ellipse" )
252  || padShapeName == wxT( "MtHole" ) )
253  {
254  if( width != height )
255  pad->SetShape( PAD_SHAPE_OVAL );
256  else
257  pad->SetShape( PAD_SHAPE_CIRCLE );
258  }
259  else if( padShapeName == wxT( "Rect" )
260  || padShapeName == wxT( "RndRect" ) )
261  pad->SetShape( PAD_SHAPE_RECT );
262  else if( padShapeName == wxT( "Polygon" ) )
263  pad->SetShape( PAD_SHAPE_RECT ); // approximation
264 
265  pad->SetSize( wxSize( width, height ) );
266  pad->SetDelta( wxSize( 0, 0 ) );
267  pad->SetOrientation( m_rotation + aRotation );
268 
270  pad->SetOffset( wxPoint( 0, 0 ) );
271  pad->SetDrillSize( wxSize( m_hole, m_hole ) );
272 
273  pad->SetAttribute( padType );
274 
275  // Set the proper net code
276  NETINFO_ITEM* netinfo = m_board->FindNet( m_net );
277  if( netinfo == NULL ) // I believe this should not happen, but just in case
278  {
279  // It is a new net
280  netinfo = new NETINFO_ITEM( m_board, m_net );
281  m_board->Add( netinfo );
282  }
283 
284  pad->SetNetCode( netinfo->GetNet() );
285  }
286 
287  if( !aEncapsulatedPad )
288  {
289  // pad's "Position" is not relative to the module's,
290  // whereas Pos0 is relative to the module's but is the unrotated coordinate.
291  wxPoint padpos( m_positionX, m_positionY );
292  pad->SetPos0( padpos );
293  RotatePoint( &padpos, aModule->GetOrientation() );
294  pad->SetPosition( padpos + aModule->GetPosition() );
295  }
296 
297  aModule->Pads().PushBack( pad );
298 }
299 
300 
302 {
303  PCB_PAD_SHAPE* padShape;
304  int i;
305  int width = 0;
306  int height = 0;
307 
308  if( m_objType == wxT( 'V' ) ) // via
309  {
310  // choose one of the shapes
311  for( i = 0; i < (int) m_shapes.GetCount(); i++ )
312  {
313  padShape = m_shapes[i];
314 
315  if( padShape->m_width > 0 && padShape->m_height > 0 )
316  {
317  if( padShape->m_KiCadLayer == F_Cu
318  || padShape->m_KiCadLayer == B_Cu )
319  {
320  width = padShape->m_width;
321  height = padShape->m_height;
322 
323  break;
324  }
325  }
326  }
327 
328  if( width == 0 || height == 0 )
329  return;
330 
331  if( IsCopperLayer( m_KiCadLayer ) )
332  {
333  VIA* via = new VIA( m_board );
334  m_board->m_Track.Append( via );
335 
336  via->SetTimeStamp( 0 );
337 
340 
341  via->SetWidth( height );
342  via->SetViaType( VIA_THROUGH );
343  via->SetLayerPair( F_Cu, B_Cu );
344  via->SetDrill( m_hole );
345 
346  via->SetLayer( m_KiCadLayer );
347  via->SetNetCode( m_netCode );
348  }
349  }
350  else // pad
351  {
352  MODULE* module = new MODULE( m_board );
353  m_board->Add( module, ADD_APPEND );
354 
356 
358  AddToModule( module, 0, true );
359 
360  }
361 }
362 
363 } // 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:639
void SetWidth(wxString aStr, wxString aDefaultMeasurementUnit, int *aWidth, wxString aActualConversion)
void SetViaType(VIATYPE_T aViaType)
Definition: class_track.h:447
like PAD_STANDARD, but not plated mechanical use only, no connection allowed
Definition: pad_shapes.h:63
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:56
void SetPosition(const wxPoint &aPoint) override
Definition: class_track.h:417
virtual void SetLayer(PCB_LAYER_ID aLayer)
Function SetLayer sets the layer this item is on.
void SetEnd(const wxPoint &aEnd)
Definition: class_track.h:117
void AddToBoard() override
Definition: pcb_pad.cpp:301
void Append(T *aNewElement)
Function Append adds aNewElement to the end of the list.
Definition: dlist.h:177
int StrToInt1Units(wxString aStr)
const wxPoint & GetPosition() const override
Definition: class_module.h:144
PCB_LAYER_ID FlipLayer(PCB_LAYER_ID aLayerId, int aCopperLayersCount)
Function FlippedLayerNumber.
Definition: lset.cpp:445
Smd pad, appears on the solder paste layer (default)
Definition: pad_shapes.h:59
void SetPosition(const wxPoint &aPos) override
Definition: class_pad.h:169
PCB_PAD(PCB_CALLBACKS *aCallbacks, BOARD *aBoard)
Definition: pcb_pad.cpp:38
void SetDrillSize(const wxSize &aSize)
Definition: class_pad.h:187
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:317
void SetTimeStamp(time_t aNewTimeStamp)
Definition: base_struct.h:203
void SetWidth(int aWidth)
Definition: class_track.h:114
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
wxString FindNodeGetContent(XNODE *aChild, wxString aTag)
Class LSET is a set of PCB_LAYER_IDs.
double GetOrientation() const
Definition: class_module.h:148
void SetPos0(const wxPoint &aPos)
Definition: class_pad.h:175
void AddToModule(MODULE *aModule, int aRotation, bool aEncapsulatedPad)
Definition: pcb_pad.cpp:187
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_INSERT) override
>
wxString m_defaultPinDes
Definition: pcb_pad.h:59
void SetSize(const wxSize &aSize)
Definition: class_pad.h:181
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(wxString aStr, wxString aDefaultMeasurementUnit, int *aX, int *aY, wxString aActualConversion)
#define THROW_IO_ERROR(x)
Definition: utf8.cpp:60
virtual void Parse(XNODE *aNode, wxString aDefaultMeasurementUnit, wxString aActualConversion)
void SetPosition(const wxPoint &aPos) override
int GetNet() const
Function GetNet.
virtual void Flip() override
Definition: pcb_pad.cpp:173
void SetAttribute(PAD_ATTR_T aAttribute)
Definition: class_pad.cpp:348
Class XNODE holds an XML or S-expression element.
Definition: xnode.h:43
void SetLayerSet(LSET aLayerMask)
Definition: class_pad.h:234
Class NETINFO_ITEM handles the data for a net.
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:218
Class BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:166
void SetDrill(int aDrill)
Function SetDrill sets the drill value for vias.
Definition: class_track.h:454
Usual pad.
Definition: pad_shapes.h:58
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:167
void SetPadName(const wxString &name)
Set the pad name (sometimes called pad number, although it can be an array ref like AA12 the pad name...
Definition: class_pad.cpp:455
void SetOrientation(double aAngle)
Function SetOrientation sets the rotation angle of the pad.
Definition: class_pad.cpp:357
XNODE * FindNode(XNODE *aChild, wxString aTag)
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
virtual void Parse(XNODE *aNode, wxString aDefaultMeasurementUnit, wxString aActualConversion)
Definition: pcb_pad.cpp:59
int GetNetCode(wxString aNetName)
Definition: pcb_component.h:75
DLIST< D_PAD > & Pads()
Definition: class_module.h:134
DLIST< TRACK > m_Track
Definition: class_board.h:244
XNODE * GetNext() const
Definition: xnode.h:68
void SetOffset(const wxPoint &aOffset)
Definition: class_pad.h:190
void SetDelta(const wxSize &aSize)
Definition: class_pad.h:184