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) 2018 Jean-Pierre Charras, jp.charras at wanadoo.fr
5  * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
6  * Copyright (C) 1992-2019 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 <trigo.h>
33 #include <macros.h>
34 #include <msgpanel.h>
35 #include <base_units.h>
36 #include <bitmaps.h>
37 #include <math/util.h> // for KiROUND
38 
40 #include <pcbnew.h>
41 #include <view/view.h>
42 
43 #include <class_board.h>
44 #include <class_module.h>
46 #include <convert_to_biu.h>
48 
49 
56 static wxString LayerMaskDescribe( const BOARD* aBoard, LSET aMask );
57 
58 int D_PAD::m_PadSketchModePenSize = 0; // Pen size used to draw pads in sketch mode
59 
60 D_PAD::D_PAD( MODULE* parent ) :
62 {
63  m_Size.x = m_Size.y = Mils2iu( 60 ); // Default pad size 60 mils.
64  m_Drill.x = m_Drill.y = Mils2iu( 30 ); // Default drill size 30 mils.
65  m_Orient = 0; // Pad rotation in 1/10 degrees.
66  m_LengthPadToDie = 0;
67 
68  if( m_Parent && m_Parent->Type() == PCB_MODULE_T )
69  {
71  }
72 
73  SetShape( PAD_SHAPE_CIRCLE ); // Default pad shape is PAD_CIRCLE.
74  SetAnchorPadShape( PAD_SHAPE_CIRCLE ); // Default shape for custom shaped pads
75  // is PAD_CIRCLE.
76  SetDrillShape( PAD_DRILL_SHAPE_CIRCLE ); // Default pad drill shape is a circle.
77  m_Attribute = PAD_ATTRIB_STANDARD; // Default pad type is NORMAL (thru hole)
78  SetProperty( PAD_PROP_NONE ); // no special fabrication property
79  m_LocalClearance = 0;
83  // Parameters for round rect only:
84  m_padRoundRectRadiusScale = 0.25; // from IPC-7351C standard
85  // Parameters for chamfered rect only:
86  m_padChamferRectScale = 0.2; // Size of chamfer: ratio of smallest of X,Y size
87  m_chamferPositions = RECT_NO_CHAMFER; // No chamfered corner
88 
89  m_ZoneConnection = ZONE_CONNECTION::INHERITED; // Use parent setting by default
90  m_ThermalWidth = 0; // Use parent setting by default
91  m_ThermalGap = 0; // Use parent setting by default
92 
94 
95  // Set layers mask to default for a standard thru hole pad.
97 
98  SetSubRatsnest( 0 ); // used in ratsnest calculations
99 
100  m_boundingRadius = -1;
101 }
102 
103 
105 {
106  static LSET saved = LSET::AllCuMask() | LSET( 2, B_Mask, F_Mask );
107  return saved;
108 }
109 
110 
112 {
113  static LSET saved( 3, F_Cu, F_Paste, F_Mask );
114  return saved;
115 }
116 
117 
119 {
120  static LSET saved( 2, F_Cu, F_Mask );
121  return saved;
122 }
123 
124 
126 {
127  static LSET saved = LSET::AllCuMask() | LSET( 2, B_Mask, F_Mask );
128  return saved;
129 }
130 
131 
133 {
134  static LSET saved = LSET( 1, F_Paste );
135  return saved;
136 }
137 
138 
139 bool D_PAD::IsFlipped() const
140 {
141  if( GetParent() && GetParent()->GetLayer() == B_Cu )
142  return true;
143  return false;
144 }
145 
147 {
148  int x, y;
149  int radius;
150 
151  switch( GetShape() )
152  {
153  case PAD_SHAPE_CIRCLE:
154  radius = m_Size.x / 2;
155  break;
156 
157  case PAD_SHAPE_OVAL:
158  radius = std::max( m_Size.x, m_Size.y ) / 2;
159  break;
160 
161  case PAD_SHAPE_RECT:
162  radius = 1 + KiROUND( EuclideanNorm( m_Size ) / 2 );
163  break;
164 
165  case PAD_SHAPE_TRAPEZOID:
166  x = m_Size.x + std::abs( m_DeltaSize.y ); // Remember: m_DeltaSize.y is the m_Size.x change
167  y = m_Size.y + std::abs( m_DeltaSize.x ); // Remember: m_DeltaSize.x is the m_Size.y change
168  radius = 1 + KiROUND( hypot( x, y ) / 2 );
169  break;
170 
171  case PAD_SHAPE_ROUNDRECT:
172  radius = GetRoundRectCornerRadius();
173  x = m_Size.x >> 1;
174  y = m_Size.y >> 1;
175  radius += 1 + KiROUND( EuclideanNorm( wxSize( x - radius, y - radius )));
176  break;
177 
179  radius = GetRoundRectCornerRadius();
180  x = m_Size.x >> 1;
181  y = m_Size.y >> 1;
182  radius += 1 + KiROUND( EuclideanNorm( wxSize( x - radius, y - radius )));
183  // TODO: modify radius if the chamfer is smaller than corner radius
184  break;
185 
186  case PAD_SHAPE_CUSTOM:
187  radius = 0;
188 
189  for( int cnt = 0; cnt < m_customShapeAsPolygon.OutlineCount(); ++cnt )
190  {
191  const SHAPE_LINE_CHAIN& poly = m_customShapeAsPolygon.COutline( cnt );
192  for( int ii = 0; ii < poly.PointCount(); ++ii )
193  {
194  int dist = KiROUND( poly.CPoint( ii ).EuclideanNorm() );
195  radius = std::max( radius, dist );
196  }
197  }
198 
199  radius += 1;
200  break;
201 
202  default:
203  radius = 0;
204  }
205 
206  return radius;
207 }
208 
209 
210 int D_PAD::GetRoundRectCornerRadius( const wxSize& aSize ) const
211 {
212  // radius of rounded corners, usually 25% of shorter pad edge for now
213  int r = aSize.x > aSize.y ? aSize.y : aSize.x;
214  r = int( r * m_padRoundRectRadiusScale );
215 
216  return r;
217 }
218 
219 
220 void D_PAD::SetRoundRectCornerRadius( double aRadius )
221 {
222  int min_r = std::min( m_Size.x, m_Size.y );
223 
224  if( min_r > 0 )
225  SetRoundRectRadiusRatio( aRadius / min_r );
226 }
227 
228 
230 {
231  EDA_RECT area;
232  wxPoint quadrant1, quadrant2, quadrant3, quadrant4;
233  int x, y, r, dx, dy;
234 
235  wxPoint center = ShapePos();
236  wxPoint endPoint;
237 
238  EDA_RECT endRect;
239 
240  switch( GetShape() )
241  {
242  case PAD_SHAPE_CIRCLE:
243  area.SetOrigin( center );
244  area.Inflate( m_Size.x / 2 );
245  break;
246 
247  case PAD_SHAPE_OVAL:
248  /* To get the BoundingBox of an oval pad:
249  * a) If the pad is ROUND, see method for PAD_SHAPE_CIRCLE above
250  * OTHERWISE:
251  * b) Construct EDA_RECT for portion between circular ends
252  * c) Rotate that EDA_RECT
253  * d) Add the circular ends to the EDA_RECT
254  */
255 
256  // Test if the shape is circular
257  if( m_Size.x == m_Size.y )
258  {
259  area.SetOrigin( center );
260  area.Inflate( m_Size.x / 2 );
261  break;
262  }
263 
264  if( m_Size.x > m_Size.y )
265  {
266  // Pad is horizontal
267  dx = ( m_Size.x - m_Size.y ) / 2;
268  dy = m_Size.y / 2;
269 
270  // Location of end-points
271  x = dx;
272  y = 0;
273  r = dy;
274  }
275  else
276  {
277  // Pad is vertical
278  dx = m_Size.x / 2;
279  dy = ( m_Size.y - m_Size.x ) / 2;
280 
281  x = 0;
282  y = dy;
283  r = dx;
284  }
285 
286  // Construct the center rectangle and rotate
287  area.SetOrigin( center );
288  area.Inflate( dx, dy );
289  area = area.GetBoundingBoxRotated( center, m_Orient );
290 
291  endPoint = wxPoint( x, y );
292  RotatePoint( &endPoint, m_Orient );
293 
294  // Add points at each quadrant of circular regions
295  endRect.SetOrigin( center + endPoint );
296  endRect.Inflate( r );
297 
298  area.Merge( endRect );
299 
300  endRect.SetSize( 0, 0 );
301  endRect.SetOrigin( center - endPoint );
302  endRect.Inflate( r );
303 
304  area.Merge( endRect );
305 
306  break;
307 
308  case PAD_SHAPE_RECT:
309  case PAD_SHAPE_ROUNDRECT:
311  // Use two opposite corners and track their rotation
312  // (use symmetry for other points)
313  quadrant1.x = m_Size.x/2;
314  quadrant1.y = m_Size.y/2;
315  quadrant2.x = -m_Size.x/2;
316  quadrant2.y = m_Size.y/2;
317 
318  RotatePoint( &quadrant1, m_Orient );
319  RotatePoint( &quadrant2, m_Orient );
320  dx = std::max( std::abs( quadrant1.x ) , std::abs( quadrant2.x ) );
321  dy = std::max( std::abs( quadrant1.y ) , std::abs( quadrant2.y ) );
322 
323  // Set the bbox
324  area.SetOrigin( ShapePos() );
325  area.Inflate( dx, dy );
326  break;
327 
328  case PAD_SHAPE_TRAPEZOID:
329  // Use the four corners and track their rotation
330  // (Trapezoids will not be symmetric)
331 
332  quadrant1.x = (m_Size.x + m_DeltaSize.y)/2;
333  quadrant1.y = (m_Size.y - m_DeltaSize.x)/2;
334 
335  quadrant2.x = -(m_Size.x + m_DeltaSize.y)/2;
336  quadrant2.y = (m_Size.y + m_DeltaSize.x)/2;
337 
338  quadrant3.x = -(m_Size.x - m_DeltaSize.y)/2;
339  quadrant3.y = -(m_Size.y + m_DeltaSize.x)/2;
340 
341  quadrant4.x = (m_Size.x - m_DeltaSize.y)/2;
342  quadrant4.y = -(m_Size.y - m_DeltaSize.x)/2;
343 
344  RotatePoint( &quadrant1, m_Orient );
345  RotatePoint( &quadrant2, m_Orient );
346  RotatePoint( &quadrant3, m_Orient );
347  RotatePoint( &quadrant4, m_Orient );
348 
349  x = std::min( quadrant1.x, std::min( quadrant2.x, std::min( quadrant3.x, quadrant4.x) ) );
350  y = std::min( quadrant1.y, std::min( quadrant2.y, std::min( quadrant3.y, quadrant4.y) ) );
351  dx = std::max( quadrant1.x, std::max( quadrant2.x, std::max( quadrant3.x, quadrant4.x) ) );
352  dy = std::max( quadrant1.y, std::max( quadrant2.y, std::max( quadrant3.y, quadrant4.y) ) );
353 
354  area.SetOrigin( ShapePos().x + x, ShapePos().y + y );
355  area.SetSize( dx-x, dy-y );
356  break;
357 
358  case PAD_SHAPE_CUSTOM:
359  {
361  // Move shape to actual position
363  quadrant1 = m_Pos;
364  quadrant2 = m_Pos;
365 
366  for( int cnt = 0; cnt < polySet.OutlineCount(); ++cnt )
367  {
368  const SHAPE_LINE_CHAIN& poly = polySet.COutline( cnt );
369 
370  for( int ii = 0; ii < poly.PointCount(); ++ii )
371  {
372  quadrant1.x = std::min( quadrant1.x, poly.CPoint( ii ).x );
373  quadrant1.y = std::min( quadrant1.y, poly.CPoint( ii ).y );
374  quadrant2.x = std::max( quadrant2.x, poly.CPoint( ii ).x );
375  quadrant2.y = std::max( quadrant2.y, poly.CPoint( ii ).y );
376  }
377  }
378 
379  area.SetOrigin( quadrant1 );
380  area.SetEnd( quadrant2 );
381  }
382  break;
383 
384  default:
385  break;
386  }
387 
388  return area;
389 }
390 
391 
393 {
394  MODULE* module = (MODULE*) m_Parent;
395 
396  m_Pos = m_Pos0;
397 
398  if( module == NULL )
399  return;
400 
401  double angle = module->GetOrientation();
402 
403  RotatePoint( &m_Pos.x, &m_Pos.y, angle );
404  m_Pos += module->GetPosition();
405 }
406 
407 
409 {
410  MODULE* module = (MODULE*) m_Parent;
411 
412  if( module == NULL )
413  {
414  m_Pos0 = m_Pos;
415  return;
416  }
417 
418  m_Pos0 = m_Pos - module->GetPosition();
419  RotatePoint( &m_Pos0.x, &m_Pos0.y, -module->GetOrientation() );
420 }
421 
422 
423 void D_PAD::SetAttribute( PAD_ATTR_T aAttribute )
424 {
425  m_Attribute = aAttribute;
426 
427  if( aAttribute == PAD_ATTRIB_SMD )
428  m_Drill = wxSize( 0, 0 );
429 }
430 
431 
433 {
434  m_Property = aProperty;
435 }
436 
437 
438 void D_PAD::SetOrientation( double aAngle )
439 {
440  NORMALIZE_ANGLE_POS( aAngle );
441  m_Orient = aAngle;
442 }
443 
444 
445 void D_PAD::Flip( const wxPoint& aCentre, bool aFlipLeftRight )
446 {
447  if( aFlipLeftRight )
448  {
449  MIRROR( m_Pos.x, aCentre.x );
450  MIRROR( m_Pos0.x, 0 );
451  MIRROR( m_Offset.x, 0 );
452  MIRROR( m_DeltaSize.x, 0 );
453  }
454  else
455  {
456  MIRROR( m_Pos.y, aCentre.y );
457  MIRROR( m_Pos0.y, 0 );
458  MIRROR( m_Offset.y, 0 );
459  MIRROR( m_DeltaSize.y, 0 );
460  }
461 
463 
464  // flip pads layers
465  // PADS items are currently on all copper layers, or
466  // currently, only on Front or Back layers.
467  // So the copper layers count is not taken in account
469 
470  // Flip the basic shapes, in custom pads
471  FlipPrimitives();
472 
473  // m_boundingRadius = -1; the shape has not been changed
474 }
475 
476 
477 // Flip the basic shapes, in custom pads
479 {
480  // Flip custom shapes
481  for( unsigned ii = 0; ii < m_basicShapes.size(); ++ii )
482  {
483  PAD_CS_PRIMITIVE& primitive = m_basicShapes[ii];
484 
485  MIRROR( primitive.m_Start.y, 0 );
486  MIRROR( primitive.m_End.y, 0 );
487  primitive.m_ArcAngle = -primitive.m_ArcAngle;
488 
489  switch( primitive.m_Shape )
490  {
491  case S_POLYGON: // polygon
492  for( unsigned jj = 0; jj < primitive.m_Poly.size(); jj++ )
493  MIRROR( primitive.m_Poly[jj].y, 0 );
494  break;
495 
496  default:
497  break;
498  }
499  }
500 
501  // Flip local coordinates in merged Polygon
502  m_customShapeAsPolygon.Mirror( false, true );
503 }
504 
505 
507 {
508  // Mirror custom shapes
509  for( unsigned ii = 0; ii < m_basicShapes.size(); ++ii )
510  {
511  PAD_CS_PRIMITIVE& primitive = m_basicShapes[ii];
512 
513  MIRROR( primitive.m_Start.x, aX );
514  MIRROR( primitive.m_End.x, aX );
515  primitive.m_ArcAngle = -primitive.m_ArcAngle;
516 
517  switch( primitive.m_Shape )
518  {
519  case S_POLYGON: // polygon
520  for( unsigned jj = 0; jj < primitive.m_Poly.size(); jj++ )
521  MIRROR( primitive.m_Poly[jj].x, 0 );
522  break;
523 
524  default:
525  break;
526  }
527  }
528 
529  // Mirror the local coordinates in merged Polygon
530  for( int cnt = 0; cnt < m_customShapeAsPolygon.OutlineCount(); ++cnt )
531  {
533  poly.Mirror( true, false );
534  }
535 }
536 
537 
538 void D_PAD::AppendConfigs( std::vector<PARAM_CFG*>* aResult )
539 {
540  // Parameters stored in config are only significant parameters
541  // for a template.
542  // So not all parameters are stored, just few.
543  aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "PadDrill" ),
544  &m_Drill.x,
545  Millimeter2iu( 0.6 ),
546  Millimeter2iu( 0.1 ), Millimeter2iu( 10.0 ),
547  NULL, MM_PER_IU ) );
548 
549  aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "PadDrillOvalY" ),
550  &m_Drill.y,
551  Millimeter2iu( 0.6 ),
552  Millimeter2iu( 0.1 ), Millimeter2iu( 10.0 ),
553  NULL, MM_PER_IU ) );
554 
555  aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "PadSizeH" ),
556  &m_Size.x,
557  Millimeter2iu( 1.4 ),
558  Millimeter2iu( 0.1 ), Millimeter2iu( 20.0 ),
559  NULL, MM_PER_IU ) );
560 
561  aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "PadSizeV" ),
562  &m_Size.y,
563  Millimeter2iu( 1.4 ),
564  Millimeter2iu( 0.1 ), Millimeter2iu( 20.0 ),
565  NULL, MM_PER_IU ) );
566 }
567 
568 
569 // Returns the position of the pad.
571 {
572  if( m_Offset.x == 0 && m_Offset.y == 0 )
573  return m_Pos;
574 
575  wxPoint loc_offset = m_Offset;
576 
577  RotatePoint( &loc_offset, m_Orient );
578 
579  wxPoint shape_pos = m_Pos + loc_offset;
580 
581  return shape_pos;
582 }
583 
584 
585 bool D_PAD::IncrementPadName( bool aSkipUnconnectable, bool aFillSequenceGaps )
586 {
587  bool skip = aSkipUnconnectable && ( GetAttribute() == PAD_ATTRIB_HOLE_NOT_PLATED );
588 
589  if( !skip )
590  SetName( GetParent()->GetNextPadName( aFillSequenceGaps ) );
591 
592  return !skip;
593 }
594 
595 
597 {
598  // A pad can have specific clearance parameters that
599  // overrides its NETCLASS clearance value
600  int clearance = m_LocalClearance;
601 
602  if( clearance == 0 )
603  {
604  // If local clearance is 0, use the parent footprint clearance value
605  if( GetParent() && GetParent()->GetLocalClearance() )
606  clearance = GetParent()->GetLocalClearance();
607  }
608 
609  if( clearance == 0 ) // If the parent footprint clearance value = 0, use NETCLASS value
610  return BOARD_CONNECTED_ITEM::GetClearance( aItem );
611 
612  // We have a specific clearance.
613  // if aItem, return the biggest clearance
614  if( aItem )
615  {
616  int hisClearance = aItem->GetClearance();
617  return std::max( hisClearance, clearance );
618  }
619 
620  // Return the specific clearance.
621  return clearance;
622 }
623 
624 
625 // Mask margins handling:
626 
628 {
629  // The pad inherits the margin only to calculate a default shape,
630  // therefore only if it is also a copper layer
631  // Pads defined only on mask layers (and perhaps on other tech layers) use the shape
632  // defined by the pad settings only
633  bool isOnCopperLayer = ( m_layerMask & LSET::AllCuMask() ).any();
634 
635  if( !isOnCopperLayer )
636  return 0;
637 
638  int margin = m_LocalSolderMaskMargin;
639 
640  MODULE* module = GetParent();
641 
642  if( module )
643  {
644  if( margin == 0 )
645  {
646  if( module->GetLocalSolderMaskMargin() )
647  margin = module->GetLocalSolderMaskMargin();
648  }
649 
650  if( margin == 0 )
651  {
652  BOARD* brd = GetBoard();
653  if( brd )
654  {
655  margin = brd->GetDesignSettings().m_SolderMaskMargin;
656  }
657  }
658  }
659 
660  // ensure mask have a size always >= 0
661  if( margin < 0 )
662  {
663  int minsize = -std::min( m_Size.x, m_Size.y ) / 2;
664 
665  if( margin < minsize )
666  margin = minsize;
667  }
668 
669  return margin;
670 }
671 
672 
674 {
675  // The pad inherits the margin only to calculate a default shape,
676  // therefore only if it is also a copper layer.
677  // Pads defined only on mask layers (and perhaps on other tech layers) use the shape
678  // defined by the pad settings only
679  bool isOnCopperLayer = ( m_layerMask & LSET::AllCuMask() ).any();
680 
681  if( !isOnCopperLayer )
682  return wxSize( 0, 0 );
683 
684  int margin = m_LocalSolderPasteMargin;
685  double mratio = m_LocalSolderPasteMarginRatio;
686 
687  MODULE* module = GetParent();
688 
689  if( module )
690  {
691  if( margin == 0 )
692  margin = module->GetLocalSolderPasteMargin();
693 
694  auto brd = GetBoard();
695 
696  if( margin == 0 && brd )
697  {
698  margin = brd->GetDesignSettings().m_SolderPasteMargin;
699  }
700 
701  if( mratio == 0.0 )
702  mratio = module->GetLocalSolderPasteMarginRatio();
703 
704  if( mratio == 0.0 && brd )
705  {
706  mratio = brd->GetDesignSettings().m_SolderPasteMarginRatio;
707  }
708  }
709 
710  wxSize pad_margin;
711  pad_margin.x = margin + KiROUND( m_Size.x * mratio );
712  pad_margin.y = margin + KiROUND( m_Size.y * mratio );
713 
714  // ensure mask have a size always >= 0
715  if( pad_margin.x < -m_Size.x / 2 )
716  pad_margin.x = -m_Size.x / 2;
717 
718  if( pad_margin.y < -m_Size.y / 2 )
719  pad_margin.y = -m_Size.y / 2;
720 
721  return pad_margin;
722 }
723 
724 
726 {
727  MODULE* module = GetParent();
728 
730  return module->GetZoneConnection();
731  else
732  return m_ZoneConnection;
733 }
734 
735 
737 {
738  MODULE* module = GetParent();
739 
740  if( m_ThermalWidth == 0 && module )
741  return module->GetThermalWidth();
742  else
743  return m_ThermalWidth;
744 }
745 
746 
748 {
749  MODULE* module = GetParent();
750 
751  if( m_ThermalGap == 0 && module )
752  return module->GetThermalGap();
753  else
754  return m_ThermalGap;
755 }
756 
757 
758 void D_PAD::GetMsgPanelInfo( EDA_UNITS aUnits, std::vector<MSG_PANEL_ITEM>& aList )
759 {
760  MODULE* module;
761  wxString msg;
762  BOARD* board;
763 
764  module = (MODULE*) m_Parent;
765 
766  if( module )
767  {
768  aList.emplace_back( _( "Footprint" ), module->GetReference(), DARKCYAN );
769  }
770 
771  aList.emplace_back( _( "Pad" ), m_name, BROWN );
772 
773  if( !GetPinFunction().IsEmpty() )
774  aList.emplace_back( _( "Pin fct" ), GetPinFunction(), BROWN );
775 
776  aList.emplace_back( _( "Net" ), UnescapeString( GetNetname() ), DARKCYAN );
777 
778  board = GetBoard();
779 
780  aList.emplace_back( _( "Layer" ),
782 
783  // Show the pad shape, attribute and property
784  wxString props = ShowPadAttr();
785 
786  if( GetProperty() != PAD_PROP_NONE )
787  props += ',';
788 
789  switch( GetProperty() )
790  {
791  case PAD_PROP_NONE: break;
792  case PAD_PROP_BGA: props += _("BGA" ); break;
793  case PAD_PROP_FIDUCIAL_GLBL: props += _("Fiducial global" ); break;
794  case PAD_PROP_FIDUCIAL_LOCAL: props += _("Fiducial local" ); break;
795  case PAD_PROP_TESTPOINT: props += _("Test point" ); break;
796  case PAD_PROP_HEATSINK: props += _("Heat sink" ); break;
797  case PAD_PROP_CASTELLATED: props += _("Castellated" ); break;
798  }
799 
800  aList.emplace_back( ShowPadShape(), props, DARKGREEN );
801 
802  msg = MessageTextFromValue( aUnits, m_Size.x, true );
803  aList.emplace_back( _( "Width" ), msg, RED );
804 
805  msg = MessageTextFromValue( aUnits, m_Size.y, true );
806  aList.emplace_back( _( "Height" ), msg, RED );
807 
808  msg = MessageTextFromValue( aUnits, m_Drill.x, true );
809 
811  {
812  aList.emplace_back( _( "Drill" ), msg, RED );
813  }
814  else
815  {
816  msg = MessageTextFromValue( aUnits, m_Drill.x, true )
817  + wxT( "/" )
818  + MessageTextFromValue( aUnits, m_Drill.y, true );
819  aList.emplace_back( _( "Drill X / Y" ), msg, RED );
820  }
821 
822  double module_orient_degrees = module ? module->GetOrientationDegrees() : 0;
823 
824  if( module_orient_degrees != 0.0 )
825  msg.Printf( wxT( "%3.1f(+%3.1f)" ),
826  GetOrientationDegrees() - module_orient_degrees,
827  module_orient_degrees );
828  else
829  msg.Printf( wxT( "%3.1f" ), GetOrientationDegrees() );
830 
831  aList.emplace_back( _( "Angle" ), msg, LIGHTBLUE );
832 
833  msg = MessageTextFromValue( aUnits, m_Pos.x )
834  + wxT( ", " )
835  + MessageTextFromValue( aUnits, m_Pos.y );
836  aList.emplace_back( _( "Position" ), msg, LIGHTBLUE );
837 
838  if( GetPadToDieLength() )
839  {
840  msg = MessageTextFromValue( aUnits, GetPadToDieLength(), true );
841  aList.emplace_back( _( "Length in package" ), msg, CYAN );
842  }
843 }
844 
845 
847  wxPoint& aEndPoint, int& aWidth ) const
848 {
849  // calculates the start point, end point and width
850  // of an equivalent segment which have the same position and width as the hole
851  int delta_cx, delta_cy;
852 
853  wxSize halfsize = GetDrillSize();
854  halfsize.x /= 2;
855  halfsize.y /= 2;
856 
857  if( m_Drill.x > m_Drill.y ) // horizontal
858  {
859  delta_cx = halfsize.x - halfsize.y;
860  delta_cy = 0;
861  aWidth = m_Drill.y;
862  }
863  else // vertical
864  {
865  delta_cx = 0;
866  delta_cy = halfsize.y - halfsize.x;
867  aWidth = m_Drill.x;
868  }
869 
870  RotatePoint( &delta_cx, &delta_cy, m_Orient );
871 
872  aStartPoint.x = delta_cx;
873  aStartPoint.y = delta_cy;
874 
875  aEndPoint.x = - delta_cx;
876  aEndPoint.y = - delta_cy;
877 }
878 
879 
880 bool D_PAD::HitTest( const wxPoint& aPosition, int aAccuracy ) const
881 {
882  int dx, dy;
883 
884  wxPoint shape_pos = ShapePos();
885 
886  wxPoint delta = aPosition - shape_pos;
887 
888  // first test: a test point must be inside a minimum sized bounding circle.
889  int radius = GetBoundingRadius();
890 
891  if( ( abs( delta.x ) > radius ) || ( abs( delta.y ) > radius ) )
892  return false;
893 
894  dx = m_Size.x >> 1; // dx also is the radius for rounded pads
895  dy = m_Size.y >> 1;
896 
897  switch( GetShape() )
898  {
899  case PAD_SHAPE_CIRCLE:
900  if( KiROUND( EuclideanNorm( delta ) ) <= dx )
901  return true;
902 
903  break;
904 
905  case PAD_SHAPE_TRAPEZOID:
906  {
907  wxPoint poly[4];
908  BuildPadPolygon( poly, wxSize(0,0), 0 );
909  RotatePoint( &delta, -m_Orient );
910 
911  return TestPointInsidePolygon( poly, 4, delta );
912  }
913 
914  case PAD_SHAPE_OVAL:
915  {
916  RotatePoint( &delta, -m_Orient );
917  // An oval pad has the same shape as a segment with rounded ends
918  // After rotation, the test point is relative to an horizontal pad
919  int dist;
920  wxPoint offset;
921  if( dy > dx ) // shape is a vertical oval
922  {
923  offset.y = dy - dx;
924  dist = dx;
925  }
926  else //if( dy <= dx ) shape is an horizontal oval
927  {
928  offset.x = dy - dx;
929  dist = dy;
930  }
931  return TestSegmentHit( delta, - offset, offset, dist );
932  }
933  break;
934 
935  case PAD_SHAPE_RECT:
936  RotatePoint( &delta, -m_Orient );
937 
938  if( (abs( delta.x ) <= dx ) && (abs( delta.y ) <= dy) )
939  return true;
940 
941  break;
942 
944  case PAD_SHAPE_ROUNDRECT:
945  {
946  // Check for hit in polygon
947  SHAPE_POLY_SET outline;
948  bool doChamfer = GetShape() == PAD_SHAPE_CHAMFERED_RECT;
949  auto board = GetBoard();
950  int maxError = ARC_HIGH_DEF;
951 
952  if( board )
953  maxError = board->GetDesignSettings().m_MaxError;
954 
957  doChamfer ? GetChamferRectRatio() : 0.0,
958  doChamfer ? GetChamferPositions() : 0,
959  maxError );
960 
961  const SHAPE_LINE_CHAIN &poly = outline.COutline( 0 );
962  return TestPointInsidePolygon( (const wxPoint*)&poly.CPoint(0), poly.PointCount(), delta );
963  }
964  break;
965 
966  case PAD_SHAPE_CUSTOM:
967  // Check for hit in polygon
968  RotatePoint( &delta, -m_Orient );
969 
971  {
973  return TestPointInsidePolygon( (const wxPoint*)&poly.CPoint(0), poly.PointCount(), delta );
974  }
975  break;
976  }
977 
978  return false;
979 }
980 
981 
982 bool D_PAD::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
983 {
984  EDA_RECT arect = aRect;
985  arect.Normalize();
986  arect.Inflate( aAccuracy );
987 
988  wxPoint shapePos = ShapePos();
989 
990  EDA_RECT shapeRect;
991 
992  int r;
993 
994  EDA_RECT bb = GetBoundingBox();
995 
996  wxPoint endCenter;
997  int radius;
998 
999  if( !arect.Intersects( bb ) )
1000  return false;
1001 
1002  // This covers total containment for all test cases
1003  if( arect.Contains( bb ) )
1004  return true;
1005 
1006  switch( GetShape() )
1007  {
1008  case PAD_SHAPE_CIRCLE:
1009  return arect.IntersectsCircle( GetPosition(), GetBoundingRadius() );
1010 
1011  case PAD_SHAPE_RECT:
1012  case PAD_SHAPE_CHAMFERED_RECT: // TODO use a finer shape analysis
1013  shapeRect.SetOrigin( shapePos );
1014  shapeRect.Inflate( m_Size.x / 2, m_Size.y / 2 );
1015  return arect.Intersects( shapeRect, m_Orient );
1016 
1017  case PAD_SHAPE_OVAL:
1018  // Circlular test if dimensions are equal
1019  if( m_Size.x == m_Size.y )
1020  return arect.IntersectsCircle( shapePos, GetBoundingRadius() );
1021 
1022  shapeRect.SetOrigin( shapePos );
1023 
1024  // Horizontal dimension is greater
1025  if( m_Size.x > m_Size.y )
1026  {
1027  radius = m_Size.y / 2;
1028 
1029  shapeRect.Inflate( m_Size.x / 2 - radius, radius );
1030 
1031  endCenter = wxPoint( m_Size.x / 2 - radius, 0 );
1032  RotatePoint( &endCenter, m_Orient );
1033 
1034  // Test circular ends
1035  if( arect.IntersectsCircle( shapePos + endCenter, radius ) ||
1036  arect.IntersectsCircle( shapePos - endCenter, radius ) )
1037  {
1038  return true;
1039  }
1040  }
1041  else
1042  {
1043  radius = m_Size.x / 2;
1044 
1045  shapeRect.Inflate( radius, m_Size.y / 2 - radius );
1046 
1047  endCenter = wxPoint( 0, m_Size.y / 2 - radius );
1048  RotatePoint( &endCenter, m_Orient );
1049 
1050  // Test circular ends
1051  if( arect.IntersectsCircle( shapePos + endCenter, radius ) ||
1052  arect.IntersectsCircle( shapePos - endCenter, radius ) )
1053  {
1054  return true;
1055  }
1056  }
1057 
1058  // Test rectangular portion between rounded ends
1059  if( arect.Intersects( shapeRect, m_Orient ) )
1060  {
1061  return true;
1062  }
1063 
1064  break;
1065 
1066  case PAD_SHAPE_TRAPEZOID:
1067  /* Trapezoid intersection tests:
1068  * A) Any points of rect inside trapezoid
1069  * B) Any points of trapezoid inside rect
1070  * C) Any sides of trapezoid cross rect
1071  */
1072  {
1073 
1074  wxPoint poly[4];
1075  BuildPadPolygon( poly, wxSize( 0, 0 ), 0 );
1076 
1077  wxPoint corners[4];
1078 
1079  corners[0] = wxPoint( arect.GetLeft(), arect.GetTop() );
1080  corners[1] = wxPoint( arect.GetRight(), arect.GetTop() );
1081  corners[2] = wxPoint( arect.GetRight(), arect.GetBottom() );
1082  corners[3] = wxPoint( arect.GetLeft(), arect.GetBottom() );
1083 
1084  for( int i=0; i<4; i++ )
1085  {
1086  RotatePoint( &poly[i], m_Orient );
1087  poly[i] += shapePos;
1088  }
1089 
1090  for( int ii=0; ii<4; ii++ )
1091  {
1092  if( TestPointInsidePolygon( poly, 4, corners[ii] ) )
1093  {
1094  return true;
1095  }
1096 
1097  if( arect.Contains( poly[ii] ) )
1098  {
1099  return true;
1100  }
1101 
1102  if( arect.Intersects( poly[ii], poly[(ii+1) % 4] ) )
1103  {
1104  return true;
1105  }
1106  }
1107 
1108  return false;
1109  }
1110 
1111  case PAD_SHAPE_ROUNDRECT:
1112  /* RoundRect intersection can be broken up into simple tests:
1113  * a) Test intersection of horizontal rect
1114  * b) Test intersection of vertical rect
1115  * c) Test intersection of each corner
1116  */
1118 
1119  /* Test A - intersection of horizontal rect */
1120  shapeRect.SetSize( 0, 0 );
1121  shapeRect.SetOrigin( shapePos );
1122  shapeRect.Inflate( m_Size.x / 2, m_Size.y / 2 - r );
1123 
1124  // Short-circuit test for zero width or height
1125  if( shapeRect.GetWidth() > 0 && shapeRect.GetHeight() > 0 &&
1126  arect.Intersects( shapeRect, m_Orient ) )
1127  {
1128  return true;
1129  }
1130 
1131  /* Test B - intersection of vertical rect */
1132  shapeRect.SetSize( 0, 0 );
1133  shapeRect.SetOrigin( shapePos );
1134  shapeRect.Inflate( m_Size.x / 2 - r, m_Size.y / 2 );
1135 
1136  // Short-circuit test for zero width or height
1137  if( shapeRect.GetWidth() > 0 && shapeRect.GetHeight() > 0 &&
1138  arect.Intersects( shapeRect, m_Orient ) )
1139  {
1140  return true;
1141  }
1142 
1143  /* Test C - intersection of each corner */
1144 
1145  endCenter = wxPoint( m_Size.x / 2 - r, m_Size.y / 2 - r );
1146  RotatePoint( &endCenter, m_Orient );
1147 
1148  if( arect.IntersectsCircle( shapePos + endCenter, r ) ||
1149  arect.IntersectsCircle( shapePos - endCenter, r ) )
1150  {
1151  return true;
1152  }
1153 
1154  endCenter = wxPoint( m_Size.x / 2 - r, -m_Size.y / 2 + r );
1155  RotatePoint( &endCenter, m_Orient );
1156 
1157  if( arect.IntersectsCircle( shapePos + endCenter, r ) ||
1158  arect.IntersectsCircle( shapePos - endCenter, r ) )
1159  {
1160  return true;
1161  }
1162 
1163  break;
1164 
1165  default:
1166  break;
1167  }
1168 
1169  return false;
1170 }
1171 
1172 int D_PAD::Compare( const D_PAD* padref, const D_PAD* padcmp )
1173 {
1174  int diff;
1175 
1176  if( ( diff = padref->GetShape() - padcmp->GetShape() ) != 0 )
1177  return diff;
1178 
1179  if( ( diff = padref->GetDrillShape() - padcmp->GetDrillShape() ) != 0)
1180  return diff;
1181 
1182  if( ( diff = padref->m_Drill.x - padcmp->m_Drill.x ) != 0 )
1183  return diff;
1184 
1185  if( ( diff = padref->m_Drill.y - padcmp->m_Drill.y ) != 0 )
1186  return diff;
1187 
1188  if( ( diff = padref->m_Size.x - padcmp->m_Size.x ) != 0 )
1189  return diff;
1190 
1191  if( ( diff = padref->m_Size.y - padcmp->m_Size.y ) != 0 )
1192  return diff;
1193 
1194  if( ( diff = padref->m_Offset.x - padcmp->m_Offset.x ) != 0 )
1195  return diff;
1196 
1197  if( ( diff = padref->m_Offset.y - padcmp->m_Offset.y ) != 0 )
1198  return diff;
1199 
1200  if( ( diff = padref->m_DeltaSize.x - padcmp->m_DeltaSize.x ) != 0 )
1201  return diff;
1202 
1203  if( ( diff = padref->m_DeltaSize.y - padcmp->m_DeltaSize.y ) != 0 )
1204  return diff;
1205 
1206 // TODO: test custom shapes
1207 
1208  // Dick: specctra_export needs this
1209  // Lorenzo: gencad also needs it to implement padstacks!
1210 
1211 #if __cplusplus >= 201103L
1212  long long d = padref->m_layerMask.to_ullong() - padcmp->m_layerMask.to_ullong();
1213  if( d < 0 )
1214  return -1;
1215  else if( d > 0 )
1216  return 1;
1217 
1218  return 0;
1219 #else
1220  // these strings are not typically constructed, since we don't get here often.
1221  std::string s1 = padref->m_layerMask.to_string();
1222  std::string s2 = padcmp->m_layerMask.to_string();
1223  return s1.compare( s2 );
1224 #endif
1225 }
1226 
1227 
1228 void D_PAD::Rotate( const wxPoint& aRotCentre, double aAngle )
1229 {
1230  RotatePoint( &m_Pos, aRotCentre, aAngle );
1231 
1232  m_Orient = NormalizeAngle360Min( m_Orient + aAngle );
1233 
1234  SetLocalCoord();
1235 }
1236 
1237 
1238 wxString D_PAD::ShowPadShape() const
1239 {
1240  switch( GetShape() )
1241  {
1242  case PAD_SHAPE_CIRCLE:
1243  return _( "Circle" );
1244 
1245  case PAD_SHAPE_OVAL:
1246  return _( "Oval" );
1247 
1248  case PAD_SHAPE_RECT:
1249  return _( "Rect" );
1250 
1251  case PAD_SHAPE_TRAPEZOID:
1252  return _( "Trap" );
1253 
1254  case PAD_SHAPE_ROUNDRECT:
1255  return _( "Roundrect" );
1256 
1258  return _( "Chamferedrect" );
1259 
1260  case PAD_SHAPE_CUSTOM:
1261  return _( "CustomShape" );
1262 
1263  default:
1264  return wxT( "???" );
1265  }
1266 }
1267 
1268 
1269 wxString D_PAD::ShowPadAttr() const
1270 {
1271  switch( GetAttribute() )
1272  {
1273  case PAD_ATTRIB_STANDARD:
1274  return _( "Std" );
1275 
1276  case PAD_ATTRIB_SMD:
1277  return _( "SMD" );
1278 
1279  case PAD_ATTRIB_CONN:
1280  return _( "Conn" );
1281 
1283  return _( "Not Plated" );
1284 
1285  default:
1286  return wxT( "???" );
1287  }
1288 }
1289 
1290 
1291 wxString D_PAD::GetSelectMenuText( EDA_UNITS aUnits ) const
1292 {
1293  if( GetName().IsEmpty() )
1294  {
1295  return wxString::Format( _( "Pad of %s on %s" ),
1296  GetParent()->GetReference(),
1298  }
1299  else
1300  {
1301  return wxString::Format( _( "Pad %s of %s on %s" ),
1302  GetName(),
1303  GetParent()->GetReference(),
1305  }
1306 }
1307 
1308 
1310 {
1311  return pad_xpm;
1312 }
1313 
1314 
1316 {
1317  return new D_PAD( *this );
1318 }
1319 
1320 
1322 {
1323  return( m_Attribute == PAD_ATTRIB_STANDARD
1324  && m_Drill.x >= m_Size.x && m_Drill.y >= m_Size.y );
1325 }
1326 
1327 
1328 void D_PAD::ViewGetLayers( int aLayers[], int& aCount ) const
1329 {
1330  aCount = 0;
1331 
1332  // These 2 types of pads contain a hole
1334  aLayers[aCount++] = LAYER_PADS_PLATEDHOLES;
1335 
1337  aLayers[aCount++] = LAYER_NON_PLATEDHOLES;
1338 
1339  if( IsOnLayer( F_Cu ) && IsOnLayer( B_Cu ) )
1340  {
1341  // Multi layer pad
1342  aLayers[aCount++] = LAYER_PADS_TH;
1343  aLayers[aCount++] = LAYER_PADS_NETNAMES;
1344  }
1345  else if( IsOnLayer( F_Cu ) )
1346  {
1347  aLayers[aCount++] = LAYER_PAD_FR;
1348 
1349  // Is this a PTH pad that has only front copper? If so, we need to also display the
1350  // net name on the PTH netname layer so that it isn't blocked by the drill hole.
1352  aLayers[aCount++] = LAYER_PADS_NETNAMES;
1353  else
1354  aLayers[aCount++] = LAYER_PAD_FR_NETNAMES;
1355  }
1356  else if( IsOnLayer( B_Cu ) )
1357  {
1358  aLayers[aCount++] = LAYER_PAD_BK;
1359 
1360  // Is this a PTH pad that has only back copper? If so, we need to also display the
1361  // net name on the PTH netname layer so that it isn't blocked by the drill hole.
1363  aLayers[aCount++] = LAYER_PADS_NETNAMES;
1364  else
1365  aLayers[aCount++] = LAYER_PAD_BK_NETNAMES;
1366  }
1367 
1368  // Check non-copper layers. This list should include all the layers that the
1369  // footprint editor allows a pad to be placed on.
1370  static const PCB_LAYER_ID layers_mech[] = { F_Mask, B_Mask, F_Paste, B_Paste,
1372 
1373  for( PCB_LAYER_ID each_layer : layers_mech )
1374  {
1375  if( IsOnLayer( each_layer ) )
1376  aLayers[aCount++] = each_layer;
1377  }
1378 
1379 #ifdef __WXDEBUG__
1380  if( aCount == 0 ) // Should not occur
1381  {
1382  wxString msg;
1383  msg.Printf( wxT( "footprint %s, pad %s: could not find valid layer for pad" ),
1384  GetParent() ? GetParent()->GetReference() : "<null>",
1385  GetName().IsEmpty() ? "(unnamed)" : GetName() );
1386  wxLogWarning( msg );
1387  }
1388 #endif
1389 }
1390 
1391 
1392 unsigned int D_PAD::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const
1393 {
1394  if( aView->GetPrintMode() > 0 ) // In printing mode the pad is always drawable
1395  return 0;
1396 
1397  const int HIDE = std::numeric_limits<unsigned int>::max();
1398  BOARD* board = GetBoard();
1399 
1400  // Handle Render tab switches
1402  && !aView->IsLayerVisible( LAYER_PADS_TH ) )
1403  return HIDE;
1404 
1405  if( !IsFlipped() && !aView->IsLayerVisible( LAYER_MOD_FR ) )
1406  return HIDE;
1407 
1408  if( IsFlipped() && !aView->IsLayerVisible( LAYER_MOD_BK ) )
1409  return HIDE;
1410 
1411  if( IsFrontLayer( ( PCB_LAYER_ID )aLayer ) && !aView->IsLayerVisible( LAYER_PAD_FR ) )
1412  return HIDE;
1413 
1414  if( IsBackLayer( ( PCB_LAYER_ID )aLayer ) && !aView->IsLayerVisible( LAYER_PAD_BK ) )
1415  return HIDE;
1416 
1417  // Only draw the pad if at least one of the layers it crosses is being displayed
1418  if( board && !( board->GetVisibleLayers() & GetLayerSet() ).any() )
1419  return HIDE;
1420 
1421  // Netnames will be shown only if zoom is appropriate
1422  if( IsNetnameLayer( aLayer ) )
1423  {
1424  int divisor = std::max( m_Size.x, m_Size.y );
1425 
1426  // Pad sizes can be zero briefly when someone is typing a number like "0.5"
1427  // in the pad properties dialog
1428  if( divisor == 0 )
1429  return HIDE;
1430 
1431  return ( Millimeter2iu( 10 ) / divisor );
1432  }
1433 
1434  // Other layers are shown without any conditions
1435  return 0;
1436 }
1437 
1438 
1439 const BOX2I D_PAD::ViewBBox() const
1440 {
1441  // Bounding box includes soldermask too
1442  int solderMaskMargin = GetSolderMaskMargin();
1443  VECTOR2I solderPasteMargin = VECTOR2D( GetSolderPasteMargin() );
1444  EDA_RECT bbox = GetBoundingBox();
1445 
1446  // Look for the biggest possible bounding box
1447  int xMargin = std::max( solderMaskMargin, solderPasteMargin.x );
1448  int yMargin = std::max( solderMaskMargin, solderPasteMargin.y );
1449 
1450  return BOX2I( VECTOR2I( bbox.GetOrigin() ) - VECTOR2I( xMargin, yMargin ),
1451  VECTOR2I( bbox.GetSize() ) + VECTOR2I( 2 * xMargin, 2 * yMargin ) );
1452 }
1453 
1454 
1455 wxString LayerMaskDescribe( const BOARD *aBoard, LSET aMask )
1456 {
1457  // Try to be smart and useful. Check all copper first.
1458  if( aMask[F_Cu] && aMask[B_Cu] )
1459  return _( "All copper layers" );
1460 
1461  // Check for copper.
1462  auto layer = aBoard->GetEnabledLayers().AllCuMask() & aMask;
1463 
1464  for( int i = 0; i < 2; i++ )
1465  {
1466  for( int bit = PCBNEW_LAYER_ID_START; bit < PCB_LAYER_ID_COUNT; ++bit )
1467  {
1468  if( layer[ bit ] )
1469  {
1470  wxString layerInfo = aBoard->GetLayerName( static_cast<PCB_LAYER_ID>( bit ) );
1471 
1472  if( aMask.count() > 1 )
1473  layerInfo << _( " and others" );
1474 
1475  return layerInfo;
1476  }
1477  }
1478 
1479  // No copper; check for technicals.
1480  layer = aBoard->GetEnabledLayers().AllTechMask() & aMask;
1481  }
1482 
1483  // No copper, no technicals: no layer
1484  return _( "no layers" );
1485 }
1486 
1487 
1488 void D_PAD::ImportSettingsFrom( const D_PAD& aMasterPad )
1489 {
1490  SetShape( aMasterPad.GetShape() );
1491  SetLayerSet( aMasterPad.GetLayerSet() );
1492  SetAttribute( aMasterPad.GetAttribute() );
1493  SetProperty( aMasterPad.GetProperty() );
1494 
1495  // The pad orientation, for historical reasons is the
1496  // pad rotation + parent rotation.
1497  // So we have to manage this parent rotation
1498  double pad_rot = aMasterPad.GetOrientation();
1499 
1500  if( aMasterPad.GetParent() )
1501  pad_rot -= aMasterPad.GetParent()->GetOrientation();
1502 
1503  if( GetParent() )
1504  pad_rot += GetParent()->GetOrientation();
1505 
1506  SetOrientation( pad_rot );
1507 
1508  SetSize( aMasterPad.GetSize() );
1509  SetDelta( wxSize( 0, 0 ) );
1510  SetOffset( aMasterPad.GetOffset() );
1511  SetDrillSize( aMasterPad.GetDrillSize() );
1512  SetDrillShape( aMasterPad.GetDrillShape() );
1514  SetChamferRectRatio( aMasterPad.GetChamferRectRatio() );
1515  SetChamferPositions( aMasterPad.GetChamferPositions() );
1516 
1517  switch( aMasterPad.GetShape() )
1518  {
1519  case PAD_SHAPE_TRAPEZOID:
1520  SetDelta( aMasterPad.GetDelta() );
1521  break;
1522 
1523  case PAD_SHAPE_CIRCLE:
1524  // ensure size.y == size.x
1525  SetSize( wxSize( GetSize().x, GetSize().x ) );
1526  break;
1527 
1528  default:
1529  ;
1530  }
1531 
1532  switch( aMasterPad.GetAttribute() )
1533  {
1534  case PAD_ATTRIB_SMD:
1535  case PAD_ATTRIB_CONN:
1536  // These pads do not have hole (they are expected to be only on one
1537  // external copper layer)
1538  SetDrillSize( wxSize( 0, 0 ) );
1539  break;
1540 
1541  default:
1542  ;
1543  }
1544 
1545  // copy also local settings:
1546  SetLocalClearance( aMasterPad.GetLocalClearance() );
1550 
1551  SetZoneConnection( aMasterPad.GetZoneConnection() );
1552  SetThermalWidth( aMasterPad.GetThermalWidth() );
1553  SetThermalGap( aMasterPad.GetThermalGap() );
1554 
1555  // Add or remove custom pad shapes:
1556  SetPrimitives( aMasterPad.GetPrimitives() );
1557  SetAnchorPadShape( aMasterPad.GetAnchorPadShape() );
1559 }
1560 
1562 {
1563  assert( aImage->Type() == PCB_PAD_T );
1564 
1565  std::swap( *((MODULE*) this), *((MODULE*) aImage) );
1566 }
int m_LocalClearance
Local clearance.
Definition: class_pad.h:939
double EuclideanNorm(const wxPoint &vector)
Euclidean norm of a 2D vector.
Definition: trigo.h:128
int m_ThermalGap
Definition: class_pad.h:952
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:686
EDA_UNITS
Definition: common.h:184
int m_LocalSolderMaskMargin
Local mask margins: when 0, the parent footprint design values are used.
Definition: class_pad.h:943
BITMAP_DEF GetMenuImage() const override
Function GetMenuImage returns a pointer to an image to be used in menus.
Definition: class_pad.cpp:1309
bool IncrementPadName(bool aSkipUnconnectable, bool aFillSequenceGaps)
Function IncrementPadName.
Definition: class_pad.cpp:585
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:143
int m_SolderMaskMargin
Solder mask margin.
ZONE_CONNECTION
How pads are covered by copper in zone.
Definition: zones.h:41
double m_padRoundRectRadiusScale
scaling factor from smallest m_Size coord to corner radius, default 0.25
Definition: class_pad.h:894
int GetLocalSolderMaskMargin() const
Definition: class_pad.h:461
double GetOrientation() const
Definition: class_module.h:215
int m_boundingRadius
radius of the circle containing the pad shape
Definition: class_pad.h:851
EDA_ITEM * Clone() const override
Function Clone creates a duplicate of this item with linked list members set to NULL.
Definition: class_pad.cpp:1315
BOX2< VECTOR2I > BOX2I
Definition: box2.h:521
EDA_ITEM * m_Parent
Linked list: Link (parent struct)
Definition: base_struct.h:183
LSET FlipLayerMask(LSET aMask, int aCopperLayersCount)
Calculate the mask layer when flipping a footprint BACK and FRONT copper layers, mask,...
Definition: lset.cpp:531
std::vector< PAD_CS_PRIMITIVE > m_basicShapes
for free shape pads: a list of basic shapes, in local coordinates, orient 0, coordinates relative to ...
Definition: class_pad.h:868
double m_padChamferRectScale
scaling factor from smallest m_Size coord to chamfer value, default 0.25
Definition: class_pad.h:896
int OutlineCount() const
Returns the number of outlines in the set
static LSET StandardMask()
layer set for a through hole pad
Definition: class_pad.cpp:104
bool HitTest(const wxPoint &aPosition, int aAccuracy=0) const override
Function HitTest tests if aPosition is contained within or on the bounding box of an item.
Definition: class_pad.cpp:880
void Merge(const EDA_RECT &aRect)
Function Merge modifies the position and size of the rectangle in order to contain aRect.
void FlipPrimitives()
Flip the basic shapes, in custom pads.
Definition: class_pad.cpp:478
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Function GetLayerName returns the name of a layer given by aLayer.
PNG memory record (file in memory).
Definition: bitmap_def.h:29
static const int dist[10][10]
Definition: ar_matrix.cpp:326
no special fabrication property
Definition: pad_shapes.h:78
like PAD_STANDARD, but not plated mechanical use only, no connection allowed
Definition: pad_shapes.h:66
void Rotate(const wxPoint &aRotCentre, double aAngle) override
Function Rotate Rotate this object.
Definition: class_pad.cpp:1228
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:59
const BITMAP_OPAQUE pad_xpm[1]
Definition: pad.cpp:41
int m_LocalSolderPasteMargin
Local solder paste margin absolute value.
Definition: class_pad.h:944
multilayer pads, usually with holes
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:125
BOARD_ITEM is a base class for any item which can be embedded within the BOARD container class,...
PAD_SHAPE_T GetAnchorPadShape() const
Function GetAnchorPadShape.
Definition: class_pad.h:247
static LSET SMDMask()
layer set for a SMD pad on Front layer
Definition: class_pad.cpp:111
int GetTop() const
Definition: eda_rect.h:123
handle color for not plated holes (holes, not pads)
bool IsBackLayer(PCB_LAYER_ID aLayerId)
Layer classification: check if it's a back layer.
D_PAD(MODULE *parent)
Definition: class_pad.cpp:60
a fiducial (usually a smd) for the full board
Definition: pad_shapes.h:80
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:846
int GetLeft() const
Definition: eda_rect.h:122
double GetOrientationDegrees() const
Definition: class_pad.h:427
wxPoint m_Start
angle of an arc, from its starting point, in 0.1 deg
Definition: class_pad.h:98
polygon (not yet used for tracks, but could be in microwave apps)
ZONE_CONNECTION GetZoneConnection() const
Definition: class_module.h:248
bool IsFlipped() const
Definition: class_pad.cpp:139
wxSize m_Size
X and Y size ( relative to orient 0)
Definition: class_pad.h:890
int GetPadToDieLength() const
Definition: class_pad.h:459
Smd pad, appears on the solder paste layer (default)
Definition: pad_shapes.h:62
int GetWidth() const
Definition: eda_rect.h:119
LSET GetVisibleLayers() const
Function GetVisibleLayers is a proxy function that calls the correspondent function in m_BoardSetting...
bool IntersectsCircle(const wxPoint &aCenter, const int aRadius) const
Function IntersectsCircle tests for a common area between a circle and this rectangle.
void SetOrigin(const wxPoint &pos)
Definition: eda_rect.h:131
Smd pad, used in BGA footprints.
Definition: pad_shapes.h:79
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:512
class D_PAD, a pad in a footprint
Definition: typeinfo.h:90
void SetSubRatsnest(int aSubRatsnest)
Definition: class_pad.h:742
void SetDrillSize(const wxSize &aSize)
Definition: class_pad.h:305
LSET GetEnabledLayers() const
Function GetEnabledLayers is a proxy function that calls the corresponding function in m_BoardSetting...
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:208
void NORMALIZE_ANGLE_POS(T &Angle)
Definition: trigo.h:257
a pad used as heat sink, usually in SMD footprints
Definition: pad_shapes.h:83
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:687
const wxString & GetPinFunction() const
Definition: class_pad.h:211
wxString ShowPadAttr() const
Function ShowPadAttr.
Definition: class_pad.cpp:1269
static LSET AllTechMask()
Function AllTechMask returns a mask holding all technical layers (no CU layer) on both side.
Definition: lset.cpp:756
PAD_PROP_T m_Property
property in fab files (BGA, FIDUCIAL, TEST POINT, CASTELLATED)
Definition: class_pad.h:930
VECTOR2< int > VECTOR2I
Definition: vector2d.h:594
int GetThermalGap() const
Definition: class_pad.cpp:747
int GetLocalSolderMaskMargin() const
Definition: class_module.h:231
int PointCount() const
Function PointCount()
BOARD_CONNECTED_ITEM is a base class derived from BOARD_ITEM for items that can be connected and have...
Configuration parameter - Integer Class with unit conversion.
int GetLocalClearance() const
Definition: class_pad.h:464
bool Contains(const wxPoint &aPoint) const
Function Contains.
void SetLocalCoord()
Set relative coordinates.
Definition: class_pad.cpp:408
PAD_ATTR_T GetAttribute() const
Definition: class_pad.h:449
void Mirror(bool aX=true, bool aY=false, const VECTOR2I &aRef={ 0, 0 })
Mirrors the line points about y or x (or both)
This file contains miscellaneous commonly used macros and functions.
int GetBottom() const
Definition: eda_rect.h:124
const wxString GetReference() const
Function GetReference.
Definition: class_module.h:436
int GetChamferPositions() const
has meaning only for chamfered rect pads
Definition: class_pad.h:724
a pad with a castellated through hole
Definition: pad_shapes.h:84
bool TestSegmentHit(const wxPoint &aRefPoint, wxPoint aStart, wxPoint aEnd, int aDist)
Test if aRefPoint is with aDistance on the line defined by aStart and aEnd.
Definition: trigo.cpp:129
show modules on front
ZONE_CONNECTION m_ZoneConnection
how the connection to zone is made: no connection, thermal relief ...
Definition: class_pad.h:949
void MIRROR(T &aPoint, const T &aMirrorRef)
Definition: macros.h:123
const VECTOR2I & CPoint(int aIndex) const
Function Point()
class MODULE, a footprint
Definition: typeinfo.h:89
void SetAnchorPadShape(PAD_SHAPE_T aShape)
Function SetAnchorPadShape Set the shape of the anchor pad for custm shped pads.
Definition: class_pad.h:274
int GetSolderMaskMargin() const
Function GetSolderMaskMargin.
Definition: class_pad.cpp:627
PCB_LAYER_ID
A quick note on layer IDs:
wxString m_name
pad name (pin number in schematic)
Definition: class_pad.h:853
virtual const BOX2I ViewBBox() const override
Function ViewBBox() returns the bounding box of the item covering all its layers.
Definition: class_pad.cpp:1439
LSET is a set of PCB_LAYER_IDs.
const std::vector< PAD_CS_PRIMITIVE > & GetPrimitives() const
Accessor to the basic shape list.
Definition: class_pad.h:373
std::vector< wxPoint > m_Poly
Bezier Control point 2.
Definition: class_pad.h:102
int GetLocalClearance() const
Definition: class_module.h:234
#define NULL
VECTOR2< double > VECTOR2D
Definition: vector2d.h:593
bool MergePrimitivesAsPolygon(SHAPE_POLY_SET *aMergedPolygon=NULL)
Merge all basic shapes, converted to a polygon in one polygon, in m_customShapeAsPolygon.
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:187
SHAPE_POLY_SET.
SHAPE_LINE_CHAIN & Outline(int aIndex)
Returns the reference to aIndex-th outline in the set
const wxPoint GetOrigin() const
Definition: eda_rect.h:114
wxString ShowPadShape() const
Function ShowPadShape.
Definition: class_pad.cpp:1238
void SetEnd(int x, int y)
Definition: eda_rect.h:192
wxString GetSelectMenuText(EDA_UNITS aUnits) const override
Function GetSelectMenuText returns the text to display to be used in the selection clarification cont...
Definition: class_pad.cpp:1291
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:1172
const EDA_RECT GetBoundingBoxRotated(wxPoint aRotCenter, double aAngle)
Function GetBoundingBoxRotated.
const wxPoint & GetOffset() const
Definition: class_pad.h:309
ZONE_CONNECTION GetZoneConnection() const
Definition: class_pad.cpp:725
PAD_DRILL_SHAPE_T GetDrillShape() const
Definition: class_pad.h:432
double GetChamferRectRatio() const
has meaning only for chamfered rect pads
Definition: class_pad.h:701
int GetThermalWidth() const
Definition: class_pad.cpp:736
Helper class to handle a primitive (basic shape: polygon, segment, circle or arc) to build a custom p...
Definition: class_pad.h:89
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:446
virtual BOARD * GetBoard() const
Function GetBoard returns the BOARD in which this BOARD_ITEM resides, or NULL if none.
int GetRight() const
Definition: eda_rect.h:121
Definition: colors.h:59
CUST_PAD_SHAPE_IN_ZONE m_customShapeClearanceArea
How to build the custom shape in zone, to create the clearance area: CUST_PAD_SHAPE_IN_ZONE_OUTLINE =...
Definition: class_pad.h:881
void SetThermalWidth(int aWidth)
Definition: class_pad.h:542
const wxString & GetName() const
Definition: class_pad.h:203
void SetSize(const wxSize &aSize)
Definition: class_pad.h:299
int GetBoundingRadius() const
Function GetBoundingRadius returns the radius of a minimum sized circle which fully encloses this pad...
Definition: class_pad.h:653
double GetOrientationDegrees() const
Definition: class_module.h:216
int m_ThermalWidth
Definition: class_pad.h:951
void SetRoundRectCornerRadius(double aRadius)
Set the rounded rectangle radius ratio based on a given radius.
Definition: class_pad.cpp:220
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:1328
PAD_PROP_T
Enum PAD_PROP_T is the set of pad properties used in Gerber files (Draw files, and P&P files) to defi...
Definition: pad_shapes.h:76
a few functions useful in geometry calculations.
Definition: colors.h:60
bool TestPointInsidePolygon(const wxPoint *aPolysList, int aCount, const wxPoint &aRefPoint)
Function TestPointInsidePolygon (overlaid) same as previous, but mainly use wxPoint.
SHAPE_POLY_SET m_customShapeAsPolygon
for free shape pads: the set of basic shapes, merged as one polygon, in local coordinates,...
Definition: class_pad.h:873
void SetZoneConnection(ZONE_CONNECTION aType)
Definition: class_pad.h:530
PAD_PROP_T GetProperty() const
Definition: class_pad.h:452
virtual unsigned int ViewGetLOD(int aLayer, KIGFX::VIEW *aView) const override
Function ViewGetLOD() Returns the level of detail (LOD) of the item.
Definition: class_pad.cpp:1392
const wxSize & GetDelta() const
Definition: class_pad.h:303
const wxString & GetNetname() const
Function GetNetname.
void SetDrawCoord()
Set absolute coordinates.
Definition: class_pad.cpp:392
wxSize m_DeltaSize
delta on rectangular shapes
Definition: class_pad.h:923
wxPoint m_End
is also the center of the circle and arc
Definition: class_pad.h:99
Like smd, does not appear on the solder paste layer (default) note also has a special attribute in Ge...
Definition: pad_shapes.h:63
STROKE_T m_Shape
Definition: class_pad.h:92
void SetAttribute(PAD_ATTR_T aAttribute)
Definition: class_pad.cpp:423
int GetHeight() const
Definition: eda_rect.h:120
int GetLocalSolderPasteMargin() const
Definition: class_module.h:237
void SetLocalClearance(int aClearance)
Definition: class_pad.h:465
int m_chamferPositions
the positions of the chamfered position for a 0 orientation
Definition: class_pad.h:898
void TransformRoundChamferedRectToPolygon(SHAPE_POLY_SET &aCornerBuffer, const wxPoint &aPosition, const wxSize &aSize, double aRotation, int aCornerRadius, double aChamferRatio, int aChamferCorners, int aApproxErrorMax, int aMinSegPerCircleCount=16)
convert a rectangle with rounded corners and/or chamfered corners to a polygon Convert rounded corner...
MODULE * GetParent() const
Definition: class_pad.h:167
void SetLocalSolderPasteMarginRatio(double aRatio)
Definition: class_pad.h:471
void BuildPadPolygon(wxPoint aCoord[4], wxSize aInflateValue, double aRotation) const
Function BuildPadPolygon Has meaning only for polygonal pads (trapezoid and rectangular) Build the Co...
bool IsFrontLayer(PCB_LAYER_ID aLayerId)
Layer classification: check if it's a front layer.
void Normalize()
Function Normalize ensures that the height ant width are positive.
wxString MessageTextFromValue(EDA_UNITS aUnits, int aValue, bool aUseMils, EDA_DATA_TYPE aType)
Definition: base_units.cpp:127
LSET m_layerMask
Bitwise layer :1= copper layer, 15= cmp, 2..14 = internal layers 16 .
Definition: class_pad.h:919
virtual void SwapData(BOARD_ITEM *aImage) override
Swap data between aItem and aImage.
Definition: class_pad.cpp:1561
int GetPrintMode()
Definition: view.h:692
void SetSize(const wxSize &size)
Definition: eda_rect.h:144
void SetLayerSet(LSET aLayerMask)
Definition: class_pad.h:445
double GetLocalSolderPasteMarginRatio() const
Definition: class_module.h:240
smd pads, front layer
a fiducial (usually a smd) local to the parent footprint
Definition: pad_shapes.h:81
void GetMsgPanelInfo(EDA_UNITS aUnits, 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:758
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:430
wxSize GetSolderPasteMargin() const
Function GetSolderPasteMargin.
Definition: class_pad.cpp:673
wxPoint m_Pos0
Initial Pad position (i.e.
Definition: class_pad.h:925
BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:163
void SetLocalSolderMaskMargin(int aMargin)
Definition: class_pad.h:462
#define _(s)
Definition: 3d_actions.cpp:33
SHAPE_LINE_CHAIN.
int m_LengthPadToDie
Length net from pad to die, inside the package.
Definition: class_pad.h:934
virtual int GetClearance(BOARD_CONNECTED_ITEM *aItem=NULL) const
Function GetClearance returns the clearance in internal units.
double GetOrientation() const
Function GetOrientation returns the rotation angle of the pad in tenths of degrees,...
Definition: class_pad.h:426
void CustomShapeAsPolygonToBoardPosition(SHAPE_POLY_SET *aMergedPolygon, wxPoint aPosition, double aRotation) const
When created, the corners coordinates are relative to the pad position, orientation 0,...
wxString UnescapeString(const wxString &aSource)
Definition: string.cpp:131
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
void ImportSettingsFrom(const D_PAD &aMasterPad)
Imports the pad settings from aMasterPad.
Definition: class_pad.cpp:1488
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
const wxSize & GetDrillSize() const
Definition: class_pad.h:306
void Flip(const wxPoint &aCentre, bool aFlipLeftRight) override
Function Flip Flip this object, i.e.
Definition: class_pad.cpp:445
wxPoint ShapePos() const
Definition: class_pad.cpp:570
EDA_RECT handles the component boundary box.
Definition: eda_rect.h:44
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:61
EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boards.
Definition: base_struct.h:166
int GetClearance(BOARD_CONNECTED_ITEM *aItem=NULL) const override
Function GetClearance returns the clearance in internal units.
Definition: class_pad.cpp:596
void SetShape(PAD_SHAPE_T aShape)
Definition: class_pad.h:238
bool Intersects(const EDA_RECT &aRect) const
Function Intersects tests for a common area between rectangles.
int GetRoundRectCornerRadius() const
Function GetRoundRectCornerRadius Has meaning only for rounded rect pads.
Definition: class_pad.h:577
void SetOrientation(double aAngle)
Function SetOrientation sets the rotation angle of the pad.
Definition: class_pad.cpp:438
double GetRoundRectRadiusRatio() const
has meaning only for rounded rect pads
Definition: class_pad.h:675
PAD_ATTR_T m_Attribute
PAD_ATTRIB_NORMAL, PAD_ATTRIB_SMD, PAD_ATTRIB_CONN, PAD_ATTRIB_HOLE_NOT_PLATED.
Definition: class_pad.h:928
void SetChamferRectRatio(double aChamferScale)
has meaning only for chamfered rect pads Set the ratio between the smaller Y or Y size and the radius...
Definition: class_pad.h:712
int boundingRadius() const
Function boundingRadius returns a calculated radius of a bounding circle for this pad.
Definition: class_pad.cpp:146
void SetLocalSolderPasteMargin(int aMargin)
Definition: class_pad.h:468
static LSET ConnSMDMask()
layer set for a SMD pad on Front layer used for edge board connectors
Definition: class_pad.cpp:118
T EuclideanNorm() const
Destructor.
Definition: vector2d.h:299
wxSize m_Drill
Drill diam (drill shape = PAD_CIRCLE) or drill size (shape = OVAL) for drill shape = PAD_CIRCLE,...
Definition: class_pad.h:886
PAD_SHAPE_T GetShape() const
Function GetShape.
Definition: class_pad.h:237
Module description (excepted pads)
double m_Orient
in 1/10 degrees
Definition: class_pad.h:932
static LSET ApertureMask()
layer set for an aperture pad
Definition: class_pad.cpp:132
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:946
wxPoint m_Offset
m_Offset is useful only for oblong and rect pads (it can be used for other shapes,...
Definition: class_pad.h:917
VIEW.
Definition: view.h:61
const wxSize & GetSize() const
Definition: class_pad.h:300
void SetProperty(PAD_PROP_T aProperty)
Definition: class_pad.cpp:432
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:746
const wxPoint GetPosition() const override
Definition: class_pad.h:241
int GetThermalWidth() const
Definition: class_module.h:254
T NormalizeAngle360Min(T Angle)
Normalize angle to be > -360.0 and < 360.0 Angle equal to -360 or +360 are set to 0.
Definition: trigo.h:237
int GetLocalSolderPasteMargin() const
Definition: class_pad.h:467
Message panel definition file.
void SetOffset(const wxPoint &aOffset)
Definition: class_pad.h:308
a test point pad
Definition: pad_shapes.h:82
bool PadShouldBeNPTH() const
A pad whose hole is the same size as the pad is a NPTH.
Definition: class_pad.cpp:1321
virtual PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
void SetThermalGap(int aGap)
Definition: class_pad.h:545
const wxPoint GetPosition() const override
Definition: class_module.h:210
int GetThermalGap() const
Definition: class_module.h:257
void MirrorXPrimitives(int aX)
Mirror the primitives about a coordinate.
Definition: class_pad.cpp:506
bool SetPrimitives(const std::vector< PAD_CS_PRIMITIVE > &aPrimitivesList)
Import to the basic shape list.
const EDA_RECT GetBoundingBox() const override
Function GetBoundingBox returns the orthogonal, bounding box of this object for display purposes.
Definition: class_pad.cpp:229
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:1455
double m_ArcAngle
radius of a circle
Definition: class_pad.h:97
double GetLocalSolderPasteMarginRatio() const
Definition: class_pad.h:470
Additional netnames layers (not associated with a PCB layer)
void AppendConfigs(std::vector< PARAM_CFG * > *aResult)
Function AppendConfigs appends to aResult the configuration setting accessors which will later allow ...
Definition: class_pad.cpp:538
void SetDelta(const wxSize &aSize)
Definition: class_pad.h:302
void Mirror(bool aX=true, bool aY=false, const VECTOR2I &aRef={ 0, 0 })
Mirrors the line points about y or x (or both)
EDA_RECT & Inflate(wxCoord dx, wxCoord dy)
Function Inflate inflates the rectangle horizontally by dx and vertically by dy.
const wxSize GetSize() const
Definition: eda_rect.h:103
bool IsNetnameLayer(LAYER_NUM aLayer)
Function IsNetnameLayer tests whether a layer is a netname layer.
KICAD_T Type() const
Function Type()
Definition: base_struct.h:212
void SetChamferPositions(int aChamferPositions)
has meaning only for chamfered rect pads set the position of the chamfer for a 0 orientation,...
Definition: class_pad.h:732
bool IsLayerVisible(int aLayer) const
Function IsLayerVisible() Returns information about visibility of a particular layer.
Definition: view.h:416
wxPoint m_Pos
pad Position on board
Definition: class_pad.h:858
Definition: colors.h:62