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