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