KiCad PCB EDA Suite
class_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) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr
5  * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
6  * Copyright (C) 1992-2016 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, 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 
31 #include <fctsys.h>
32 #include <PolyLine.h>
33 #include <trigo.h>
34 #include <wxstruct.h>
35 #include <macros.h>
36 #include <msgpanel.h>
37 #include <base_units.h>
38 #include <bitmaps.h>
39 
40 #include <pcbnew.h>
41 
42 #include <class_board.h>
43 #include <class_module.h>
45 #include <convert_to_biu.h>
47 
48 
55 static wxString LayerMaskDescribe( const BOARD* aBoard, LSET aMask );
56 
57 int D_PAD::m_PadSketchModePenSize = 0; // Pen size used to draw pads in sketch mode
58 
59 
60 D_PAD::D_PAD( MODULE* parent ) :
62 {
63  m_NumPadName = 0;
64  m_Size.x = m_Size.y = Mils2iu( 60 ); // Default pad size 60 mils.
65  m_Drill.x = m_Drill.y = Mils2iu( 30 ); // Default drill size 30 mils.
66  m_Orient = 0; // Pad rotation in 1/10 degrees.
67  m_LengthPadToDie = 0;
68 
69  if( m_Parent && m_Parent->Type() == PCB_MODULE_T )
70  {
72  }
73 
74  SetShape( PAD_SHAPE_CIRCLE ); // Default pad shape is PAD_CIRCLE.
75  SetDrillShape( PAD_DRILL_SHAPE_CIRCLE ); // Default pad drill shape is a circle.
76  m_Attribute = PAD_ATTRIB_STANDARD; // Default pad type is NORMAL (thru hole)
77  m_LocalClearance = 0;
81  // Parameters for round rect only:
82  m_padRoundRectRadiusScale = 0.25; // from IPC-7351C standard
83 
84  m_ZoneConnection = PAD_ZONE_CONN_INHERITED; // Use parent setting by default
85  m_ThermalWidth = 0; // Use parent setting by default
86  m_ThermalGap = 0; // Use parent setting by default
87 
88  // Set layers mask to default for a standard thru hole pad.
90 
91  SetSubRatsnest( 0 ); // used in ratsnest calculations
92 
93  m_boundingRadius = -1;
94 }
95 
96 
98 {
99  static LSET saved = LSET::AllCuMask() | LSET( 2, B_Mask, F_Mask );
100  return saved;
101 }
102 
103 
105 {
106  static LSET saved( 3, F_Cu, F_Paste, F_Mask );
107  return saved;
108 }
109 
110 
112 {
113  static LSET saved( 2, F_Cu, F_Mask );
114  return saved;
115 }
116 
117 
119 {
120  static LSET saved = LSET::AllCuMask() | LSET( 2, B_Mask, F_Mask );
121  return saved;
122 }
123 
124 bool D_PAD::IsFlipped() const
125 {
126  if( GetParent() && GetParent()->GetLayer() == B_Cu )
127  return true;
128  return false;
129 }
130 
132 {
133  int x, y;
134  int radius;
135 
136  switch( GetShape() )
137  {
138  case PAD_SHAPE_CIRCLE:
139  radius = m_Size.x / 2;
140  break;
141 
142  case PAD_SHAPE_OVAL:
143  radius = std::max( m_Size.x, m_Size.y ) / 2;
144  break;
145 
146  case PAD_SHAPE_RECT:
147  radius = 1 + KiROUND( EuclideanNorm( m_Size ) / 2 );
148  break;
149 
150  case PAD_SHAPE_TRAPEZOID:
151  x = m_Size.x + std::abs( m_DeltaSize.y ); // Remember: m_DeltaSize.y is the m_Size.x change
152  y = m_Size.y + std::abs( m_DeltaSize.x ); // Remember: m_DeltaSize.x is the m_Size.y change
153  radius = 1 + KiROUND( hypot( x, y ) / 2 );
154  break;
155 
156  case PAD_SHAPE_ROUNDRECT:
157  radius = GetRoundRectCornerRadius();
158  x = m_Size.x >> 1;
159  y = m_Size.y >> 1;
160  radius += 1 + KiROUND( EuclideanNorm( wxSize( x - radius, y - radius )));
161  break;
162 
163  default:
164  radius = 0;
165  }
166 
167  return radius;
168 }
169 
170 
171 int D_PAD::GetRoundRectCornerRadius( const wxSize& aSize ) const
172 {
173  // radius of rounded corners, usually 25% of shorter pad edge for now
174  int r = aSize.x > aSize.y ? aSize.y : aSize.x;
175  r = int( r * m_padRoundRectRadiusScale );
176 
177  return r;
178 }
179 
180 
182 {
183  EDA_RECT area;
184  wxPoint quadrant1, quadrant2, quadrant3, quadrant4;
185  int x, y, r, dx, dy;
186 
187  wxPoint center = ShapePos();
188  wxPoint endPoint;
189 
190  EDA_RECT endRect;
191 
192  switch( GetShape() )
193  {
194  case PAD_SHAPE_CIRCLE:
195  area.SetOrigin( center );
196  area.Inflate( m_Size.x / 2 );
197  break;
198 
199  case PAD_SHAPE_OVAL:
200  /* To get the BoundingBox of an oval pad:
201  * a) If the pad is ROUND, see method for PAD_SHAPE_CIRCLE above
202  * OTHERWISE:
203  * b) Construct EDA_RECT for portion between circular ends
204  * c) Rotate that EDA_RECT
205  * d) Add the circular ends to the EDA_RECT
206  */
207 
208  // Test if the shape is circular
209  if( m_Size.x == m_Size.y )
210  {
211  area.SetOrigin( center );
212  area.Inflate( m_Size.x / 2 );
213  break;
214  }
215 
216  if( m_Size.x > m_Size.y )
217  {
218  // Pad is horizontal
219  dx = ( m_Size.x - m_Size.y ) / 2;
220  dy = m_Size.y / 2;
221 
222  // Location of end-points
223  x = dx;
224  y = 0;
225  r = dy;
226  }
227  else
228  {
229  // Pad is vertical
230  dx = m_Size.x / 2;
231  dy = ( m_Size.y - m_Size.x ) / 2;
232 
233  x = 0;
234  y = dy;
235  r = dx;
236  }
237 
238  // Construct the center rectangle and rotate
239  area.SetOrigin( center );
240  area.Inflate( dx, dy );
241  area = area.GetBoundingBoxRotated( center, m_Orient );
242 
243  endPoint = wxPoint( x, y );
244  RotatePoint( &endPoint, m_Orient );
245 
246  // Add points at each quadrant of circular regions
247  endRect.SetOrigin( center + endPoint );
248  endRect.Inflate( r );
249 
250  area.Merge( endRect );
251 
252  endRect.SetSize( 0, 0 );
253  endRect.SetOrigin( center - endPoint );
254  endRect.Inflate( r );
255 
256  area.Merge( endRect );
257 
258  break;
259 
260  case PAD_SHAPE_RECT:
261  case PAD_SHAPE_ROUNDRECT:
262  // Use two opposite corners and track their rotation
263  // (use symmetry for other points)
264  quadrant1.x = m_Size.x/2;
265  quadrant1.y = m_Size.y/2;
266  quadrant2.x = -m_Size.x/2;
267  quadrant2.y = m_Size.y/2;
268 
269  RotatePoint( &quadrant1, m_Orient );
270  RotatePoint( &quadrant2, m_Orient );
271  dx = std::max( std::abs( quadrant1.x ) , std::abs( quadrant2.x ) );
272  dy = std::max( std::abs( quadrant1.y ) , std::abs( quadrant2.y ) );
273 
274  // Set the bbox
275  area.SetOrigin( ShapePos() );
276  area.Inflate( dx, dy );
277  break;
278 
279  case PAD_SHAPE_TRAPEZOID:
280  // Use the four corners and track their rotation
281  // (Trapezoids will not be symmetric)
282 
283  quadrant1.x = (m_Size.x + m_DeltaSize.y)/2;
284  quadrant1.y = (m_Size.y - m_DeltaSize.x)/2;
285 
286  quadrant2.x = -(m_Size.x + m_DeltaSize.y)/2;
287  quadrant2.y = (m_Size.y + m_DeltaSize.x)/2;
288 
289  quadrant3.x = -(m_Size.x - m_DeltaSize.y)/2;
290  quadrant3.y = -(m_Size.y + m_DeltaSize.x)/2;
291 
292  quadrant4.x = (m_Size.x - m_DeltaSize.y)/2;
293  quadrant4.y = -(m_Size.y - m_DeltaSize.x)/2;
294 
295  RotatePoint( &quadrant1, m_Orient );
296  RotatePoint( &quadrant2, m_Orient );
297  RotatePoint( &quadrant3, m_Orient );
298  RotatePoint( &quadrant4, m_Orient );
299 
300  x = std::min( quadrant1.x, std::min( quadrant2.x, std::min( quadrant3.x, quadrant4.x) ) );
301  y = std::min( quadrant1.y, std::min( quadrant2.y, std::min( quadrant3.y, quadrant4.y) ) );
302  dx = std::max( quadrant1.x, std::max( quadrant2.x, std::max( quadrant3.x, quadrant4.x) ) );
303  dy = std::max( quadrant1.y, std::max( quadrant2.y, std::max( quadrant3.y, quadrant4.y) ) );
304 
305  area.SetOrigin( ShapePos().x + x, ShapePos().y + y );
306  area.SetSize( dx-x, dy-y );
307  break;
308 
309  default:
310  break;
311  }
312 
313  return area;
314 }
315 
316 
318 {
319  MODULE* module = (MODULE*) m_Parent;
320 
321  m_Pos = m_Pos0;
322 
323  if( module == NULL )
324  return;
325 
326  double angle = module->GetOrientation();
327 
328  RotatePoint( &m_Pos.x, &m_Pos.y, angle );
329  m_Pos += module->GetPosition();
330 }
331 
332 
334 {
335  MODULE* module = (MODULE*) m_Parent;
336 
337  if( module == NULL )
338  {
339  m_Pos0 = m_Pos;
340  return;
341  }
342 
343  m_Pos0 = m_Pos - module->GetPosition();
344  RotatePoint( &m_Pos0.x, &m_Pos0.y, -module->GetOrientation() );
345 }
346 
347 
348 void D_PAD::SetAttribute( PAD_ATTR_T aAttribute )
349 {
350  m_Attribute = aAttribute;
351 
352  if( aAttribute == PAD_ATTRIB_SMD )
353  m_Drill = wxSize( 0, 0 );
354 }
355 
356 
357 void D_PAD::SetOrientation( double aAngle )
358 {
359  NORMALIZE_ANGLE_POS( aAngle );
360  m_Orient = aAngle;
361 }
362 
363 
364 void D_PAD::Flip( const wxPoint& aCentre )
365 {
366  int y = GetPosition().y;
367  MIRROR( y, aCentre.y ); // invert about x axis.
368  SetY( y );
369 
370  MIRROR( m_Pos0.y, 0 );
371  MIRROR( m_Offset.y, 0 );
372  MIRROR( m_DeltaSize.y, 0 );
373 
375 
376  // flip pads layers
377  // PADS items are currently on all copper layers, or
378  // currently, only on Front or Back layers.
379  // So the copper layers count is not taken in account
381 
382  // m_boundingRadius = -1; the shape has not been changed
383 }
384 
385 
387 {
388  // Parameters stored in config are only significant parameters
389  // for a template.
390  // So not all parameters are stored, just few.
391  aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "PadDrill" ),
392  &m_Drill.x,
393  Millimeter2iu( 0.6 ),
394  Millimeter2iu( 0.1 ), Millimeter2iu( 10.0 ),
395  NULL, MM_PER_IU ) );
396 
397  aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "PadDrillOvalY" ),
398  &m_Drill.y,
399  Millimeter2iu( 0.6 ),
400  Millimeter2iu( 0.1 ), Millimeter2iu( 10.0 ),
401  NULL, MM_PER_IU ) );
402 
403  aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "PadSizeH" ),
404  &m_Size.x,
405  Millimeter2iu( 1.4 ),
406  Millimeter2iu( 0.1 ), Millimeter2iu( 20.0 ),
407  NULL, MM_PER_IU ) );
408 
409  aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "PadSizeV" ),
410  &m_Size.y,
411  Millimeter2iu( 1.4 ),
412  Millimeter2iu( 0.1 ), Millimeter2iu( 20.0 ),
413  NULL, MM_PER_IU ) );
414 }
415 
416 
417 // Returns the position of the pad.
419 {
420  if( m_Offset.x == 0 && m_Offset.y == 0 )
421  return m_Pos;
422 
423  wxPoint loc_offset = m_Offset;
424 
425  RotatePoint( &loc_offset, m_Orient );
426 
427  wxPoint shape_pos = m_Pos + loc_offset;
428 
429  return shape_pos;
430 }
431 
432 
433 wxString D_PAD::GetPadName() const
434 {
435  wxString name;
436 
437  StringPadName( name );
438  return name;
439 }
440 
441 
442 void D_PAD::StringPadName( wxString& text ) const
443 {
444  text.Empty();
445 
446  for( int ii = 0; ii < PADNAMEZ && m_Padname[ii]; ii++ )
447  {
448  // m_Padname is 8 bit KiCad font junk, do not sign extend
449  text.Append( (unsigned char) m_Padname[ii] );
450  }
451 }
452 
453 
454 // Change pad name
455 void D_PAD::SetPadName( const wxString& name )
456 {
457  int ii, len;
458 
459  len = name.Length();
460 
461  if( len > PADNAMEZ )
462  len = PADNAMEZ;
463 
464  // m_Padname[] is not UTF8, it is an 8 bit character that matches the KiCad font,
465  // so only copy the lower 8 bits of each character.
466 
467  for( ii = 0; ii < len; ii++ )
468  m_Padname[ii] = (char) name.GetChar( ii );
469 
470  for( ii = len; ii < PADNAMEZ; ii++ )
471  m_Padname[ii] = '\0';
472 }
473 
474 
475 bool D_PAD::IncrementPadName( bool aSkipUnconnectable, bool aFillSequenceGaps )
476 {
477  bool skip = aSkipUnconnectable && ( GetAttribute() == PAD_ATTRIB_HOLE_NOT_PLATED );
478 
479  if( !skip )
480  SetPadName( GetParent()->GetNextPadName( aFillSequenceGaps ) );
481 
482  return !skip;
483 }
484 
485 
486 void D_PAD::CopyNetlistSettings( D_PAD* aPad, bool aCopyLocalSettings )
487 {
488  // Don't do anything foolish like trying to copy to yourself.
489  wxCHECK_RET( aPad != NULL && aPad != this, wxT( "Cannot copy to NULL or yourself." ) );
490 
491  aPad->SetNetCode( GetNetCode() );
492 
493  if( aCopyLocalSettings )
494  {
501  aPad->SetThermalGap( m_ThermalGap );
502  }
503 }
504 
505 
507 {
508  // A pad can have specific clearance parameters that
509  // overrides its NETCLASS clearance value
510  int clearance = m_LocalClearance;
511 
512  if( clearance == 0 )
513  {
514  // If local clearance is 0, use the parent footprint clearance value
515  if( GetParent() && GetParent()->GetLocalClearance() )
516  clearance = GetParent()->GetLocalClearance();
517  }
518 
519  if( clearance == 0 ) // If the parent footprint clearance value = 0, use NETCLASS value
520  return BOARD_CONNECTED_ITEM::GetClearance( aItem );
521 
522  // We have a specific clearance.
523  // if aItem, return the biggest clearance
524  if( aItem )
525  {
526  int hisClearance = aItem->GetClearance();
527  return std::max( hisClearance, clearance );
528  }
529 
530  // Return the specific clearance.
531  return clearance;
532 }
533 
534 
535 // Mask margins handling:
536 
538 {
539  int margin = m_LocalSolderMaskMargin;
540  MODULE* module = GetParent();
541 
542  if( module )
543  {
544  if( margin == 0 )
545  {
546  if( module->GetLocalSolderMaskMargin() )
547  margin = module->GetLocalSolderMaskMargin();
548  }
549 
550  if( margin == 0 )
551  {
552  BOARD* brd = GetBoard();
553  margin = brd->GetDesignSettings().m_SolderMaskMargin;
554  }
555  }
556 
557  // ensure mask have a size always >= 0
558  if( margin < 0 )
559  {
560  int minsize = -std::min( m_Size.x, m_Size.y ) / 2;
561 
562  if( margin < minsize )
563  margin = minsize;
564  }
565 
566  return margin;
567 }
568 
569 
571 {
572  int margin = m_LocalSolderPasteMargin;
573  double mratio = m_LocalSolderPasteMarginRatio;
574  MODULE* module = GetParent();
575 
576  if( module )
577  {
578  if( margin == 0 )
579  margin = module->GetLocalSolderPasteMargin();
580 
581  BOARD * brd = GetBoard();
582 
583  if( margin == 0 )
584  margin = brd->GetDesignSettings().m_SolderPasteMargin;
585 
586  if( mratio == 0.0 )
587  mratio = module->GetLocalSolderPasteMarginRatio();
588 
589  if( mratio == 0.0 )
590  {
592  }
593  }
594 
595  wxSize pad_margin;
596  pad_margin.x = margin + KiROUND( m_Size.x * mratio );
597  pad_margin.y = margin + KiROUND( m_Size.y * mratio );
598 
599  // ensure mask have a size always >= 0
600  if( pad_margin.x < -m_Size.x / 2 )
601  pad_margin.x = -m_Size.x / 2;
602 
603  if( pad_margin.y < -m_Size.y / 2 )
604  pad_margin.y = -m_Size.y / 2;
605 
606  return pad_margin;
607 }
608 
609 
611 {
612  MODULE* module = GetParent();
613 
614  if( m_ZoneConnection == PAD_ZONE_CONN_INHERITED && module )
615  return module->GetZoneConnection();
616  else
617  return m_ZoneConnection;
618 }
619 
620 
622 {
623  MODULE* module = GetParent();
624 
625  if( m_ThermalWidth == 0 && module )
626  return module->GetThermalWidth();
627  else
628  return m_ThermalWidth;
629 }
630 
631 
633 {
634  MODULE* module = GetParent();
635 
636  if( m_ThermalGap == 0 && module )
637  return module->GetThermalGap();
638  else
639  return m_ThermalGap;
640 }
641 
642 
643 void D_PAD::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM>& aList )
644 {
645  MODULE* module;
646  wxString Line;
647  BOARD* board;
648 
649  module = (MODULE*) m_Parent;
650 
651  if( module )
652  {
653  wxString msg = module->GetReference();
654  aList.push_back( MSG_PANEL_ITEM( _( "Footprint" ), msg, DARKCYAN ) );
655  StringPadName( Line );
656  aList.push_back( MSG_PANEL_ITEM( _( "Pad" ), Line, BROWN ) );
657  }
658 
659  aList.push_back( MSG_PANEL_ITEM( _( "Net" ), GetNetname(), DARKCYAN ) );
660 
661  board = GetBoard();
662 
663  aList.push_back( MSG_PANEL_ITEM( _( "Layer" ),
664  LayerMaskDescribe( board, m_layerMask ), DARKGREEN ) );
665 
666  aList.push_back( MSG_PANEL_ITEM( ShowPadShape(), ShowPadAttr(), DARKGREEN ) );
667 
668  Line = ::CoordinateToString( m_Size.x );
669  aList.push_back( MSG_PANEL_ITEM( _( "Width" ), Line, RED ) );
670 
671  Line = ::CoordinateToString( m_Size.y );
672  aList.push_back( MSG_PANEL_ITEM( _( "Height" ), Line, RED ) );
673 
674  Line = ::CoordinateToString( (unsigned) m_Drill.x );
675 
677  {
678  aList.push_back( MSG_PANEL_ITEM( _( "Drill" ), Line, RED ) );
679  }
680  else
681  {
682  Line = ::CoordinateToString( (unsigned) m_Drill.x );
683  wxString msg;
684  msg = ::CoordinateToString( (unsigned) m_Drill.y );
685  Line += wxT( "/" ) + msg;
686  aList.push_back( MSG_PANEL_ITEM( _( "Drill X / Y" ), Line, RED ) );
687  }
688 
689  double module_orient_degrees = module ? module->GetOrientationDegrees() : 0;
690 
691  if( module_orient_degrees != 0.0 )
692  Line.Printf( wxT( "%3.1f(+%3.1f)" ),
693  GetOrientationDegrees() - module_orient_degrees,
694  module_orient_degrees );
695  else
696  Line.Printf( wxT( "%3.1f" ), GetOrientationDegrees() );
697 
698  aList.push_back( MSG_PANEL_ITEM( _( "Angle" ), Line, LIGHTBLUE ) );
699 
700  Line = ::CoordinateToString( m_Pos.x ) + wxT( ", " ) + ::CoordinateToString( m_Pos.y );
701  aList.push_back( MSG_PANEL_ITEM( _( "Position" ), Line, LIGHTBLUE ) );
702 
703  if( GetPadToDieLength() )
704  {
706  aList.push_back( MSG_PANEL_ITEM( _( "Length in package" ), Line, CYAN ) );
707  }
708 }
709 
710 
712  wxPoint& aEndPoint, int& aWidth ) const
713 {
714  // calculates the start point, end point and width
715  // of an equivalent segment which have the same position and width as the hole
716  int delta_cx, delta_cy;
717 
718  wxSize halfsize = GetDrillSize();
719  halfsize.x /= 2;
720  halfsize.y /= 2;
721 
722  if( m_Drill.x > m_Drill.y ) // horizontal
723  {
724  delta_cx = halfsize.x - halfsize.y;
725  delta_cy = 0;
726  aWidth = m_Drill.y;
727  }
728  else // vertical
729  {
730  delta_cx = 0;
731  delta_cy = halfsize.y - halfsize.x;
732  aWidth = m_Drill.x;
733  }
734 
735  RotatePoint( &delta_cx, &delta_cy, m_Orient );
736 
737  aStartPoint.x = delta_cx;
738  aStartPoint.y = delta_cy;
739 
740  aEndPoint.x = - delta_cx;
741  aEndPoint.y = - delta_cy;
742 }
743 
744 
745 bool D_PAD::HitTest( const wxPoint& aPosition ) const
746 {
747  int dx, dy;
748 
749  wxPoint shape_pos = ShapePos();
750 
751  wxPoint delta = aPosition - shape_pos;
752 
753  // first test: a test point must be inside a minimum sized bounding circle.
754  int radius = GetBoundingRadius();
755 
756  if( ( abs( delta.x ) > radius ) || ( abs( delta.y ) > radius ) )
757  return false;
758 
759  dx = m_Size.x >> 1; // dx also is the radius for rounded pads
760  dy = m_Size.y >> 1;
761 
762  switch( GetShape() )
763  {
764  case PAD_SHAPE_CIRCLE:
765  if( KiROUND( EuclideanNorm( delta ) ) <= dx )
766  return true;
767 
768  break;
769 
770  case PAD_SHAPE_TRAPEZOID:
771  {
772  wxPoint poly[4];
773  BuildPadPolygon( poly, wxSize(0,0), 0 );
774  RotatePoint( &delta, -m_Orient );
775 
776  return TestPointInsidePolygon( poly, 4, delta );
777  }
778 
779  case PAD_SHAPE_OVAL:
780  {
781  RotatePoint( &delta, -m_Orient );
782  // An oval pad has the same shape as a segment with rounded ends
783  // After rotation, the test point is relative to an horizontal pad
784  int dist;
785  wxPoint offset;
786  if( dy > dx ) // shape is a vertical oval
787  {
788  offset.y = dy - dx;
789  dist = dx;
790  }
791  else //if( dy <= dx ) shape is an horizontal oval
792  {
793  offset.x = dy - dx;
794  dist = dy;
795  }
796  return TestSegmentHit( delta, - offset, offset, dist );
797  }
798  break;
799 
800  case PAD_SHAPE_RECT:
801  RotatePoint( &delta, -m_Orient );
802 
803  if( (abs( delta.x ) <= dx ) && (abs( delta.y ) <= dy) )
804  return true;
805 
806  break;
807 
808  case PAD_SHAPE_ROUNDRECT:
809  {
810  // Check for hit in polygon
811  SHAPE_POLY_SET outline;
812  const int segmentToCircleCount = 32;
814  GetRoundRectCornerRadius(), segmentToCircleCount );
815 
816  const SHAPE_LINE_CHAIN &poly = outline.COutline( 0 );
817  return TestPointInsidePolygon( (const wxPoint*)&poly.CPoint(0), poly.PointCount(), delta );
818  }
819  break;
820  }
821 
822  return false;
823 }
824 
825 
826 bool D_PAD::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
827 {
828  EDA_RECT arect = aRect;
829  arect.Normalize();
830  arect.Inflate( aAccuracy );
831 
832  wxPoint shapePos = ShapePos();
833 
834  EDA_RECT shapeRect;
835 
836  int r;
837 
838  EDA_RECT bb = GetBoundingBox();
839 
840  wxPoint endCenter;
841  int radius;
842 
843  if( !arect.Intersects( bb ) )
844  return false;
845 
846  // This covers total containment for all test cases
847  if( arect.Contains( bb ) )
848  return true;
849 
850  switch( GetShape() )
851  {
852  case PAD_SHAPE_CIRCLE:
853  return arect.IntersectsCircle( GetPosition(), GetBoundingRadius() );
854  case PAD_SHAPE_RECT:
855  shapeRect.SetOrigin( shapePos );
856  shapeRect.Inflate( m_Size.x / 2, m_Size.y / 2 );
857  return arect.Intersects( shapeRect, m_Orient );
858  case PAD_SHAPE_OVAL:
859 
860  // Circlular test if dimensions are equal
861  if( m_Size.x == m_Size.y )
862  return arect.IntersectsCircle( shapePos, GetBoundingRadius() );
863 
864  shapeRect.SetOrigin( shapePos );
865 
866  // Horizontal dimension is greater
867  if( m_Size.x > m_Size.y )
868  {
869  radius = m_Size.y / 2;
870 
871  shapeRect.Inflate( m_Size.x / 2 - radius, radius );
872 
873  endCenter = wxPoint( m_Size.x / 2 - radius, 0 );
874  RotatePoint( &endCenter, m_Orient );
875 
876  // Test circular ends
877  if( arect.IntersectsCircle( shapePos + endCenter, radius ) ||
878  arect.IntersectsCircle( shapePos - endCenter, radius ) )
879  {
880  return true;
881  }
882  }
883  else
884  {
885  radius = m_Size.x / 2;
886 
887  shapeRect.Inflate( radius, m_Size.y / 2 - radius );
888 
889  endCenter = wxPoint( 0, m_Size.y / 2 - radius );
890  RotatePoint( &endCenter, m_Orient );
891 
892  // Test circular ends
893  if( arect.IntersectsCircle( shapePos + endCenter, radius ) ||
894  arect.IntersectsCircle( shapePos - endCenter, radius ) )
895  {
896  return true;
897  }
898  }
899 
900  // Test rectangular portion between rounded ends
901  if( arect.Intersects( shapeRect, m_Orient ) )
902  {
903  return true;
904  }
905 
906  break;
907  case PAD_SHAPE_TRAPEZOID:
908  /* Trapezoid intersection tests:
909  * A) Any points of rect inside trapezoid
910  * B) Any points of trapezoid inside rect
911  * C) Any sides of trapezoid cross rect
912  */
913  {
914 
915  wxPoint poly[4];
916  BuildPadPolygon( poly, wxSize( 0, 0 ), 0 );
917 
918  wxPoint corners[4];
919 
920  corners[0] = wxPoint( arect.GetLeft(), arect.GetTop() );
921  corners[1] = wxPoint( arect.GetRight(), arect.GetTop() );
922  corners[2] = wxPoint( arect.GetRight(), arect.GetBottom() );
923  corners[3] = wxPoint( arect.GetLeft(), arect.GetBottom() );
924 
925  for( int i=0; i<4; i++ )
926  {
927  RotatePoint( &poly[i], m_Orient );
928  poly[i] += shapePos;
929  }
930 
931  for( int ii=0; ii<4; ii++ )
932  {
933  if( TestPointInsidePolygon( poly, 4, corners[ii] ) )
934  {
935  return true;
936  }
937 
938  if( arect.Contains( poly[ii] ) )
939  {
940  return true;
941  }
942 
943  if( arect.Intersects( poly[ii], poly[(ii+1) % 4] ) )
944  {
945  return true;
946  }
947  }
948 
949  return false;
950 
951  }
952  case PAD_SHAPE_ROUNDRECT:
953  /* RoundRect intersection can be broken up into simple tests:
954  * a) Test intersection of horizontal rect
955  * b) Test intersection of vertical rect
956  * c) Test intersection of each corner
957  */
958 
959 
961 
962  /* Test A - intersection of horizontal rect */
963  shapeRect.SetSize( 0, 0 );
964  shapeRect.SetOrigin( shapePos );
965  shapeRect.Inflate( m_Size.x / 2, m_Size.y / 2 - r );
966 
967  // Short-circuit test for zero width or height
968  if( shapeRect.GetWidth() > 0 && shapeRect.GetHeight() > 0 &&
969  arect.Intersects( shapeRect, m_Orient ) )
970  {
971  return true;
972  }
973 
974  /* Test B - intersection of vertical rect */
975  shapeRect.SetSize( 0, 0 );
976  shapeRect.SetOrigin( shapePos );
977  shapeRect.Inflate( m_Size.x / 2 - r, m_Size.y / 2 );
978 
979  // Short-circuit test for zero width or height
980  if( shapeRect.GetWidth() > 0 && shapeRect.GetHeight() > 0 &&
981  arect.Intersects( shapeRect, m_Orient ) )
982  {
983  return true;
984  }
985 
986  /* Test C - intersection of each corner */
987 
988  endCenter = wxPoint( m_Size.x / 2 - r, m_Size.y / 2 - r );
989  RotatePoint( &endCenter, m_Orient );
990 
991  if( arect.IntersectsCircle( shapePos + endCenter, r ) ||
992  arect.IntersectsCircle( shapePos - endCenter, r ) )
993  {
994  return true;
995  }
996 
997  endCenter = wxPoint( m_Size.x / 2 - r, -m_Size.y / 2 + r );
998  RotatePoint( &endCenter, m_Orient );
999 
1000  if( arect.IntersectsCircle( shapePos + endCenter, r ) ||
1001  arect.IntersectsCircle( shapePos - endCenter, r ) )
1002  {
1003  return true;
1004  }
1005 
1006  break;
1007  default:
1008  break;
1009  }
1010 
1011  return false;
1012 }
1013 
1014 int D_PAD::Compare( const D_PAD* padref, const D_PAD* padcmp )
1015 {
1016  int diff;
1017 
1018  if( ( diff = padref->GetShape() - padcmp->GetShape() ) != 0 )
1019  return diff;
1020 
1021  if( ( diff = padref->GetDrillShape() - padcmp->GetDrillShape() ) != 0)
1022  return diff;
1023 
1024  if( ( diff = padref->m_Drill.x - padcmp->m_Drill.x ) != 0 )
1025  return diff;
1026 
1027  if( ( diff = padref->m_Drill.y - padcmp->m_Drill.y ) != 0 )
1028  return diff;
1029 
1030  if( ( diff = padref->m_Size.x - padcmp->m_Size.x ) != 0 )
1031  return diff;
1032 
1033  if( ( diff = padref->m_Size.y - padcmp->m_Size.y ) != 0 )
1034  return diff;
1035 
1036  if( ( diff = padref->m_Offset.x - padcmp->m_Offset.x ) != 0 )
1037  return diff;
1038 
1039  if( ( diff = padref->m_Offset.y - padcmp->m_Offset.y ) != 0 )
1040  return diff;
1041 
1042  if( ( diff = padref->m_DeltaSize.x - padcmp->m_DeltaSize.x ) != 0 )
1043  return diff;
1044 
1045  if( ( diff = padref->m_DeltaSize.y - padcmp->m_DeltaSize.y ) != 0 )
1046  return diff;
1047 
1048 // TODO: test custom shapes
1049 
1050  // Dick: specctra_export needs this
1051  // Lorenzo: gencad also needs it to implement padstacks!
1052 
1053 #if __cplusplus >= 201103L
1054  long long d = padref->m_layerMask.to_ullong() - padcmp->m_layerMask.to_ullong();
1055  if( d < 0 )
1056  return -1;
1057  else if( d > 0 )
1058  return 1;
1059 
1060  return 0;
1061 #else
1062  // these strings are not typically constructed, since we don't get here often.
1063  std::string s1 = padref->m_layerMask.to_string();
1064  std::string s2 = padcmp->m_layerMask.to_string();
1065  return s1.compare( s2 );
1066 #endif
1067 }
1068 
1069 
1070 void D_PAD::Rotate( const wxPoint& aRotCentre, double aAngle )
1071 {
1072  RotatePoint( &m_Pos, aRotCentre, aAngle );
1073 
1074  m_Orient = NormalizeAngle360( m_Orient + aAngle );
1075 
1076  SetLocalCoord();
1077 }
1078 
1079 
1080 wxString D_PAD::ShowPadShape() const
1081 {
1082  switch( GetShape() )
1083  {
1084  case PAD_SHAPE_CIRCLE:
1085  return _( "Circle" );
1086 
1087  case PAD_SHAPE_OVAL:
1088  return _( "Oval" );
1089 
1090  case PAD_SHAPE_RECT:
1091  return _( "Rect" );
1092 
1093  case PAD_SHAPE_TRAPEZOID:
1094  return _( "Trap" );
1095 
1096  case PAD_SHAPE_ROUNDRECT:
1097  return _( "Roundrect" );
1098 
1099  default:
1100  return wxT( "???" );
1101  }
1102 }
1103 
1104 
1105 wxString D_PAD::ShowPadAttr() const
1106 {
1107  switch( GetAttribute() )
1108  {
1109  case PAD_ATTRIB_STANDARD:
1110  return _( "Std" );
1111 
1112  case PAD_ATTRIB_SMD:
1113  return _( "SMD" );
1114 
1115  case PAD_ATTRIB_CONN:
1116  return _( "Conn" );
1117 
1119  return _( "Not Plated" );
1120 
1121  default:
1122  return wxT( "???" );
1123  }
1124 }
1125 
1126 
1128 {
1129  wxString text;
1130  wxString padlayers( LayerMaskDescribe( GetBoard(), m_layerMask ) );
1131  wxString padname( GetPadName() );
1132 
1133  if( padname.IsEmpty() )
1134  {
1135  text.Printf( _( "Pad on %s of %s" ),
1136  GetChars( padlayers ),
1137  GetChars(GetParent()->GetReference() ) );
1138  }
1139  else
1140  {
1141  text.Printf( _( "Pad %s on %s of %s" ),
1142  GetChars(GetPadName() ), GetChars( padlayers ),
1143  GetChars(GetParent()->GetReference() ) );
1144  }
1145 
1146  return text;
1147 }
1148 
1149 
1151 {
1152  return pad_xpm;
1153 }
1154 
1155 
1157 {
1158  return new D_PAD( *this );
1159 }
1160 
1161 
1162 void D_PAD::ViewGetLayers( int aLayers[], int& aCount ) const
1163 {
1164  aCount = 0;
1165 
1166  // These types of pads contain a hole
1168  aLayers[aCount++] = LAYER_PADS_HOLES;
1169 
1170  if( IsOnLayer( F_Cu ) && IsOnLayer( B_Cu ) )
1171  {
1172  // Multi layer pad
1173  aLayers[aCount++] = LAYER_PADS;
1174  aLayers[aCount++] = LAYER_PADS_NETNAMES;
1175  }
1176  else if( IsOnLayer( F_Cu ) )
1177  {
1178  aLayers[aCount++] = LAYER_PAD_FR;
1179  aLayers[aCount++] = LAYER_PAD_FR_NETNAMES;
1180  }
1181  else if( IsOnLayer( B_Cu ) )
1182  {
1183  aLayers[aCount++] = LAYER_PAD_BK;
1184  aLayers[aCount++] = LAYER_PAD_BK_NETNAMES;
1185  }
1186 
1187  // Check non-copper layers. This list should include all the layers that the
1188  // footprint editor allows a pad to be placed on.
1189  static const PCB_LAYER_ID layers_mech[] = { F_Mask, B_Mask, F_Paste, B_Paste,
1191 
1192  for( PCB_LAYER_ID each_layer : layers_mech )
1193  {
1194  if( IsOnLayer( each_layer ) )
1195  aLayers[aCount++] = each_layer;
1196  }
1197 
1198 #ifdef __WXDEBUG__
1199  if( aCount == 0 ) // Should not occur
1200  {
1201  wxString msg;
1202  msg.Printf( wxT( "footprint %s, pad %s: could not find valid layer for pad" ),
1203  GetParent() ? GetParent()->GetReference() : "<null>",
1204  GetPadName().IsEmpty() ? "(unnamed)" : GetPadName() );
1205  wxLogWarning( msg );
1206  }
1207 #endif
1208 }
1209 
1210 
1211 unsigned int D_PAD::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const
1212 {
1213  // Netnames will be shown only if zoom is appropriate
1214  if( IsNetnameLayer( aLayer ) )
1215  {
1216  int divisor = std::max( m_Size.x, m_Size.y );
1217 
1218  // Pad sizes can be zero briefly when someone is typing a number like "0.5"
1219  // in the pad properties dialog
1220  if( divisor == 0 )
1221  return UINT_MAX;
1222 
1223  return ( Millimeter2iu( 100 ) / divisor );
1224  }
1225 
1226  // Other layers are shown without any conditions
1227  return 0;
1228 }
1229 
1230 
1231 const BOX2I D_PAD::ViewBBox() const
1232 {
1233  // Bounding box includes soldermask too
1234  int solderMaskMargin = GetSolderMaskMargin();
1235  VECTOR2I solderPasteMargin = VECTOR2D( GetSolderPasteMargin() );
1236  EDA_RECT bbox = GetBoundingBox();
1237 
1238  // Look for the biggest possible bounding box
1239  int xMargin = std::max( solderMaskMargin, solderPasteMargin.x );
1240  int yMargin = std::max( solderMaskMargin, solderPasteMargin.y );
1241 
1242  return BOX2I( VECTOR2I( bbox.GetOrigin() ) - VECTOR2I( xMargin, yMargin ),
1243  VECTOR2I( bbox.GetSize() ) + VECTOR2I( 2 * xMargin, 2 * yMargin ) );
1244 }
1245 
1246 
1247 wxString LayerMaskDescribe( const BOARD *aBoard, LSET aMask )
1248 {
1249  // Try the single or no- layer case (easy)
1250  PCB_LAYER_ID layer = aMask.ExtractLayer();
1251 
1252  switch( (int) layer )
1253  {
1254  case UNSELECTED_LAYER:
1255  return _( "No layers" );
1256 
1257  case UNDEFINED_LAYER:
1258  break;
1259 
1260  default:
1261  return aBoard->GetLayerName( layer );
1262  }
1263 
1264  // Try to be smart and useful, starting with outer copper
1265  // (which are more important than internal ones)
1266  wxString layerInfo;
1267 
1268  if( aMask[F_Cu] )
1269  AccumulateDescription( layerInfo, aBoard->GetLayerName( F_Cu ) );
1270 
1271  if( aMask[B_Cu] )
1272  AccumulateDescription( layerInfo, aBoard->GetLayerName( B_Cu ) );
1273 
1274  if( ( aMask & LSET::InternalCuMask() ).any() )
1275  AccumulateDescription( layerInfo, _("Internal" ) );
1276 
1277  if( ( aMask & LSET::AllNonCuMask() ).any() )
1278  AccumulateDescription( layerInfo, _("Non-copper" ) );
1279 
1280  return layerInfo;
1281 }
1282 
1283 
1284 void D_PAD::ImportSettingsFromMaster( const D_PAD& aMasterPad )
1285 {
1286  SetShape( aMasterPad.GetShape() );
1287  SetLayerSet( aMasterPad.GetLayerSet() );
1288  SetAttribute( aMasterPad.GetAttribute() );
1289 
1290  // The pad orientation, for historical reasons is the
1291  // pad rotation + parent rotation.
1292  // So we have to manage this parent rotation
1293  double pad_rot = aMasterPad.GetOrientation();
1294 
1295  if( aMasterPad.GetParent() )
1296  pad_rot -= aMasterPad.GetParent()->GetOrientation();
1297 
1298  if( GetParent() )
1299  pad_rot += GetParent()->GetOrientation();
1300 
1301  SetOrientation( pad_rot );
1302 
1303  SetSize( aMasterPad.GetSize() );
1304  SetDelta( wxSize( 0, 0 ) );
1305  SetOffset( aMasterPad.GetOffset() );
1306  SetDrillSize( aMasterPad.GetDrillSize() );
1307  SetDrillShape( aMasterPad.GetDrillShape() );
1309 
1310  switch( aMasterPad.GetShape() )
1311  {
1312  case PAD_SHAPE_TRAPEZOID:
1313  SetDelta( aMasterPad.GetDelta() );
1314  break;
1315 
1316  case PAD_SHAPE_CIRCLE:
1317  // ensure size.y == size.x
1318  SetSize( wxSize( GetSize().x, GetSize().x ) );
1319  break;
1320 
1321  default:
1322  ;
1323  }
1324 
1325  switch( aMasterPad.GetAttribute() )
1326  {
1327  case PAD_ATTRIB_SMD:
1328  case PAD_ATTRIB_CONN:
1329  // These pads do not have hole (they are expected to be only on one
1330  // external copper layer)
1331  SetDrillSize( wxSize( 0, 0 ) );
1332  break;
1333 
1334  default:
1335  ;
1336  }
1337 }
int m_LocalClearance
Local clearance.
Definition: class_pad.h:658
double EuclideanNorm(const wxPoint &vector)
Euclidean norm of a 2D vector.
Definition: trigo.h:104
int m_ThermalGap
Definition: class_pad.h:671
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
int m_LocalSolderMaskMargin
Local mask margins: when 0, the parent footprint design values are used.
Definition: class_pad.h:662
BITMAP_DEF GetMenuImage() const override
Function GetMenuImage returns a pointer to an image to be used in menus.
Definition: class_pad.cpp:1150
wxString CoordinateToString(int aValue, bool aConvertToMils)
Function CoordinateToString is a helper to convert the integer coordinate aValue to a string in inche...
Definition: base_units.cpp:117
bool IncrementPadName(bool aSkipUnconnectable, bool aFillSequenceGaps)
Function IncrementPadName.
Definition: class_pad.cpp:475
KICAD_T Type() const
Function Type()
Definition: base_struct.h:198
static int m_PadSketchModePenSize
Pen size used to draw pads in sketch mode (mode used to print pads on silkscreen layer) ...
Definition: class_pad.h:83
int m_SolderMaskMargin
Solder mask margin.
double m_padRoundRectRadiusScale
scaling factor from smallest m_Size coord to corner radius, default 0.25
Definition: class_pad.h:621
A list of parameters type.
int m_boundingRadius
radius of the circle containing the pad shape
Definition: class_pad.h:591
EDA_ITEM * Clone() const override
Function Clone creates a duplicate of this item with linked list members set to NULL.
Definition: class_pad.cpp:1156
BOX2< VECTOR2I > BOX2I
Definition: box2.h:468
EDA_ITEM * m_Parent
Linked list: Link (parent struct)
Definition: base_struct.h:168
LSET FlipLayerMask(LSET aMask, int aCopperLayersCount)
Calculate the mask layer when flipping a footprint BACK and FRONT copper layers, mask, paste, solder layers are swapped internal layers are flipped only if the copper layers count is known.
Definition: lset.cpp:491
int GetThermalGap() const
Definition: class_module.h:195
static LSET StandardMask()
layer set for a through hole pad
Definition: class_pad.cpp:97
#define PADNAMEZ
Definition: class_pad.h:598
wxString GetSelectMenuText() const override
Function GetSelectMenuText returns the text to display to be used in the selection clarification cont...
Definition: class_pad.cpp:1127
void Merge(const EDA_RECT &aRect)
Function Merge modifies the position and size of the rectangle in order to contain aRect...
PNG memory record (file in memory).
Definition: bitmap_types.h:38
PAD_ATTR_T GetAttribute() const
Definition: class_pad.h:238
bool HitTest(const wxPoint &aPosition) const override
Function HitTest tests if aPosition is contained within or on the bounding area of an item...
Definition: class_pad.cpp:745
int GetLeft() const
static int KiROUND(double v)
KiROUND rounds a floating point number to an int using "round halfway cases away from zero"...
Definition: common.h:107
like PAD_STANDARD, but not plated mechanical use only, no connection allowed
Definition: pad_shapes.h:63
int m_SolderPasteMargin
Solder paste margin absolute value.
void Rotate(const wxPoint &aRotCentre, double aAngle) override
Function Rotate Rotate this object.
Definition: class_pad.cpp:1070
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
int m_LocalSolderPasteMargin
Local solder paste margin absolute value.
Definition: class_pad.h:663
Implementation of conversion functions that require both schematic and board internal units...
static LSET UnplatedHoleMask()
layer set for a mechanical unplated through hole pad
Definition: class_pad.cpp:118
int GetLocalClearance() const
Definition: class_module.h:179
void BuildPadPolygon(wxPoint aCoord[4], wxSize aInflateValue, double aRotation) const
Function BuildPadPolygon Has meaning only for polygonal pads (trapezoid and rectangular) Build the Co...
static LSET SMDMask()
layer set for a SMD pad on Front layer
Definition: class_pad.cpp:104
int PointCount() const
Function PointCount()
bool Contains(const wxPoint &aPoint) const
Function Contains.
bool IntersectsCircle(const wxPoint &aCenter, const int aRadius) const
Function IntersectsCircle tests for a common area between a circle and this rectangle.
int GetPadToDieLength() const
Definition: class_pad.h:241
Class BOARD to handle a board.
const wxPoint & GetPosition() const override
Definition: class_module.h:155
D_PAD(MODULE *parent)
Definition: class_pad.cpp:60
void TransformRoundRectToPolygon(SHAPE_POLY_SET &aCornerBuffer, const wxPoint &aPosition, const wxSize &aSize, double aRotation, int aCornerRadius, int aCircleToSegmentsCount)
Function TransformRoundRectToPolygon convert a rectangle with rounded corners to a polygon Convert ar...
int GetRoundRectCornerRadius() const
Function GetRoundRectCornerRadius Has meaning only for rounded rect pads.
Definition: class_pad.h:351
ZoneConnection
How pads are covered by copper in zone.
Definition: zones.h:55
static LSET AllNonCuMask()
Function AllNonCuMask returns a mask holding all layer minus CU layers.
Definition: lset.cpp:662
wxSize m_Size
X and Y size ( relative to orient 0)
Definition: class_pad.h:617
MODULE * GetParent() const
Definition: class_pad.h:108
Smd pad, appears on the solder paste layer (default)
Definition: pad_shapes.h:59
static const int dist[10][10]
Definition: dist.cpp:57
int GetHeight() const
void SetOrigin(const wxPoint &pos)
int boundingRadius() const
Function boundingRadius returns a calculated radius of a bounding circle for this pad...
Definition: class_pad.cpp:131
wxString ShowPadAttr() const
Function ShowPadAttr.
Definition: class_pad.cpp:1105
PAD_DRILL_SHAPE_T GetDrillShape() const
Definition: class_pad.h:221
class D_PAD, a pad in a footprint
Definition: typeinfo.h:102
void SetSubRatsnest(int aSubRatsnest)
Definition: class_pad.h:475
void SetDrillSize(const wxSize &aSize)
Definition: class_pad.h:187
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:317
ZoneConnection GetZoneConnection() const
Definition: class_module.h:189
void NORMALIZE_ANGLE_POS(T &Angle)
Definition: trigo.h:222
const wxSize & GetDrillSize() const
Definition: class_pad.h:188
void SetRoundRectRadiusRatio(double aRadiusScale)
has meaning only for rounded rect pads Set the scaling factor between the smaller Y or Y size and the...
Definition: class_pad.h:462
static wxString GetNextPadName(wxString aPadName)
Compute the 'next' pad number for autoincrement aPadName is the last pad name used.
VECTOR2< int > VECTOR2I
Definition: vector2d.h:590
PAD_SHAPE_T GetShape() const
Function GetShape.
Definition: class_pad.h:166
#define abs(a)
Definition: auxiliary.h:84
Class BOARD_CONNECTED_ITEM is a base class derived from BOARD_ITEM for items that can be connected an...
Configuration parameter - Integer Class with unit conversion.
smd pads, back layer
double GetLocalSolderPasteMarginRatio() const
Definition: class_module.h:185
static const int delta[8][2]
Definition: solve.cpp:112
void SetLocalCoord()
Set relative coordinates.
Definition: class_pad.cpp:333
This file contains miscellaneous commonly used macros and functions.
wxUint32 m_NumPadName
Definition: class_pad.h:600
PCB_LAYER_ID ExtractLayer() const
Find the first set PCB_LAYER_ID.
Definition: lset.cpp:578
const wxPoint & GetOrigin() const
void MIRROR(T &aPoint, const T &aMirrorRef)
Definition: macros.h:111
class MODULE, a footprint
Definition: typeinfo.h:101
PCB_LAYER_ID
A quick note on layer IDs:
virtual const BOX2I ViewBBox() const override
Function ViewBBox() returns the bounding box of the item covering all its layers. ...
Definition: class_pad.cpp:1231
Class LSET is a set of PCB_LAYER_IDs.
bool TestPointInsidePolygon(const CPOLYGONS_LIST &aPolysList, int aIdxstart, int aIdxend, int aRefx, int aRefy)
Function TestPointInsidePolygon test if a point is inside or outside a polygon.
double GetOrientationDegrees() const
Definition: class_module.h:161
VECTOR2< double > VECTOR2D
Definition: vector2d.h:589
void SetZoneConnection(ZoneConnection aType)
Definition: class_pad.h:309
int GetBoundingRadius() const
Function GetBoundingRadius returns the radius of a minimum sized circle which fully encloses this pad...
Definition: class_pad.h:428
double GetOrientation() const
Definition: class_module.h:160
Class SHAPE_POLY_SET.
Base window classes and related definitions.
int GetSolderMaskMargin() const
Function GetSolderMaskMargin.
Definition: class_pad.cpp:537
const wxPoint & GetPosition() const override
Definition: class_pad.h:170
static int Compare(const D_PAD *padref, const D_PAD *padcmp)
Function Compare compares two pads and return 0 if they are equal.
Definition: class_pad.cpp:1014
const EDA_RECT GetBoundingBoxRotated(wxPoint aRotCenter, double aAngle)
Function GetBoundingBoxRotated.
multilayer pads, usually with holes
ZoneConnection GetZoneConnection() const
Definition: class_pad.cpp:610
LSET GetLayerSet() const override
Function GetLayerSet returns a "layer mask", which is a bitmap of all layers on which the TRACK segme...
Definition: class_pad.h:235
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Function GetLayerName returns the name of a layer given by aLayer.
Definition: colors.h:59
int GetThermalWidth() const
Definition: class_pad.cpp:621
int GetThermalGap() const
Definition: class_pad.cpp:632
static LSET InternalCuMask()
Function InternalCuMask() returns a complete set of internal copper layers, which is all Cu layers ex...
Definition: lset.cpp:599
void SetThermalWidth(int aWidth)
Definition: class_pad.h:312
const wxSize & GetSize() const
Definition: class_pad.h:182
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:532
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.
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
int m_ThermalWidth
Definition: class_pad.h:670
virtual void ViewGetLayers(int aLayers[], int &aCount) const override
Function ViewGetLayers() Returns the all the layers within the VIEW the object is painted on...
Definition: class_pad.cpp:1162
Definition: colors.h:60
int GetBottom() const
void ImportSettingsFromMaster(const D_PAD &aMasterPad)
Imports the pad settings from aMasterPad.
Definition: class_pad.cpp:1284
virtual unsigned int ViewGetLOD(int aLayer, KIGFX::VIEW *aView) const override
Function ViewGetLOD() Returns the level of detail of the item.
Definition: class_pad.cpp:1211
virtual int GetClearance(BOARD_CONNECTED_ITEM *aItem=NULL) const
Function GetClearance returns the clearance in internal units.
int GetLocalSolderMaskMargin() const
Definition: class_module.h:176
void SetDrawCoord()
Set absolute coordinates.
Definition: class_pad.cpp:317
int GetRight() const
wxSize m_DeltaSize
delta on rectangular shapes
Definition: class_pad.h:644
Like smd, does not appear on the solder paste layer (default) note also has a special attribute in Ge...
Definition: pad_shapes.h:60
to draw pad holes (plated or not plated)
void SetAttribute(PAD_ATTR_T aAttribute)
Definition: class_pad.cpp:348
bool IsFlipped() const
Definition: class_pad.cpp:124
int GetLocalClearance() const
Definition: class_pad.h:246
void SetLocalClearance(int aClearance)
Definition: class_pad.h:247
int GetLocalSolderPasteMargin() const
Definition: class_module.h:182
void SetLocalSolderPasteMarginRatio(double aRatio)
Definition: class_pad.h:253
int GetNetCode() const
Function GetNetCode.
void Normalize()
Function Normalize ensures that the height ant width are positive.
LSET m_layerMask
Bitwise layer :1= copper layer, 15= cmp, 2..14 = internal layers 16 .
Definition: class_pad.h:640
void AccumulateDescription(wxString &aDesc, const wxString &aItem)
Utility to build comma separated lists in messages.
Definition: macros.h:65
void SetSize(const wxSize &size)
bool Intersects(const EDA_RECT &aRect) const
Function Intersects tests for a common area between rectangles.
void SetLayerSet(LSET aLayerMask)
Definition: class_pad.h:234
PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
void SetY(int y)
Definition: class_pad.h:172
static const wxChar * GetChars(const wxString &s)
Function GetChars returns a wxChar* to the actual wxChar* data within a wxString, and is helpful for ...
Definition: macros.h:92
smd pads, front layer
const wxString & GetNetname() const
Function GetNetname.
double GetRoundRectRadiusRatio() const
has meaning only for rounded rect pads
Definition: class_pad.h:450
void SetDrillShape(PAD_DRILL_SHAPE_T aDrillShape)
Definition: class_pad.h:218
wxPoint m_Pos0
Initial Pad position (i.e.
Definition: class_pad.h:646
void GetOblongDrillGeometry(wxPoint &aStartPoint, wxPoint &aEndPoint, int &aWidth) const
Function GetOblongDrillGeometry calculates the start point, end point and width of an equivalent segm...
Definition: class_pad.cpp:711
#define max(a, b)
Definition: auxiliary.h:86
Class BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:169
const wxString & GetReference() const
Function GetReference.
Definition: class_module.h:419
void SetLocalSolderMaskMargin(int aMargin)
Definition: class_pad.h:244
void Flip(const wxPoint &aCentre) override
Function Flip Flip this object, i.e.
Definition: class_pad.cpp:364
Class SHAPE_LINE_CHAIN.
int m_LengthPadToDie
Length net from pad to die, inside the package.
Definition: class_pad.h:653
wxString ShowPadShape() const
Function ShowPadShape.
Definition: class_pad.cpp:1080
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
double GetOrientation() const
Function GetOrientation returns the rotation angle of the pad in tenths of degrees, but soon degrees.
Definition: class_pad.h:214
Class EDA_RECT handles the component boundary box.
const wxSize & GetDelta() const
Definition: class_pad.h:185
Usual pad.
Definition: pad_shapes.h:58
wxSize GetSolderPasteMargin() const
Function GetSolderPasteMargin.
Definition: class_pad.cpp:570
Class EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boa...
Definition: base_struct.h:151
int GetWidth() const
int GetClearance(BOARD_CONNECTED_ITEM *aItem=NULL) const override
Function GetClearance returns the clearance in internal units.
Definition: class_pad.cpp:506
void SetShape(PAD_SHAPE_T aShape)
Definition: class_pad.h:167
wxPoint ShapePos() const
Definition: class_pad.cpp:418
char m_Padname[PADNAMEZ]
Definition: class_pad.h:599
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
const char * name
void SetOrientation(double aAngle)
Function SetOrientation sets the rotation angle of the pad.
Definition: class_pad.cpp:357
virtual BOARD * GetBoard() const
Function GetBoard returns the BOARD in which this BOARD_ITEM resides, or NULL if none.
PAD_ATTR_T m_Attribute
PAD_ATTRIB_NORMAL, PAD_ATTRIB_SMD, PAD_ATTRIB_CONN, PAD_ATTRIB_HOLE_NOT_PLATED.
Definition: class_pad.h:649
void SetLocalSolderPasteMargin(int aMargin)
Definition: class_pad.h:250
static LSET ConnSMDMask()
layer set for a SMD pad on Front layer used for edge board connectors
Definition: class_pad.cpp:111
wxString GetPadName() const
Definition: class_pad.cpp:433
wxSize m_Drill
Drill diam (drill shape = PAD_CIRCLE) or drill size (shape = OVAL) for drill shape = PAD_CIRCLE...
Definition: class_pad.h:613
Module description (excepted pads)
double m_Orient
in 1/10 degrees
Definition: class_pad.h:651
double m_LocalSolderPasteMarginRatio
Local solder mask margin ratio value of pad size The final margin is the sum of these 2 values...
Definition: class_pad.h:665
wxPoint m_Offset
m_Offset is useful only for oblong and rect pads (it can be used for other shapes, but without any interest).
Definition: class_pad.h:638
Class EDA_MSG_ITEM is used EDA_MSG_PANEL as the item type for displaying messages.
Definition: msgpanel.h:53
Class VIEW.
Definition: view.h:58
bool TestSegmentHit(const wxPoint &aRefPoint, wxPoint aStart, wxPoint aEnd, int aDist)
Function TestSegmentHit test for hit on line segment i.e.
Definition: trigo.cpp:142
void StringPadName(wxString &text) const
Definition: class_pad.cpp:442
double m_SolderPasteMarginRatio
Solder pask margin ratio value of pad size The final margin is the sum of these 2 values...
bool IsOnLayer(PCB_LAYER_ID aLayer) const override
Function IsOnLayer tests to see if this object is on the given layer.
Definition: class_pad.h:479
Message panel definition file.
void SetOffset(const wxPoint &aOffset)
Definition: class_pad.h:190
const wxSize & GetSize() const
const VECTOR2I & CPoint(int aIndex) const
Function CPoint()
void SetThermalGap(int aGap)
Definition: class_pad.h:315
double GetOrientationDegrees() const
Definition: class_pad.h:215
void CopyNetlistSettings(D_PAD *aPad, bool aCopyLocalSettings)
Function CopyNetlistSettings copies the netlist settings to aPad, and the net name.
Definition: class_pad.cpp:486
const EDA_RECT GetBoundingBox() const override
Function GetBoundingBox returns the orthogonal, bounding box of this object for display purposes...
Definition: class_pad.cpp:181
const wxPoint & GetOffset() const
Definition: class_pad.h:191
static wxString LayerMaskDescribe(const BOARD *aBoard, LSET aMask)
Helper function Return a string (to be shown to the user) describing a layer mask.
Definition: class_pad.cpp:1247
int GetThermalWidth() const
Definition: class_module.h:192
Additional netnames layers (not associated with a PCB layer)
ZoneConnection m_ZoneConnection
how the connection to zone is made: no connection, thermal relief ...
Definition: class_pad.h:668
void SetDelta(const wxSize &aSize)
Definition: class_pad.h:184
EDA_RECT & Inflate(wxCoord dx, wxCoord dy)
Function Inflate inflates the rectangle horizontally by dx and vertically by dy.
T NormalizeAngle360(T Angle)
Normalize angle to be in the -360.0 .. 360.0:
Definition: trigo.h:202
bool IsNetnameLayer(LAYER_NUM aLayer)
Function IsNetnameLayer tests whether a layer is a netname layer.
#define min(a, b)
Definition: auxiliary.h:85
wxPoint m_Pos
pad Position on board
Definition: class_pad.h:604
void AppendConfigs(PARAM_CFG_ARRAY *aResult)
Function AppendConfigs appends to aResult the configuration setting accessors which will later allow ...
Definition: class_pad.cpp:386
void GetMsgPanelInfo(std::vector< MSG_PANEL_ITEM > &aList) override
Function GetMsgPanelInfo populates aList of MSG_PANEL_ITEM objects with it's internal state for displ...
Definition: class_pad.cpp:643
Definition: colors.h:62
int GetTop() const