KiCad PCB EDA Suite
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-2021 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 
26 #include <base_units.h>
27 #include <bitmaps.h>
28 #include <core/mirror.h>
29 #include <math/util.h> // for KiROUND
30 #include <eda_draw_frame.h>
31 #include <geometry/shape_circle.h>
32 #include <geometry/shape_segment.h>
33 #include <geometry/shape_simple.h>
34 #include <geometry/shape_rect.h>
36 #include <string_utils.h>
37 #include <i18n_utility.h>
38 #include <view/view.h>
39 #include <board.h>
40 #include <board_connected_item.h>
41 #include <board_design_settings.h>
42 #include <footprint.h>
43 #include <pad.h>
44 #include <pcb_shape.h>
46 #include <convert_to_biu.h>
48 #include <widgets/msgpanel.h>
49 #include <pcb_painter.h>
50 #include <wx/log.h>
51 
52 #include <memory>
53 
54 using KIGFX::PCB_PAINTER;
56 
57 
58 PAD::PAD( FOOTPRINT* 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_FOOTPRINT_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::PTH; // Default pad type is plated through hole
76  SetProperty( PAD_PROP::NONE ); // no special fabrication property
77  m_localClearance = 0;
81 
82  // Parameters for round rect only:
83  m_roundedCornerScale = 0.25; // from IPC-7351C standard
84 
85  // Parameters for chamfered rect only:
86  m_chamferScale = 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.
96  m_layerMask = PTHMask();
97 
98  SetSubRatsnest( 0 ); // used in ratsnest calculations
99 
100  SetDirty();
102  m_removeUnconnectedLayer = false;
103  m_keepTopBottomLayer = true;
104 }
105 
106 
107 PAD::PAD( const PAD& aOther ) :
108  BOARD_CONNECTED_ITEM( aOther.GetParent(), PCB_PAD_T )
109 {
111 
112  ImportSettingsFrom( aOther );
114  SetPosition( aOther.GetPosition() );
115  SetPos0( aOther.GetPos0() );
116  SetNumber( aOther.GetNumber() );
117  SetPinFunction( aOther.GetPinFunction() );
118  SetSubRatsnest( aOther.GetSubRatsnest() );
122  const_cast<KIID&>( m_Uuid ) = aOther.m_Uuid;
123 }
124 
125 
126 PAD& PAD::operator=( const PAD &aOther )
127 {
129 
130  ImportSettingsFrom( aOther );
132  SetPosition( aOther.GetPosition() );
133  SetPos0( aOther.GetPos0() );
134  SetNumber( aOther.GetNumber() );
135  SetPinFunction( aOther.GetPinFunction() );
136  SetSubRatsnest( aOther.GetSubRatsnest() );
140 
141  return *this;
142 }
143 
144 
145 bool PAD::CanHaveNumber() const
146 {
147  // Aperture pads don't get a number
148  if( IsAperturePad() )
149  return false;
150 
151  // NPTH pads don't get numbers
152  if( GetAttribute() == PAD_ATTRIB::NPTH )
153  return false;
154 
155  return true;
156 }
157 
158 
159 bool PAD::IsLocked() const
160 {
161  if( GetParent() && static_cast<FOOTPRINT*>( GetParent() )->IsLocked() )
162  return true;
163 
164  return BOARD_ITEM::IsLocked();
165 };
166 
167 
169 {
170  static LSET saved = LSET::AllCuMask() | LSET( 2, F_Mask, B_Mask );
171  return saved;
172 }
173 
174 
176 {
177  static LSET saved( 3, F_Cu, F_Paste, F_Mask );
178  return saved;
179 }
180 
181 
183 {
184  static LSET saved( 2, F_Cu, F_Mask );
185  return saved;
186 }
187 
188 
190 {
191  static LSET saved = LSET( 4, F_Cu, B_Cu, F_Mask, B_Mask );
192  return saved;
193 }
194 
195 
197 {
198  static LSET saved( 1, F_Paste );
199  return saved;
200 }
201 
202 
203 bool PAD::IsFlipped() const
204 {
205  if( GetParent() && GetParent()->GetLayer() == B_Cu )
206  return true;
207  return false;
208 }
209 
210 
211 bool PAD::FlashLayer( LSET aLayers ) const
212 {
213  for( auto layer : aLayers.Seq() )
214  {
215  if( FlashLayer( layer ) )
216  return true;
217  }
218 
219  return false;
220 }
221 
222 
223 bool PAD::FlashLayer( int aLayer ) const
224 {
225  std::vector<KICAD_T> types
227 
228  // Return the "normal" shape if the caller doesn't specify a particular layer
229  if( aLayer == UNDEFINED_LAYER )
230  return true;
231 
232  const BOARD* board = GetBoard();
233 
234  if( !board )
235  return false;
236 
238  if( GetAttribute() != PAD_ATTRIB::PTH )
239  return IsOnLayer( static_cast<PCB_LAYER_ID>( aLayer ) );
240 
243  return IsOnLayer( static_cast<PCB_LAYER_ID>( aLayer ) );
244 
246  return IsOnLayer( static_cast<PCB_LAYER_ID>( aLayer ) );
247 
248  // Plated through hole pads need copper on the top/bottom layers for proper soldering
249  // Unless the user has removed them in the pad dialog
250  if( m_keepTopBottomLayer && ( aLayer == F_Cu || aLayer == B_Cu ) )
251  return IsOnLayer( static_cast<PCB_LAYER_ID>( aLayer ) );
252 
253  return board->GetConnectivity()->IsConnectedOnLayer( this, static_cast<int>( aLayer ), types );
254 }
255 
256 
258 {
259  return KiROUND( std::min( m_size.x, m_size.y ) * m_roundedCornerScale );
260 }
261 
262 
263 void PAD::SetRoundRectCornerRadius( double aRadius )
264 {
265  int min_r = std::min( m_size.x, m_size.y );
266 
267  if( min_r > 0 )
268  SetRoundRectRadiusRatio( aRadius / min_r );
269 }
270 
271 
272 void PAD::SetRoundRectRadiusRatio( double aRadiusScale )
273 {
274  m_roundedCornerScale = std::max( 0.0, std::min( aRadiusScale, 0.5 ) );
275 
276  SetDirty();
277 }
278 
279 
280 void PAD::SetChamferRectRatio( double aChamferScale )
281 {
282  m_chamferScale = std::max( 0.0, std::min( aChamferScale, 0.5 ) );
283 
284  SetDirty();
285 }
286 
287 
288 const std::shared_ptr<SHAPE_POLY_SET>& PAD::GetEffectivePolygon() const
289 {
290  if( m_polyDirty )
292 
293  return m_effectivePolygon;
294 }
295 
296 
297 std::shared_ptr<SHAPE> PAD::GetEffectiveShape( PCB_LAYER_ID aLayer ) const
298 {
299  if( m_shapesDirty )
300  BuildEffectiveShapes( aLayer );
301 
302  return m_effectiveShape;
303 }
304 
305 
307 {
308  if( m_shapesDirty )
310 
311  return m_effectiveHoleShape.get();
312 }
313 
314 
316 {
317  if( m_polyDirty )
319 
321 }
322 
323 
325 {
326  std::lock_guard<std::mutex> RAII_lock( m_shapesBuildingLock );
327 
328  // If we had to wait for the lock then we were probably waiting for someone else to
329  // finish rebuilding the shapes. So check to see if they're clean now.
330  if( !m_shapesDirty )
331  return;
332 
333  const BOARD* board = GetBoard();
334  int maxError = board ? board->GetDesignSettings().m_MaxError : ARC_HIGH_DEF;
335 
336  m_effectiveShape = std::make_shared<SHAPE_COMPOUND>();
337  m_effectiveHoleShape = nullptr;
338 
339  auto add = [this]( SHAPE* aShape )
340  {
341  m_effectiveShape->AddShape( aShape );
342  };
343 
344  wxPoint shapePos = ShapePos(); // Fetch only once; rotation involves trig
345  PAD_SHAPE effectiveShape = GetShape();
346 
347  if( GetShape() == PAD_SHAPE::CUSTOM )
348  effectiveShape = GetAnchorPadShape();
349 
350  switch( effectiveShape )
351  {
352  case PAD_SHAPE::CIRCLE:
353  add( new SHAPE_CIRCLE( shapePos, m_size.x / 2 ) );
354  break;
355 
356  case PAD_SHAPE::OVAL:
357  if( m_size.x == m_size.y ) // the oval pad is in fact a circle
358  {
359  add( new SHAPE_CIRCLE( shapePos, m_size.x / 2 ) );
360  }
361  else
362  {
363  wxSize half_size = m_size / 2;
364  int half_width = std::min( half_size.x, half_size.y );
365  wxPoint half_len( half_size.x - half_width, half_size.y - half_width );
366  RotatePoint( &half_len, m_orient );
367  add( new SHAPE_SEGMENT( shapePos - half_len, shapePos + half_len, half_width * 2 ) );
368  }
369 
370  break;
371 
372  case PAD_SHAPE::RECT:
375  {
376  int r = ( effectiveShape == PAD_SHAPE::ROUNDRECT ) ? GetRoundRectCornerRadius() : 0;
377  wxPoint half_size( m_size.x / 2, m_size.y / 2 );
378  wxSize trap_delta( 0, 0 );
379 
380  if( r )
381  {
382  half_size -= wxPoint( r, r );
383 
384  // Avoid degenerated shapes (0 length segments) that always create issues
385  // For roundrect pad very near a circle, use only a circle
386  const int min_len = Millimeter2iu( 0.0001);
387 
388  if( half_size.x < min_len && half_size.y < min_len )
389  {
390  add( new SHAPE_CIRCLE( shapePos, r ) );
391  break;
392  }
393  }
394  else if( effectiveShape == PAD_SHAPE::TRAPEZOID )
395  {
396  trap_delta = m_deltaSize / 2;
397  }
398 
399  SHAPE_LINE_CHAIN corners;
400 
401  corners.Append( -half_size.x - trap_delta.y, half_size.y + trap_delta.x );
402  corners.Append( half_size.x + trap_delta.y, half_size.y - trap_delta.x );
403  corners.Append( half_size.x - trap_delta.y, -half_size.y + trap_delta.x );
404  corners.Append( -half_size.x + trap_delta.y, -half_size.y - trap_delta.x );
405 
406  corners.Rotate( -DECIDEG2RAD( m_orient ) );
407  corners.Move( shapePos );
408 
409  // GAL renders rectangles faster than 4-point polygons so it's worth checking if our
410  // body shape is a rectangle.
411  if( corners.PointCount() == 4
412  &&
413  ( ( corners.CPoint( 0 ).y == corners.CPoint( 1 ).y
414  && corners.CPoint( 1 ).x == corners.CPoint( 2 ).x
415  && corners.CPoint( 2 ).y == corners.CPoint( 3 ).y
416  && corners.CPoint( 3 ).x == corners.CPoint( 0 ).x )
417  ||
418  ( corners.CPoint( 0 ).x == corners.CPoint( 1 ).x
419  && corners.CPoint( 1 ).y == corners.CPoint( 2 ).y
420  && corners.CPoint( 2 ).x == corners.CPoint( 3 ).x
421  && corners.CPoint( 3 ).y == corners.CPoint( 0 ).y )
422  )
423  )
424  {
425  int width = std::abs( corners.CPoint( 2 ).x - corners.CPoint( 0 ).x );
426  int height = std::abs( corners.CPoint( 2 ).y - corners.CPoint( 0 ).y );
427  VECTOR2I pos( std::min( corners.CPoint( 2 ).x, corners.CPoint( 0 ).x ),
428  std::min( corners.CPoint( 2 ).y, corners.CPoint( 0 ).y ) );
429 
430  add( new SHAPE_RECT( pos, width, height ) );
431  }
432  else
433  {
434  add( new SHAPE_SIMPLE( corners ) );
435  }
436 
437  if( r )
438  {
439  add( new SHAPE_SEGMENT( corners.CPoint( 0 ), corners.CPoint( 1 ), r * 2 ) );
440  add( new SHAPE_SEGMENT( corners.CPoint( 1 ), corners.CPoint( 2 ), r * 2 ) );
441  add( new SHAPE_SEGMENT( corners.CPoint( 2 ), corners.CPoint( 3 ), r * 2 ) );
442  add( new SHAPE_SEGMENT( corners.CPoint( 3 ), corners.CPoint( 0 ), r * 2 ) );
443  }
444  }
445  break;
446 
448  {
449  SHAPE_POLY_SET outline;
450 
453  GetChamferPositions(), 0, maxError, ERROR_INSIDE );
454 
455  add( new SHAPE_SIMPLE( outline.COutline( 0 ) ) );
456  }
457  break;
458 
459  default:
460  wxFAIL_MSG( "PAD::buildEffectiveShapes: Unsupported pad shape: "
461  + PAD_SHAPE_T_asString( effectiveShape ) );
462  break;
463  }
464 
465  if( GetShape() == PAD_SHAPE::CUSTOM )
466  {
467  for( const std::shared_ptr<PCB_SHAPE>& primitive : m_editPrimitives )
468  {
469  for( SHAPE* shape : primitive->MakeEffectiveShapes() )
470  {
471  shape->Rotate( -DECIDEG2RAD( m_orient ) );
472  shape->Move( shapePos );
473  add( shape );
474  }
475  }
476  }
477 
478  BOX2I bbox = m_effectiveShape->BBox();
479  m_effectiveBoundingBox = EDA_RECT( (wxPoint) bbox.GetPosition(),
480  wxSize( bbox.GetWidth(), bbox.GetHeight() ) );
481 
482  // Hole shape
483  wxSize half_size = m_drill / 2;
484  int half_width = std::min( half_size.x, half_size.y );
485  wxPoint half_len( half_size.x - half_width, half_size.y - half_width );
486 
487  RotatePoint( &half_len, m_orient );
488 
489  m_effectiveHoleShape = std::make_shared<SHAPE_SEGMENT>( m_pos - half_len, m_pos + half_len,
490  half_width * 2 );
491 
492  // All done
493  m_shapesDirty = false;
494 }
495 
496 
498 {
499  std::lock_guard<std::mutex> RAII_lock( m_polyBuildingLock );
500 
501  // If we had to wait for the lock then we were probably waiting for someone else to
502  // finish rebuilding the shapes. So check to see if they're clean now.
503  if( !m_polyDirty )
504  return;
505 
506  const BOARD* board = GetBoard();
507  int maxError = board ? board->GetDesignSettings().m_MaxError : ARC_HIGH_DEF;
508 
509  // Polygon
510  m_effectivePolygon = std::make_shared<SHAPE_POLY_SET>();
512  ERROR_INSIDE );
513 
514  // Bounding radius
515  //
516  // PADSTACKS TODO: these will both need to cycle through all layers to get the largest
517  // values....
519 
520  for( int cnt = 0; cnt < m_effectivePolygon->OutlineCount(); ++cnt )
521  {
522  const SHAPE_LINE_CHAIN& poly = m_effectivePolygon->COutline( cnt );
523 
524  for( int ii = 0; ii < poly.PointCount(); ++ii )
525  {
526  int dist = KiROUND( ( poly.CPoint( ii ) - m_pos ).EuclideanNorm() );
528  }
529  }
530 
531  // All done
532  m_polyDirty = false;
533 }
534 
535 
537 {
538  if( m_shapesDirty )
540 
541  return m_effectiveBoundingBox;
542 }
543 
544 
546 {
547  FOOTPRINT* parentFootprint = static_cast<FOOTPRINT*>( m_parent );
548 
549  m_pos = m_pos0;
550 
551  if( parentFootprint == nullptr )
552  return;
553 
554  double angle = parentFootprint->GetOrientation();
555 
556  RotatePoint( &m_pos.x, &m_pos.y, angle );
557  m_pos += parentFootprint->GetPosition();
558 
559  SetDirty();
560 }
561 
562 
564 {
565  FOOTPRINT* parentFootprint = static_cast<FOOTPRINT*>( m_parent );
566 
567  if( parentFootprint == nullptr )
568  {
569  m_pos0 = m_pos;
570  return;
571  }
572 
573  m_pos0 = m_pos - parentFootprint->GetPosition();
574  RotatePoint( &m_pos0.x, &m_pos0.y, -parentFootprint->GetOrientation() );
575 }
576 
577 
578 void PAD::SetAttribute( PAD_ATTRIB aAttribute )
579 {
580  m_attribute = aAttribute;
581 
582  if( aAttribute == PAD_ATTRIB::SMD )
583  m_drill = wxSize( 0, 0 );
584 
585  SetDirty();
586 }
587 
588 
589 void PAD::SetProperty( PAD_PROP aProperty )
590 {
591  m_property = aProperty;
592 
593  SetDirty();
594 }
595 
596 
597 void PAD::SetOrientation( double aAngle )
598 {
599  NORMALIZE_ANGLE_POS( aAngle );
600  m_orient = aAngle;
601 
602  SetDirty();
603 }
604 
605 
606 void PAD::Flip( const wxPoint& aCentre, bool aFlipLeftRight )
607 {
608  if( aFlipLeftRight )
609  {
610  MIRROR( m_pos.x, aCentre.x );
611  MIRROR( m_pos0.x, 0 );
612  MIRROR( m_offset.x, 0 );
613  MIRROR( m_deltaSize.x, 0 );
614  }
615  else
616  {
617  MIRROR( m_pos.y, aCentre.y );
618  MIRROR( m_pos0.y, 0 );
619  MIRROR( m_offset.y, 0 );
620  MIRROR( m_deltaSize.y, 0 );
621  }
622 
624 
625  auto mirrorBitFlags = []( int& aBitfield, int a, int b )
626  {
627  bool temp = aBitfield & a;
628 
629  if( aBitfield & b )
630  aBitfield |= a;
631  else
632  aBitfield &= ~a;
633 
634  if( temp )
635  aBitfield |= b;
636  else
637  aBitfield &= ~b;
638  };
639 
640  if( aFlipLeftRight )
641  {
644  }
645  else
646  {
649  }
650 
651  // flip pads layers
652  // PADS items are currently on all copper layers, or
653  // currently, only on Front or Back layers.
654  // So the copper layers count is not taken in account
656 
657  // Flip the basic shapes, in custom pads
658  FlipPrimitives( aFlipLeftRight );
659 
660  SetDirty();
661 }
662 
663 
664 void PAD::FlipPrimitives( bool aFlipLeftRight )
665 {
666  for( std::shared_ptr<PCB_SHAPE>& primitive : m_editPrimitives )
667  primitive->Flip( wxPoint( 0, 0 ), aFlipLeftRight );
668 
669  SetDirty();
670 }
671 
672 
673 wxPoint PAD::ShapePos() const
674 {
675  if( m_offset.x == 0 && m_offset.y == 0 )
676  return m_pos;
677 
678  wxPoint loc_offset = m_offset;
679 
680  RotatePoint( &loc_offset, m_orient );
681 
682  wxPoint shape_pos = m_pos + loc_offset;
683 
684  return shape_pos;
685 }
686 
687 
688 int PAD::GetLocalClearanceOverrides( wxString* aSource ) const
689 {
690  // A pad can have specific clearance that overrides its NETCLASS clearance value
691  if( GetLocalClearance() )
692  return GetLocalClearance( aSource );
693 
694  // A footprint can have a specific clearance value
695  if( GetParent() && GetParent()->GetLocalClearance() )
696  return GetParent()->GetLocalClearance( aSource );
697 
698  return 0;
699 }
700 
701 
702 int PAD::GetLocalClearance( wxString* aSource ) const
703 {
704  if( aSource )
705  *aSource = _( "pad" );
706 
707  return m_localClearance;
708 }
709 
710 
712 {
713  // The pad inherits the margin only to calculate a default shape,
714  // therefore only if it is also a copper layer
715  // Pads defined only on mask layers (and perhaps on other tech layers) use the shape
716  // defined by the pad settings only
717  bool isOnCopperLayer = ( m_layerMask & LSET::AllCuMask() ).any();
718 
719  if( !isOnCopperLayer )
720  return 0;
721 
722  int margin = m_localSolderMaskMargin;
723 
724  FOOTPRINT* parentFootprint = GetParent();
725 
726  if( parentFootprint )
727  {
728  if( margin == 0 )
729  {
730  if( parentFootprint->GetLocalSolderMaskMargin() )
731  margin = parentFootprint->GetLocalSolderMaskMargin();
732  }
733 
734  if( margin == 0 )
735  {
736  const BOARD* brd = GetBoard();
737 
738  if( brd )
739  margin = brd->GetDesignSettings().m_SolderMaskMargin;
740  }
741  }
742 
743  // ensure mask have a size always >= 0
744  if( margin < 0 )
745  {
746  int minsize = -std::min( m_size.x, m_size.y ) / 2;
747 
748  if( margin < minsize )
749  margin = minsize;
750  }
751 
752  return margin;
753 }
754 
755 
757 {
758  // The pad inherits the margin only to calculate a default shape,
759  // therefore only if it is also a copper layer.
760  // Pads defined only on mask layers (and perhaps on other tech layers) use the shape
761  // defined by the pad settings only
762  bool isOnCopperLayer = ( m_layerMask & LSET::AllCuMask() ).any();
763 
764  if( !isOnCopperLayer )
765  return wxSize( 0, 0 );
766 
767  int margin = m_localSolderPasteMargin;
768  double mratio = m_localSolderPasteMarginRatio;
769 
770  FOOTPRINT* parentFootprint = GetParent();
771 
772  if( parentFootprint )
773  {
774  if( margin == 0 )
775  margin = parentFootprint->GetLocalSolderPasteMargin();
776 
777  auto brd = GetBoard();
778 
779  if( margin == 0 && brd )
780  margin = brd->GetDesignSettings().m_SolderPasteMargin;
781 
782  if( mratio == 0.0 )
783  mratio = parentFootprint->GetLocalSolderPasteMarginRatio();
784 
785  if( mratio == 0.0 && brd )
786  {
787  mratio = brd->GetDesignSettings().m_SolderPasteMarginRatio;
788  }
789  }
790 
791  wxSize pad_margin;
792  pad_margin.x = margin + KiROUND( m_size.x * mratio );
793  pad_margin.y = margin + KiROUND( m_size.y * mratio );
794 
795  // ensure mask have a size always >= 0
796  if( pad_margin.x < -m_size.x / 2 )
797  pad_margin.x = -m_size.x / 2;
798 
799  if( pad_margin.y < -m_size.y / 2 )
800  pad_margin.y = -m_size.y / 2;
801 
802  return pad_margin;
803 }
804 
805 
807 {
808  FOOTPRINT* parentFootprint = GetParent();
809 
810  if( m_zoneConnection == ZONE_CONNECTION::INHERITED && parentFootprint )
811  {
812  if( aSource )
813  *aSource = _( "parent footprint" );
814 
815  return parentFootprint->GetZoneConnection();
816  }
817  else
818  {
819  if( aSource )
820  *aSource = _( "pad" );
821 
822  return m_zoneConnection;
823  }
824 }
825 
826 
827 int PAD::GetEffectiveThermalSpokeWidth( wxString* aSource ) const
828 {
829  FOOTPRINT* parentFootprint = GetParent();
830 
831  if( m_thermalWidth == 0 && parentFootprint )
832  {
833  if( aSource )
834  *aSource = _( "parent footprint" );
835 
836  return parentFootprint->GetThermalWidth();
837  }
838 
839  if( aSource )
840  *aSource = _( "pad" );
841 
842  return m_thermalWidth;
843 }
844 
845 
846 int PAD::GetEffectiveThermalGap( wxString* aSource ) const
847 {
848  FOOTPRINT* parentFootprint = GetParent();
849 
850  if( m_thermalGap == 0 && parentFootprint )
851  {
852  if( aSource )
853  *aSource = _( "parent footprint" );
854 
855  return parentFootprint->GetThermalGap();
856  }
857 
858  if( aSource )
859  *aSource = _( "pad" );
860 
861  return m_thermalGap;
862 }
863 
864 
865 void PAD::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
866 {
867  EDA_UNITS units = aFrame->GetUserUnits();
868  wxString msg;
869  FOOTPRINT* parentFootprint = static_cast<FOOTPRINT*>( m_parent );
870 
871  if( parentFootprint )
872  aList.emplace_back( _( "Footprint" ), parentFootprint->GetReference() );
873 
874  aList.emplace_back( _( "Pad" ), m_number );
875 
876  if( !GetPinFunction().IsEmpty() )
877  aList.emplace_back( _( "Pin Name" ), GetPinFunction() );
878 
879  if( !GetPinType().IsEmpty() )
880  aList.emplace_back( _( "Pin Type" ), GetPinType() );
881 
882  aList.emplace_back( _( "Net" ), UnescapeString( GetNetname() ) );
883 
884  aList.emplace_back( _( "NetClass" ), UnescapeString( GetNetClass()->GetName() ) );
885 
886  if( IsLocked() )
887  aList.emplace_back( _( "Status" ), _( "Locked" ) );
888 
890  aList.emplace_back( _( "Layer" ), layerMaskDescribe() );
891 
892  // Show the pad shape, attribute and property
893  wxString props = ShowPadAttr();
894 
895  if( GetProperty() != PAD_PROP::NONE )
896  props += ',';
897 
898  switch( GetProperty() )
899  {
900  case PAD_PROP::NONE: break;
901  case PAD_PROP::BGA: props += _("BGA" ); break;
902  case PAD_PROP::FIDUCIAL_GLBL: props += _("Fiducial global" ); break;
903  case PAD_PROP::FIDUCIAL_LOCAL: props += _("Fiducial local" ); break;
904  case PAD_PROP::TESTPOINT: props += _("Test point" ); break;
905  case PAD_PROP::HEATSINK: props += _("Heat sink" ); break;
906  case PAD_PROP::CASTELLATED: props += _("Castellated" ); break;
907  }
908 
909  aList.emplace_back( ShowPadShape(), props );
910 
911  if( ( GetShape() == PAD_SHAPE::CIRCLE || GetShape() == PAD_SHAPE::OVAL ) &&
912  m_size.x == m_size.y )
913  {
914  aList.emplace_back( _( "Diameter" ), MessageTextFromValue( units, m_size.x ) );
915  }
916  else
917  {
918  aList.emplace_back( _( "Width" ), MessageTextFromValue( units, m_size.x ) );
919  aList.emplace_back( _( "Height" ), MessageTextFromValue( units, m_size.y ) );
920  }
921 
922  double fp_orient_degrees = parentFootprint ? parentFootprint->GetOrientationDegrees() : 0;
923  double pad_orient_degrees = GetOrientationDegrees() - fp_orient_degrees;
924  pad_orient_degrees = NormalizeAngleDegrees( pad_orient_degrees, -180.0, +180.0 );
925 
926  if( fp_orient_degrees != 0.0 )
927  msg.Printf( wxT( "%g(+ %g)" ), pad_orient_degrees, fp_orient_degrees );
928  else
929  msg.Printf( wxT( "%g" ), GetOrientationDegrees() );
930 
931  aList.emplace_back( _( "Rotation" ), msg );
932 
933  if( GetPadToDieLength() )
934  {
935  msg = MessageTextFromValue(units, GetPadToDieLength() );
936  aList.emplace_back( _( "Length in Package" ), msg );
937  }
938 
939  if( m_drill.x > 0 || m_drill.y > 0 )
940  {
942  {
943  aList.emplace_back( _( "Hole" ),
944  wxString::Format( "%s",
945  MessageTextFromValue( units, m_drill.x ) ) );
946  }
947  else
948  {
949  aList.emplace_back( _( "Hole X / Y" ),
950  wxString::Format( "%s / %s",
951  MessageTextFromValue( units, m_drill.x ),
952  MessageTextFromValue( units, m_drill.y ) ) );
953  }
954  }
955 
956  wxString source;
957  int clearance = GetOwnClearance( GetLayer(), &source );
958 
959  aList.emplace_back( wxString::Format( _( "Min Clearance: %s" ),
960  MessageTextFromValue( units, clearance ) ),
961  wxString::Format( _( "(from %s)" ), source ) );
962 #if 0
963  // useful for debug only
964  aList.emplace_back( "UUID", m_Uuid.AsString() );
965 #endif
966 }
967 
968 
969 bool PAD::HitTest( const wxPoint& aPosition, int aAccuracy ) const
970 {
971  VECTOR2I delta = aPosition - GetPosition();
972  int boundingRadius = GetBoundingRadius() + aAccuracy;
973 
974  if( delta.SquaredEuclideanNorm() > SEG::Square( boundingRadius ) )
975  return false;
976 
977  return GetEffectivePolygon()->Contains( aPosition, -1, aAccuracy );
978 }
979 
980 
981 bool PAD::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
982 {
983  EDA_RECT arect = aRect;
984  arect.Normalize();
985  arect.Inflate( aAccuracy );
986 
987  EDA_RECT bbox = GetBoundingBox();
988 
989  if( aContained )
990  {
991  return arect.Contains( bbox );
992  }
993  else
994  {
995  // Fast test: if aRect is outside the polygon bounding box,
996  // rectangles cannot intersect
997  if( !arect.Intersects( bbox ) )
998  return false;
999 
1000  const std::shared_ptr<SHAPE_POLY_SET>& poly = GetEffectivePolygon();
1001 
1002  int count = poly->TotalVertices();
1003 
1004  for( int ii = 0; ii < count; ii++ )
1005  {
1006  auto vertex = poly->CVertex( ii );
1007  auto vertexNext = poly->CVertex(( ii + 1 ) % count );
1008 
1009  // Test if the point is within aRect
1010  if( arect.Contains( ( wxPoint ) vertex ) )
1011  return true;
1012 
1013  // Test if this edge intersects aRect
1014  if( arect.Intersects( ( wxPoint ) vertex, ( wxPoint ) vertexNext ) )
1015  return true;
1016  }
1017 
1018  return false;
1019  }
1020 }
1021 
1022 
1023 int PAD::Compare( const PAD* padref, const PAD* padcmp )
1024 {
1025  int diff;
1026 
1027  if( ( diff = static_cast<int>( padref->GetShape() ) -
1028  static_cast<int>( padcmp->GetShape() ) ) != 0 )
1029  return diff;
1030 
1031  if( ( diff = padref->GetDrillShape() - padcmp->GetDrillShape() ) != 0)
1032  return diff;
1033 
1034  if( ( diff = padref->m_drill.x - padcmp->m_drill.x ) != 0 )
1035  return diff;
1036 
1037  if( ( diff = padref->m_drill.y - padcmp->m_drill.y ) != 0 )
1038  return diff;
1039 
1040  if( ( diff = padref->m_size.x - padcmp->m_size.x ) != 0 )
1041  return diff;
1042 
1043  if( ( diff = padref->m_size.y - padcmp->m_size.y ) != 0 )
1044  return diff;
1045 
1046  if( ( diff = padref->m_offset.x - padcmp->m_offset.x ) != 0 )
1047  return diff;
1048 
1049  if( ( diff = padref->m_offset.y - padcmp->m_offset.y ) != 0 )
1050  return diff;
1051 
1052  if( ( diff = padref->m_deltaSize.x - padcmp->m_deltaSize.x ) != 0 )
1053  return diff;
1054 
1055  if( ( diff = padref->m_deltaSize.y - padcmp->m_deltaSize.y ) != 0 )
1056  return diff;
1057 
1058  // TODO: test custom shapes
1059 
1060  // Dick: specctra_export needs this
1061  // Lorenzo: gencad also needs it to implement padstacks!
1062 
1063 #if __cplusplus >= 201103L
1064  long long d = padref->m_layerMask.to_ullong() - padcmp->m_layerMask.to_ullong();
1065  if( d < 0 )
1066  return -1;
1067  else if( d > 0 )
1068  return 1;
1069 
1070  return 0;
1071 #else
1072  // these strings are not typically constructed, since we don't get here often.
1073  std::string s1 = padref->m_layerMask.to_string();
1074  std::string s2 = padcmp->m_layerMask.to_string();
1075  return s1.compare( s2 );
1076 #endif
1077 }
1078 
1079 
1080 void PAD::Rotate( const wxPoint& aRotCentre, double aAngle )
1081 {
1082  RotatePoint( &m_pos, aRotCentre, aAngle );
1083 
1084  m_orient = NormalizeAngle360Min( m_orient + aAngle );
1085 
1086  SetLocalCoord();
1087 
1088  SetDirty();
1089 }
1090 
1091 
1092 wxString PAD::ShowPadShape() const
1093 {
1094  switch( GetShape() )
1095  {
1096  case PAD_SHAPE::CIRCLE: return _( "Circle" );
1097  case PAD_SHAPE::OVAL: return _( "Oval" );
1098  case PAD_SHAPE::RECT: return _( "Rect" );
1099  case PAD_SHAPE::TRAPEZOID: return _( "Trap" );
1100  case PAD_SHAPE::ROUNDRECT: return _( "Roundrect" );
1101  case PAD_SHAPE::CHAMFERED_RECT: return _( "Chamferedrect" );
1102  case PAD_SHAPE::CUSTOM: return _( "CustomShape" );
1103  default: return wxT( "???" );
1104  }
1105 }
1106 
1107 
1108 wxString PAD::ShowPadAttr() const
1109 {
1110  switch( GetAttribute() )
1111  {
1112  case PAD_ATTRIB::PTH: return _( "PTH" );
1113  case PAD_ATTRIB::SMD: return _( "SMD" );
1114  case PAD_ATTRIB::CONN: return _( "Conn" );
1115  case PAD_ATTRIB::NPTH: return _( "NPTH" );
1116  default: return wxT( "???" );
1117  }
1118 }
1119 
1120 
1121 wxString PAD::GetSelectMenuText( EDA_UNITS aUnits ) const
1122 {
1123  if( GetNumber().IsEmpty() )
1124  {
1126  {
1127  return wxString::Format( _( "Pad of %s on %s" ),
1128  GetParent()->GetReference(),
1129  layerMaskDescribe() );
1130  }
1131  else
1132  {
1133  return wxString::Format( _( "Through hole pad of %s" ),
1134  GetParent()->GetReference() );
1135  }
1136  }
1137  else
1138  {
1140  {
1141  return wxString::Format( _( "Pad %s of %s on %s" ),
1142  GetNumber(),
1143  GetParent()->GetReference(),
1144  layerMaskDescribe() );
1145  }
1146  else
1147  {
1148  return wxString::Format( _( "Through hole pad %s of %s" ),
1149  GetNumber(),
1150  GetParent()->GetReference() );
1151  }
1152  }
1153 }
1154 
1155 
1157 {
1158  return BITMAPS::pad;
1159 }
1160 
1161 
1163 {
1164  return new PAD( *this );
1165 }
1166 
1167 
1168 void PAD::ViewGetLayers( int aLayers[], int& aCount ) const
1169 {
1170  aCount = 0;
1171 
1172  // These 2 types of pads contain a hole
1173  if( m_attribute == PAD_ATTRIB::PTH )
1174  {
1175  aLayers[aCount++] = LAYER_PAD_PLATEDHOLES;
1176  aLayers[aCount++] = LAYER_PAD_HOLEWALLS;
1177  }
1178 
1179  if( m_attribute == PAD_ATTRIB::NPTH )
1180  aLayers[aCount++] = LAYER_NON_PLATEDHOLES;
1181 
1182  if( IsOnLayer( F_Cu ) && IsOnLayer( B_Cu ) )
1183  {
1184  // Multi layer pad
1185  aLayers[aCount++] = LAYER_PADS_TH;
1186  aLayers[aCount++] = LAYER_PAD_NETNAMES;
1187  }
1188  else if( IsOnLayer( F_Cu ) )
1189  {
1190  aLayers[aCount++] = LAYER_PAD_FR;
1191 
1192  // Is this a PTH pad that has only front copper? If so, we need to also display the
1193  // net name on the PTH netname layer so that it isn't blocked by the drill hole.
1194  if( m_attribute == PAD_ATTRIB::PTH )
1195  aLayers[aCount++] = LAYER_PAD_NETNAMES;
1196  else
1197  aLayers[aCount++] = LAYER_PAD_FR_NETNAMES;
1198  }
1199  else if( IsOnLayer( B_Cu ) )
1200  {
1201  aLayers[aCount++] = LAYER_PAD_BK;
1202 
1203  // Is this a PTH pad that has only back copper? If so, we need to also display the
1204  // net name on the PTH netname layer so that it isn't blocked by the drill hole.
1205  if( m_attribute == PAD_ATTRIB::PTH )
1206  aLayers[aCount++] = LAYER_PAD_NETNAMES;
1207  else
1208  aLayers[aCount++] = LAYER_PAD_BK_NETNAMES;
1209  }
1210  else
1211  {
1212  // Internal layers only. (Not yet supported in GUI, but is being used by Python
1213  // footprint generators and will be needed anyway once pad stacks are supported.)
1214  for ( int internal = In1_Cu; internal < In30_Cu; ++internal )
1215  {
1216  if( IsOnLayer( (PCB_LAYER_ID) internal ) )
1217  aLayers[aCount++] = internal;
1218  }
1219  }
1220 
1221  // Check non-copper layers. This list should include all the layers that the
1222  // footprint editor allows a pad to be placed on.
1223  static const PCB_LAYER_ID layers_mech[] = { F_Mask, B_Mask, F_Paste, B_Paste,
1225 
1226  for( PCB_LAYER_ID each_layer : layers_mech )
1227  {
1228  if( IsOnLayer( each_layer ) )
1229  aLayers[aCount++] = each_layer;
1230  }
1231 
1232 #ifdef DEBUG
1233  if( aCount == 0 ) // Should not occur
1234  {
1235  wxString msg;
1236  msg.Printf( wxT( "footprint %s, pad %s: could not find valid layer for pad" ),
1237  GetParent() ? GetParent()->GetReference() : "<null>",
1238  GetNumber().IsEmpty() ? "(unnumbered)" : GetNumber() );
1239  wxLogDebug( msg );
1240  }
1241 #endif
1242 }
1243 
1244 
1245 double PAD::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const
1246 {
1247  constexpr double HIDE = std::numeric_limits<double>::max();
1248 
1249  PCB_PAINTER* painter = static_cast<PCB_PAINTER*>( aView->GetPainter() );
1250  PCB_RENDER_SETTINGS* renderSettings = painter->GetSettings();
1251  const BOARD* board = GetBoard();
1252  LSET visible = LSET::AllLayersMask();
1253 
1254  // Meta control for hiding all pads
1255  if( !aView->IsLayerVisible( LAYER_PADS ) )
1256  return HIDE;
1257 
1258  // Handle board visibility
1259  if( board )
1260  visible = board->GetVisibleLayers() & board->GetEnabledLayers();
1261 
1262  // Handle Render tab switches
1264  && !aView->IsLayerVisible( LAYER_PADS_TH ) )
1265  {
1266  return HIDE;
1267  }
1268 
1269  if( !IsFlipped() && !aView->IsLayerVisible( LAYER_MOD_FR ) )
1270  return HIDE;
1271 
1272  if( IsFlipped() && !aView->IsLayerVisible( LAYER_MOD_BK ) )
1273  return HIDE;
1274 
1275  if( IsFrontLayer( (PCB_LAYER_ID) aLayer ) && !aView->IsLayerVisible( LAYER_PAD_FR ) )
1276  return HIDE;
1277 
1278  if( IsBackLayer( (PCB_LAYER_ID) aLayer ) && !aView->IsLayerVisible( LAYER_PAD_BK ) )
1279  return HIDE;
1280 
1281  if( aLayer == LAYER_PADS_TH )
1282  {
1283  if( !FlashLayer( visible ) )
1284  return HIDE;
1285  }
1286  else if( IsHoleLayer( aLayer ) )
1287  {
1288  if( !( visible & LSET::PhysicalLayersMask() ).any() )
1289  return HIDE;
1290  }
1291  else if( IsNetnameLayer( aLayer ) )
1292  {
1293  if( renderSettings->GetHighContrast() )
1294  {
1295  // Hide netnames unless pad is flashed to a high-contrast layer
1296  if( !FlashLayer( renderSettings->GetPrimaryHighContrastLayer() ) )
1297  return HIDE;
1298  }
1299  else
1300  {
1301  // Hide netnames unless pad is flashed to a visible layer
1302  if( !FlashLayer( visible ) )
1303  return HIDE;
1304  }
1305 
1306  // Netnames will be shown only if zoom is appropriate
1307  int divisor = std::min( GetBoundingBox().GetWidth(), GetBoundingBox().GetHeight() );
1308 
1309  // Pad sizes can be zero briefly when someone is typing a number like "0.5"
1310  // in the pad properties dialog
1311  if( divisor == 0 )
1312  return HIDE;
1313 
1314  return ( double ) Millimeter2iu( 5 ) / divisor;
1315  }
1316 
1317  if( aLayer == LAYER_PADS_TH
1318  && GetShape() != PAD_SHAPE::CUSTOM
1319  && GetSizeX() <= GetDrillSizeX()
1320  && GetSizeY() <= GetDrillSizeY() )
1321  {
1322  // Don't tweak the drawing code with a degenerate pad
1323  return HIDE;
1324  }
1325 
1326  // Passed all tests; show.
1327  return 0.0;
1328 }
1329 
1330 
1331 const BOX2I PAD::ViewBBox() const
1332 {
1333  // Bounding box includes soldermask too. Remember mask and/or paste
1334  // margins can be < 0
1335  int solderMaskMargin = std::max( GetSolderMaskMargin(), 0 );
1336  VECTOR2I solderPasteMargin = VECTOR2D( GetSolderPasteMargin() );
1337  EDA_RECT bbox = GetBoundingBox();
1338 
1339  // get the biggest possible clearance
1340  int clearance = 0;
1341 
1342  for( PCB_LAYER_ID layer : GetLayerSet().Seq() )
1343  clearance = std::max( clearance, GetOwnClearance( layer ) );
1344 
1345  // Look for the biggest possible bounding box
1346  int xMargin = std::max( solderMaskMargin, solderPasteMargin.x ) + clearance;
1347  int yMargin = std::max( solderMaskMargin, solderPasteMargin.y ) + clearance;
1348 
1349  return BOX2I( VECTOR2I( bbox.GetOrigin() ) - VECTOR2I( xMargin, yMargin ),
1350  VECTOR2I( bbox.GetSize() ) + VECTOR2I( 2 * xMargin, 2 * yMargin ) );
1351 }
1352 
1353 
1355 {
1356  return dynamic_cast<FOOTPRINT*>( m_parent );
1357 }
1358 
1359 
1360 void PAD::ImportSettingsFrom( const PAD& aMasterPad )
1361 {
1362  SetShape( aMasterPad.GetShape() );
1363  SetLayerSet( aMasterPad.GetLayerSet() );
1364  SetAttribute( aMasterPad.GetAttribute() );
1365  SetProperty( aMasterPad.GetProperty() );
1366 
1367  // I am not sure the m_LengthPadToDie must be imported, because this is
1368  // a parameter really specific to a given pad (JPC).
1369  // So this is currently non imported
1370  #if 0
1371  SetPadToDieLength( aMasterPad.GetPadToDieLength() );
1372  #endif
1373 
1374  // The pad orientation, for historical reasons is the
1375  // pad rotation + parent rotation.
1376  // So we have to manage this parent rotation
1377  double pad_rot = aMasterPad.GetOrientation();
1378 
1379  if( aMasterPad.GetParent() )
1380  pad_rot -= aMasterPad.GetParent()->GetOrientation();
1381 
1382  if( GetParent() )
1383  pad_rot += GetParent()->GetOrientation();
1384 
1385  SetOrientation( pad_rot );
1386 
1387  SetSize( aMasterPad.GetSize() );
1388  SetDelta( wxSize( 0, 0 ) );
1389  SetOffset( aMasterPad.GetOffset() );
1390  SetDrillSize( aMasterPad.GetDrillSize() );
1391  SetDrillShape( aMasterPad.GetDrillShape() );
1393  SetChamferRectRatio( aMasterPad.GetChamferRectRatio() );
1394  SetChamferPositions( aMasterPad.GetChamferPositions() );
1395 
1396  switch( aMasterPad.GetShape() )
1397  {
1398  case PAD_SHAPE::TRAPEZOID:
1399  SetDelta( aMasterPad.GetDelta() );
1400  break;
1401 
1402  case PAD_SHAPE::CIRCLE:
1403  // ensure size.y == size.x
1404  SetSize( wxSize( GetSize().x, GetSize().x ) );
1405  break;
1406 
1407  default:
1408  ;
1409  }
1410 
1411  switch( aMasterPad.GetAttribute() )
1412  {
1413  case PAD_ATTRIB::SMD:
1414  case PAD_ATTRIB::CONN:
1415  // These pads do not have hole (they are expected to be only on one
1416  // external copper layer)
1417  SetDrillSize( wxSize( 0, 0 ) );
1418  break;
1419 
1420  default:
1421  ;
1422  }
1423 
1424  // copy also local settings:
1425  SetLocalClearance( aMasterPad.GetLocalClearance() );
1429 
1432  SetThermalGap( aMasterPad.GetThermalGap() );
1433 
1435 
1436  // Add or remove custom pad shapes:
1437  ReplacePrimitives( aMasterPad.GetPrimitives() );
1438  SetAnchorPadShape( aMasterPad.GetAnchorPadShape() );
1439 
1440  SetDirty();
1441 }
1442 
1443 
1444 void PAD::SwapData( BOARD_ITEM* aImage )
1445 {
1446  assert( aImage->Type() == PCB_PAD_T );
1447 
1448  std::swap( *((FOOTPRINT*) this), *((FOOTPRINT*) aImage) );
1449 }
1450 
1451 
1452 static struct PAD_DESC
1453 {
1455  {
1457  .Map( PAD_ATTRIB::PTH, _HKI( "Through-hole" ) )
1458  .Map( PAD_ATTRIB::SMD, _HKI( "SMD" ) )
1459  .Map( PAD_ATTRIB::CONN, _HKI( "Edge connector" ) )
1460  .Map( PAD_ATTRIB::NPTH, _HKI( "NPTH, mechanical" ) );
1461 
1463  .Map( PAD_SHAPE::CIRCLE, _HKI( "Circle" ) )
1464  .Map( PAD_SHAPE::RECT, _HKI( "Rectangle" ) )
1465  .Map( PAD_SHAPE::OVAL, _HKI( "Oval" ) )
1466  .Map( PAD_SHAPE::TRAPEZOID, _HKI( "Trapezoid" ) )
1467  .Map( PAD_SHAPE::ROUNDRECT, _HKI( "Rounded rectangle" ) )
1468  .Map( PAD_SHAPE::CHAMFERED_RECT, _HKI( "Chamfered rectangle" ) )
1469  .Map( PAD_SHAPE::CUSTOM, _HKI( "Custom" ) );
1470 
1472  .Map( PAD_PROP::NONE, _HKI( "None" ) )
1473  .Map( PAD_PROP::BGA, _HKI( "BGA pad" ) )
1474  .Map( PAD_PROP::FIDUCIAL_GLBL, _HKI( "Fiducial, global to board" ) )
1475  .Map( PAD_PROP::FIDUCIAL_LOCAL, _HKI( "Fiducial, local to footprint" ) )
1476  .Map( PAD_PROP::TESTPOINT, _HKI( "Test point pad" ) )
1477  .Map( PAD_PROP::HEATSINK, _HKI( "Heatsink pad" ) )
1478  .Map( PAD_PROP::CASTELLATED, _HKI( "Castellated pad" ) );
1479 
1481  REGISTER_TYPE( PAD );
1483 
1484  auto padType = new PROPERTY_ENUM<PAD, PAD_ATTRIB>( _HKI( "Pad Type" ),
1486  propMgr.AddProperty( padType );
1487 
1488  auto shape = new PROPERTY_ENUM<PAD, PAD_SHAPE>( _HKI( "Shape" ),
1490  propMgr.AddProperty( shape );
1491 
1492  propMgr.AddProperty( new PROPERTY<PAD, wxString>( _HKI( "Pad Number" ),
1494  propMgr.AddProperty( new PROPERTY<PAD, wxString>( _HKI( "Pin Name" ),
1496  propMgr.AddProperty( new PROPERTY<PAD, wxString>( _HKI( "Pin Type" ),
1498  propMgr.AddProperty( new PROPERTY<PAD, double>( _HKI( "Orientation" ),
1501  propMgr.AddProperty( new PROPERTY<PAD, int>( _HKI( "Size X" ),
1504  propMgr.AddProperty( new PROPERTY<PAD, int>( _HKI( "Size Y" ),
1507  propMgr.AddProperty( new PROPERTY<PAD, int>( _HKI( "Hole Size X" ),
1510  propMgr.AddProperty( new PROPERTY<PAD, int>( _HKI( "Hole Size Y" ),
1513  propMgr.AddProperty( new PROPERTY<PAD, int>( _HKI( "Pad To Die Length" ),
1516  propMgr.AddProperty( new PROPERTY<PAD, int>( _HKI( "Soldermask Margin Override" ),
1519  propMgr.AddProperty( new PROPERTY<PAD, int>( _HKI( "Solderpaste Margin Override" ),
1522  propMgr.AddProperty( new PROPERTY<PAD, double>( _HKI( "Solderpaste Margin Ratio Override" ),
1524  propMgr.AddProperty( new PROPERTY<PAD, int>( _HKI( "Thermal Relief Width" ),
1527  propMgr.AddProperty( new PROPERTY<PAD, int>( _HKI( "Thermal Relief Gap" ),
1530  propMgr.AddProperty( new PROPERTY_ENUM<PAD, PAD_PROP>( _HKI( "Fabrication Property" ),
1532 
1533  auto roundRadiusRatio = new PROPERTY<PAD, double>( _HKI( "Round Radius Ratio" ),
1535  roundRadiusRatio->SetAvailableFunc(
1536  [=]( INSPECTABLE* aItem ) -> bool
1537  {
1538  return aItem->Get( shape ) == static_cast<int>( PAD_SHAPE::ROUNDRECT );
1539  } );
1540  propMgr.AddProperty( roundRadiusRatio );
1541 
1542  propMgr.AddProperty( new PROPERTY<PAD, int>( _HKI( "Clearance Override" ),
1545  propMgr.AddProperty( new PROPERTY<PAD, wxString>( _HKI( "Parent" ),
1546  NO_SETTER( PAD, wxString ), &PAD::GetParentAsString ) );
1547 
1548  // TODO delta, drill shape offset, layer set, zone connection
1549  }
1550 } _PAD_DESC;
1551 
double EuclideanNorm(const wxPoint &vector)
Euclidean norm of a 2D vector.
Definition: trigo.h:146
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:750
Display value expressed in degrees.
Definition: property.h:54
BITMAPS GetMenuImage() const override
Return a pointer to an image to be used in menus.
Definition: pad.cpp:1156
ZONE_CONNECTION
How pads are covered by copper in zone.
Definition: zones.h:41
int GetLocalSolderMaskMargin() const
Definition: pad.h:386
void FlipPrimitives(bool aFlipLeftRight)
Flip (mirror) the primitives left to right or top to bottom, around the anchor position in custom pad...
Definition: pad.cpp:664
EDA_ITEM * m_parent
Linked list: Link (parent struct)
Definition: eda_item.h:479
wxString MessageTextFromValue(EDA_UNITS aUnits, int aValue, bool aAddUnitLabel, EDA_DATA_TYPE aType)
Convert a value to a string using double notation.
Definition: base_units.cpp:104
smd pads, front layer
Definition: layer_ids.h:198
void SetOffset(const wxPoint &aOffset)
Definition: pad.h:249
const int GetSizeY() const
Definition: pad.h:237
BOX2< VECTOR2I > BOX2I
Definition: box2.h:506
int GetLocalClearance() const
Definition: pad.h:390
Represent a simple polygon consisting of a zero-thickness closed chain of connected line segments.
Definition: shape_simple.h:41
static PROPERTY_MANAGER & Instance()
Definition: property_mgr.h:65
bool m_shapesDirty
Definition: pad.h:693
#define TYPE_HASH(x)
Definition: property.h:59
LSET FlipLayerMask(LSET aMask, int aCopperLayersCount)
Calculate the mask layer when flipping a footprint.
Definition: lset.cpp:567
static LSET ConnSMDMask()
layer set for a SMD pad on Front layer used for edge board connectors
Definition: pad.cpp:182
static struct PAD_DESC _PAD_DESC
void SetLocalSolderPasteMarginRatio(double aRatio)
Definition: pad.h:397
int m_chamferPositions
Definition: pad.h:723
void SetAttribute(PAD_ATTRIB aAttribute)
Definition: pad.cpp:578
const int GetDrillSizeX() const
Definition: pad.h:245
std::mutex m_shapesBuildingLock
Definition: pad.h:694
std::mutex m_polyBuildingLock
Definition: pad.h:700
int GetLocalSolderPasteMargin() const
Definition: pad.h:393
double GetRoundRectRadiusRatio() const
Definition: pad.h:523
virtual void ViewGetLayers(int aLayers[], int &aCount) const override
Return the all the layers within the VIEW the object is painted on.
Definition: pad.cpp:1168
void SetLocalClearance(int aClearance)
Definition: pad.h:391
Implementation of conversion functions that require both schematic and board internal units.
wxSize m_deltaSize
Definition: pad.h:740
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:49
int m_effectiveBoundingRadius
Definition: pad.h:702
void SetThermalSpokeWidth(int aWidth)
Set the width of the thermal spokes connecting the pad to a zone.
Definition: pad.h:490
void SetDrillSizeY(const int aY)
Definition: pad.h:246
Meta control for all pads opacity/visibility (color ignored)
Definition: layer_ids.h:226
PAD_PROP GetProperty() const
Definition: pad.h:374
wxSize m_drill
Definition: pad.h:714
int GetLocalClearanceOverrides(wxString *aSource) const override
Return any local clearance overrides set in the "classic" (ie: pre-rule) system.
Definition: pad.cpp:688
static int Compare(const PAD *padref, const PAD *padcmp)
Compare two pads and return 0 if they are equal.
Definition: pad.cpp:1023
virtual NETCLASS * GetNetClass() const
Return the NETCLASS for this item.
smd pads, back layer
Definition: layer_ids.h:199
double m_roundedCornerScale
Definition: pad.h:719
LSET m_layerMask
Definition: pad.h:737
void Move(const VECTOR2I &aVector) override
Like smd, does not appear on the solder paste layer (default)
bool HitTest(const wxPoint &aPosition, int aAccuracy=0) const override
Test if aPosition is contained within or on the bounding box of an item.
Definition: pad.cpp:969
void SetOrientationDegrees(double aOrientation)
Set orientation in degrees.
Definition: pad.h:343
Additional netnames layers (not associated with a PCB layer)
Definition: layer_ids.h:161
Smd pad, appears on the solder paste layer (default)
bool IsLocked() const override
Definition: pad.cpp:159
void SetSubRatsnest(int aSubRatsnest)
Definition: pad.h:548
static ENUM_MAP< T > & Instance()
Definition: property.h:510
double GetOrientation() const
Definition: footprint.h:190
LSET GetVisibleLayers() const
A proxy function that calls the correspondent function in m_BoardSettings.
Definition: board.cpp:481
class PCB_ARC, an arc track segment on a copper layer
Definition: typeinfo.h:97
bool IsOnLayer(PCB_LAYER_ID aLayer) const override
Test to see if this object is on the given layer.
Definition: pad.h:567
void SetSizeX(const int aX)
Definition: pad.h:234
const SHAPE_SEGMENT * GetEffectiveHoleShape() const
Return a SHAPE object representing the pad's hole.
Definition: pad.cpp:306
wxString AsString() const
Definition: kiid.cpp:218
class PAD, a pad in a footprint
Definition: typeinfo.h:89
void SetPinType(const wxString &aType)
Set the pad electrical type.
Definition: pad.h:145
show footprints on back
Definition: layer_ids.h:205
void ReplacePrimitives(const std::vector< std::shared_ptr< PCB_SHAPE >> &aPrimitivesList)
Clear the current custom shape primitives list and import a new list.
LSET GetEnabledLayers() const
A proxy function that calls the corresponding function in m_BoardSettings.
Definition: board.cpp:467
wxPoint m_pos
Definition: pad.h:681
void SetSize(const wxSize &aSize)
Definition: pad.h:232
int GetEffectiveThermalGap(wxString *aSource=nullptr) const
Return the effective thermal gap having resolved any inheritance.
Definition: pad.cpp:846
void SetDelta(const wxSize &aSize)
Definition: pad.h:239
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:229
void NORMALIZE_ANGLE_POS(T &Angle)
Definition: trigo.h:290
wxPoint m_pos0
Definition: pad.h:744
The base class for create windows for drawing purpose.
bool IsAperturePad() const
Definition: pad.h:378
VECTOR2< int > VECTOR2I
Definition: vector2d.h:623
a test point pad
#define NO_SETTER(owner, type)
Definition: property.h:621
virtual bool IsLocked() const
Definition: board_item.cpp:64
int PointCount() const
Return the number of points (vertices) in this line chain.
LSEQ Seq(const PCB_LAYER_ID *aWishListSequence, unsigned aCount) const
Return an LSEQ from the union of this LSET and a desired sequence.
Definition: lset.cpp:411
std::shared_ptr< SHAPE_COMPOUND > m_effectiveShape
Definition: pad.h:696
static SEG::ecoord Square(int a)
Definition: seg.h:122
Contains methods for drawing PCB-specific items.
Definition: pcb_painter.h:241
int GetThermalGap() const
Definition: pad.h:499
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:590
wxString ShowPadShape() const
Definition: pad.cpp:1092
#define REGISTER_TYPE(x)
Definition: property_mgr.h:248
double m_localSolderPasteMarginRatio
Definition: pad.h:774
bool Contains(const wxPoint &aPoint) const
Definition: eda_rect.cpp:57
bool IsFlipped() const
Definition: pad.cpp:203
int m_localSolderPasteMargin
Definition: pad.h:773
PAINTER * GetPainter() const
Return the painter object used by the view for drawing #VIEW_ITEMS.
Definition: view.h:208
class PCB_TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:95
EDA_RECT m_effectiveBoundingBox
Definition: pad.h:695
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
Plated through hole pad.
void MIRROR(T &aPoint, const T &aMirrorRef)
Updates aPoint with the mirror of aPoint relative to the aMirrorRef.
Definition: mirror.h:40
int m_localSolderMaskMargin
Definition: pad.h:772
void SetPadToDieLength(int aLength)
Definition: pad.h:383
void SetProperty(PAD_PROP aProperty)
Definition: pad.cpp:589
void TransformRoundChamferedRectToPolygon(SHAPE_POLY_SET &aCornerBuffer, const wxPoint &aPosition, const wxSize &aSize, double aRotation, int aCornerRadius, double aChamferRatio, int aChamferCorners, int aInflate, int aError, ERROR_LOC aErrorLoc)
Convert a rectangle with rounded corners and/or chamfered corners to a polygon.
void ImportSettingsFrom(const PAD &aMasterPad)
Import the pad settings from aMasterPad.
Definition: pad.cpp:1360
std::shared_ptr< SHAPE_SEGMENT > m_effectiveHoleShape
Definition: pad.h:697
a pad used as heat sink, usually in SMD footprints
int GetEffectiveThermalSpokeWidth(wxString *aSource=nullptr) const
Return the effective thermal spoke width having resolved any inheritance.
Definition: pad.cpp:827
bool m_keepTopBottomLayer
Definition: pad.h:759
PCB specific render settings.
Definition: pcb_painter.h:64
double ViewGetLOD(int aLayer, KIGFX::VIEW *aView) const override
Return the level of detail (LOD) of the item.
Definition: pad.cpp:1245
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
void SetLocalSolderMaskMargin(int aMargin)
Definition: pad.h:387
PAD_SHAPE
The set of pad shapes, used with PAD::{Set,Get}Shape() DO NOT REORDER, legacy_plugin is dependent on ...
Definition: pad_shapes.h:33
int m_localClearance
Definition: pad.h:771
const wxPoint & GetOffset() const
Definition: pad.h:250
std::shared_ptr< SHAPE_POLY_SET > m_effectivePolygon
Definition: pad.h:701
void GetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList) override
Populate aList of MSG_PANEL_ITEM objects with it's internal state for display purposes.
Definition: pad.cpp:865
void SetDrillSizeX(const int aX)
Definition: pad.h:244
const wxSize & GetDrillSize() const
Definition: pad.h:243
virtual void SwapData(BOARD_ITEM *aImage) override
Swap data between aItem and aImage.
Definition: pad.cpp:1444
virtual wxString layerMaskDescribe() const
Return a string (to be shown to the user) describing a layer mask.
Definition: board_item.cpp:85
wxPoint ShapePos() const
Definition: pad.cpp:673
like PAD_PTH, but not plated
double m_chamferScale
Definition: pad.h:721
bool IsHoleLayer(LAYER_NUM aLayer)
Definition: layer_ids.h:835
Display value expressed in distance units (mm/inch)
Definition: property.h:53
bool FlashLayer(int aLayer) const
Check to see whether the pad should be flashed on the specific layer.
Definition: pad.cpp:223
LSET is a set of PCB_LAYER_IDs.
Definition: layer_ids.h:504
handle color for not plated holes (holes, not pads)
Definition: layer_ids.h:193
int m_thermalGap
Definition: pad.h:779
int GetThermalSpokeWidth() const
Definition: pad.h:491
double GetOrientation() const
Return the rotation angle of the pad in a variety of units (the basic call returns tenths of degrees)...
Definition: pad.h:349
VECTOR2< double > VECTOR2D
Definition: vector2d.h:622
void SetPos0(const wxPoint &aPos)
Definition: pad.h:226
bool IsBackLayer(PCB_LAYER_ID aLayerId)
Layer classification: check if it's a back layer.
Definition: layer_ids.h:895
void SetLocalCoord()
< Set relative coordinates.
Definition: pad.cpp:563
virtual PCB_RENDER_SETTINGS * GetSettings() override
Return a pointer to current settings that are going to be used when drawing items.
Definition: pcb_painter.h:247
void Flip(const wxPoint &aCentre, bool aFlipLeftRight) override
Flip this object, i.e.
Definition: pad.cpp:606
void SetThermalGap(int aGap)
Definition: pad.h:498
Represent a set of closed polygons.
int m_thermalWidth
Definition: pad.h:778
const wxPoint GetOrigin() const
Definition: eda_rect.h:101
coord_type GetWidth() const
Definition: box2.h:180
void SetDrillSize(const wxSize &aSize)
Definition: pad.h:242
const wxSize & GetSize() const
Definition: pad.h:233
wxAny Get(PROPERTY_BASE *aProperty)
Definition: inspectable.h:86
ZONE_CONNECTION GetEffectiveZoneConnection(wxString *aSource=nullptr) const
Return the zone connection in effect (either locally overridden or overridden in the parent footprint...
Definition: pad.cpp:806
Smd pad, used in BGA footprints.
virtual const BOX2I ViewBBox() const override
Return the bounding box of the item covering all its layers.
Definition: pad.cpp:1331
std::shared_ptr< CONNECTIVITY_DATA > GetConnectivity() const
Return a list of missing connections between components/tracks.
Definition: board.h:344
void InheritsAfter(TYPE_ID aDerived, TYPE_ID aBase)
Declare an inheritance relationship between types.
show footprints on front
Definition: layer_ids.h:204
static LSET PTHMask()
layer set for a through hole pad
Definition: pad.cpp:168
const EDA_RECT GetBoundingBox() const override
The bounding box is cached, so this will be efficient most of the time.
Definition: pad.cpp:536
const wxString & GetNumber() const
Definition: pad.h:129
double m_orient
Definition: pad.h:751
int GetLocalClearance() const
Definition: footprint.h:209
const wxString & GetPinType() const
Definition: pad.h:146
PAD_SHAPE GetShape() const
Definition: pad.h:170
const wxString & GetReference() const
Definition: footprint.h:449
a fiducial (usually a smd) local to the parent footprint
#define _(s)
PAD & operator=(const PAD &aOther)
Definition: pad.cpp:126
virtual std::shared_ptr< SHAPE > GetEffectiveShape(PCB_LAYER_ID aLayer=UNDEFINED_LAYER) const override
Some pad shapes can be complex (rounded/chamfered rectangle), even without considering custom shapes.
Definition: pad.cpp:297
static LSET AllLayersMask()
Definition: lset.cpp:787
LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
Definition: pad.h:368
class ZONE, a copper pour area
Definition: typeinfo.h:105
An abstract shape on 2D plane.
Definition: shape.h:116
void SetZoneConnection(ZONE_CONNECTION aType)
Definition: pad.h:475
void SetDrawCoord()
Definition: pad.cpp:545
ZONE_CONNECTION m_zoneConnection
Definition: pad.h:777
void SetPinFunction(const wxString &aName)
Set the pad function (pin name in schematic)
Definition: pad.h:139
void BuildEffectivePolygon() const
Definition: pad.cpp:497
void SetCustomShapeInZoneOpt(CUST_PAD_SHAPE_IN_ZONE aOption)
Set the option for the custom pad shape to use as clearance area in copper zones.
Definition: pad.h:198
E_SERIE r
Definition: eserie.cpp:41
bool IsFrontLayer(PCB_LAYER_ID aLayerId)
Layer classification: check if it's a front layer.
Definition: layer_ids.h:872
Class that other classes need to inherit from, in order to be inspectable.
Definition: inspectable.h:35
void SetRoundRectRadiusRatio(double aRadiusScale)
Has meaning only for rounded rectangle pads.
Definition: pad.cpp:272
PAD_ATTRIB
The set of pad shapes, used with PAD::{Set,Get}Attribute().
Definition: pad_shapes.h:79
int GetThermalWidth() const
Definition: footprint.h:230
EDA_ITEM & operator=(const EDA_ITEM &aItem)
Assign the members of aItem to another object.
Definition: eda_item.cpp:180
int GetLocalClearance(wxString *aSource) const override
Return any local clearances set in the "classic" (ie: pre-rule) system.
Definition: pad.cpp:702
void SetDrillShape(PAD_DRILL_SHAPE_T aShape)
Definition: pad.h:353
wxString UnescapeString(const wxString &aSource)
void BuildEffectiveShapes(PCB_LAYER_ID aLayer) const
Rebuild the effective shape cache (and bounding box and radius) for the pad and clears the dirty bit.
Definition: pad.cpp:324
double GetLocalSolderPasteMarginRatio() const
Definition: pad.h:396
class FOOTPRINT, a footprint
Definition: typeinfo.h:88
void SetRoundRectCornerRadius(double aRadius)
Has meaning only for rounded rectangle pads.
Definition: pad.cpp:263
const KIID m_Uuid
Definition: eda_item.h:475
const Vec & GetPosition() const
Definition: box2.h:177
Some functions to handle hotkeys in KiCad.
int GetRoundRectCornerRadius() const
Definition: pad.cpp:257
const wxSize & GetDelta() const
Definition: pad.h:240
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
wxSize m_size
Definition: pad.h:715
int GetSolderMaskMargin() const
Definition: pad.cpp:711
FOOTPRINT * GetParent() const
Definition: pad.cpp:1354
void Rotate(double aAngle, const VECTOR2I &aCenter=VECTOR2I(0, 0)) override
Rotate all vertices by a given angle.
void SetChamferPositions(int aPositions)
Has meaning only for chamfered rectangular pads.
Definition: pad.h:541
EDA_UNITS
Definition: eda_units.h:38
void Normalize()
Ensures that the height ant width are positive.
Definition: eda_rect.cpp:35
wxPoint m_offset
Definition: pad.h:735
const wxPoint & GetPos0() const
Definition: pad.h:227
static LSET PhysicalLayersMask()
Return a mask holding all layers which are physically realized.
Definition: lset.cpp:849
double GetOrientationDegrees() const
Definition: footprint.h:191
void TransformShapeWithClearanceToPolygon(SHAPE_POLY_SET &aCornerBuffer, PCB_LAYER_ID aLayer, int aClearanceValue, int aMaxError, ERROR_LOC aErrorLoc, bool ignoreLineWidth=false) const override
Convert the pad shape to a closed polygon.
void SetSizeY(const int aY)
Definition: pad.h:236
int GetBoundingRadius() const
Return the radius of a minimum sized circle which fully encloses this pad.
Definition: pad.cpp:315
int GetLocalSolderMaskMargin() const
Definition: footprint.h:206
static LSET ApertureMask()
layer set for an aperture pad
Definition: pad.cpp:196
void SetLayerSet(LSET aLayers) override
Definition: pad.h:367
bool m_removeUnconnectedLayer
< If true, the pad copper is removed for layers that are not connected.
Definition: pad.h:756
PAD_DESC()
Definition: pad.cpp:1454
CUST_PAD_SHAPE_IN_ZONE GetCustomShapeInZoneOpt() const
Definition: pad.h:188
multilayer pads, usually with holes
Definition: layer_ids.h:209
a fiducial (usually a smd) for the full board
double GetChamferRectRatio() const
Definition: pad.h:532
std::vector< std::shared_ptr< PCB_SHAPE > > m_editPrimitives
Definition: pad.h:690
BITMAPS
A list of all bitmap identifiers.
Definition: bitmaps_list.h:32
wxSize GetSolderPasteMargin() const
Usually < 0 (mask shape smaller than pad)because the margin can be dependent on the pad size,...
Definition: pad.cpp:756
int GetSubRatsnest() const
Definition: pad.h:547
PAD_PROP
Ghe set of pad properties used in Gerber files (Draw files, and P&P files) to define some properties ...
Definition: pad_shapes.h:95
wxPoint GetPosition() const override
Definition: pad.h:178
void SetLocalSolderPasteMargin(int aMargin)
Definition: pad.h:394
PAD_DRILL_SHAPE_T GetDrillShape() const
Definition: pad.h:354
no special fabrication property
ENUM_TO_WXANY(PAD_ATTRIB)
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:190
const int GetDrillSizeY() const
Definition: pad.h:247
Represent a polyline (an zero-thickness chain of connected line segments).
bool IsNetnameLayer(LAYER_NUM aLayer)
Test whether a layer is a netname layer.
Definition: layer_ids.h:964
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:65
PAD_ATTRIB GetAttribute() const
Definition: pad.h:371
void SetNumber(const wxString &aNumber)
Set the pad number (note that it can be alphanumeric, such as the array reference "AA12").
Definition: pad.h:128
double GetOrientationDegrees() const
Definition: pad.h:350
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
Definition: layer_ids.h:71
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
void SetPosition(const wxPoint &aPos) override
Definition: pad.h:172
void AddProperty(PROPERTY_BASE *aProperty)
Register a property.
void SetDirty()
Definition: pad.h:361
class ZONE, managed by a footprint
Definition: typeinfo.h:94
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
Definition: pad.cpp:1162
Handle the component boundary box.
Definition: eda_rect.h:42
double DECIDEG2RAD(double deg)
Definition: trigo.h:233
const int GetSizeX() const
Definition: pad.h:235
static std::string PAD_SHAPE_T_asString(PAD_SHAPE a)
Definition: pad_shapes.h:47
const std::shared_ptr< SHAPE_POLY_SET > & GetEffectivePolygon() const
Definition: pad.cpp:288
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:73
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:100
coord_type GetHeight() const
Definition: box2.h:181
wxPoint GetPosition() const override
Definition: footprint.h:186
wxString GetSelectMenuText(EDA_UNITS aUnits) const override
Return the text to display to be used in the selection clarification context menu when multiple items...
Definition: pad.cpp:1121
double NormalizeAngleDegrees(double Angle, double aMin, double aMax)
Normalize angle to be aMin < angle <= aMax angle is in degrees.
Definition: trigo.h:327
virtual int GetOwnClearance(PCB_LAYER_ID aLayer, wxString *aSource=nullptr) const
Return an item's "own" clearance in internal units.
double GetLocalSolderPasteMarginRatio() const
Definition: footprint.h:223
bool Intersects(const EDA_RECT &aRect) const
Test for a common area between rectangles.
Definition: eda_rect.cpp:150
void SetShape(PAD_SHAPE aShape)
Set the new shape of this pad.
Definition: pad.h:161
int GetChamferPositions() const
Definition: pad.h:542
wxString GetParentAsString() const
Definition: pad.h:107
int m_lengthPadToDie
Definition: pad.h:753
constexpr int delta
to draw pad holes (plated)
Definition: layer_ids.h:210
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
Definition: board_item.cpp:36
Provide class metadata.Helper macro to map type hashes to names.
Definition: property_mgr.h:62
PAD_ATTRIB m_attribute
Definition: pad.h:747
a pad with a castellated through hole
class PCB_VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:96
wxString ShowPadAttr() const
Definition: pad.cpp:1108
ZONE_CONNECTION GetZoneConnection() const
Definition: footprint.h:227
static LSET UnplatedHoleMask()
layer set for a mechanical unplated through hole pad
Definition: pad.cpp:189
CUST_PAD_SHAPE_IN_ZONE m_customShapeClearanceArea
Definition: pad.h:709
wxString m_number
Definition: pad.h:677
int GetLocalSolderPasteMargin() const
Definition: footprint.h:220
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
Definition: view.h:68
Definition: pad.h:57
void SetChamferRectRatio(double aChamferScale)
Has meaning only for chamfered rectangular pads.
Definition: pad.cpp:280
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:254
Message panel definition file.
static LSET SMDMask()
layer set for a SMD pad on Front layer
Definition: pad.cpp:175
static constexpr int Millimeter2iu(double mm)
#define _HKI(x)
int GetPadToDieLength() const
Definition: pad.h:384
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition: board_item.h:140
PAD(FOOTPRINT *parent)
Definition: pad.cpp:58
const wxString & GetPinFunction() const
Definition: pad.h:140
bool m_polyDirty
Definition: pad.h:699
int GetThermalGap() const
Definition: footprint.h:233
const std::vector< std::shared_ptr< PCB_SHAPE > > & GetPrimitives() const
Accessor to the basic shape list for custom-shaped pads.
Definition: pad.h:301
PAD_SHAPE GetAnchorPadShape() const
Definition: pad.h:183
EDA_UNITS GetUserUnits() const
Return the user units currently in use.
void SetOrientation(double aAngle)
Set the rotation angle of the pad.
Definition: pad.cpp:597
EDA_RECT & Inflate(wxCoord dx, wxCoord dy)
Inflate the rectangle horizontally by dx and vertically by dy.
Definition: eda_rect.cpp:364
const wxSize GetSize() const
Definition: eda_rect.h:91
PAD_PROP m_property
Definition: pad.h:749
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:113
void SetAnchorPadShape(PAD_SHAPE aShape)
Set the shape of the anchor pad for custom shaped pads.
Definition: pad.h:209
bool IsLayerVisible(int aLayer) const
Return information about visibility of a particular layer.
Definition: view.h:405
void Rotate(const wxPoint &aRotCentre, double aAngle) override
Rotate this object.
Definition: pad.cpp:1080
bool CanHaveNumber() const
Indicates whether or not the pad can have a number.
Definition: pad.cpp:145