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-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 
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 ), types );
233 }
234 
235 
237 {
238  return KiROUND( std::min( m_size.x, m_size.y ) * m_roundedCornerScale );
239 }
240 
241 
242 void PAD::SetRoundRectCornerRadius( double aRadius )
243 {
244  int min_r = std::min( m_size.x, m_size.y );
245 
246  if( min_r > 0 )
247  SetRoundRectRadiusRatio( aRadius / min_r );
248 }
249 
250 
251 void PAD::SetRoundRectRadiusRatio( double aRadiusScale )
252 {
253  m_roundedCornerScale = std::max( 0.0, std::min( aRadiusScale, 0.5 ) );
254 
255  SetDirty();
256 }
257 
258 
259 void PAD::SetChamferRectRatio( double aChamferScale )
260 {
261  m_chamferScale = std::max( 0.0, std::min( aChamferScale, 0.5 ) );
262 
263  SetDirty();
264 }
265 
266 
267 const std::shared_ptr<SHAPE_POLY_SET>& PAD::GetEffectivePolygon() const
268 {
269  if( m_polyDirty )
271 
272  return m_effectivePolygon;
273 }
274 
275 
276 std::shared_ptr<SHAPE> PAD::GetEffectiveShape( PCB_LAYER_ID aLayer ) const
277 {
278  if( m_shapesDirty )
279  BuildEffectiveShapes( aLayer );
280 
281  return m_effectiveShape;
282 }
283 
284 
286 {
287  if( m_shapesDirty )
289 
290  return m_effectiveHoleShape.get();
291 }
292 
293 
295 {
296  if( m_polyDirty )
298 
300 }
301 
302 
304 {
305  std::lock_guard<std::mutex> RAII_lock( m_shapesBuildingLock );
306 
307  // If we had to wait for the lock then we were probably waiting for someone else to
308  // finish rebuilding the shapes. So check to see if they're clean now.
309  if( !m_shapesDirty )
310  return;
311 
312  BOARD* board = GetBoard();
313  int maxError = board ? board->GetDesignSettings().m_MaxError : ARC_HIGH_DEF;
314 
315  m_effectiveShape = std::make_shared<SHAPE_COMPOUND>();
316  m_effectiveHoleShape = nullptr;
317 
318  auto add = [this]( SHAPE* aShape )
319  {
320  m_effectiveShape->AddShape( aShape );
321  };
322 
323  wxPoint shapePos = ShapePos(); // Fetch only once; rotation involves trig
324  PAD_SHAPE effectiveShape = GetShape();
325 
326  if( GetShape() == PAD_SHAPE::CUSTOM )
327  effectiveShape = GetAnchorPadShape();
328 
329  switch( effectiveShape )
330  {
331  case PAD_SHAPE::CIRCLE:
332  add( new SHAPE_CIRCLE( shapePos, m_size.x / 2 ) );
333  break;
334 
335  case PAD_SHAPE::OVAL:
336  if( m_size.x == m_size.y ) // the oval pad is in fact a circle
337  add( new SHAPE_CIRCLE( shapePos, m_size.x / 2 ) );
338  else
339  {
340  wxSize half_size = m_size / 2;
341  int half_width = std::min( half_size.x, half_size.y );
342  wxPoint half_len( half_size.x - half_width, half_size.y - half_width );
343  RotatePoint( &half_len, m_orient );
344  add( new SHAPE_SEGMENT( shapePos - half_len, shapePos + half_len, half_width * 2 ) );
345  }
346  break;
347 
348  case PAD_SHAPE::RECT:
351  {
352  int r = ( effectiveShape == PAD_SHAPE::ROUNDRECT ) ? GetRoundRectCornerRadius() : 0;
353  wxPoint half_size( m_size.x / 2, m_size.y / 2 );
354  wxSize trap_delta( 0, 0 );
355 
356  if( r )
357  {
358  half_size -= wxPoint( r, r );
359 
360  // Avoid degenerated shapes (0 length segments) that always create issues
361  // For roundrect pad very near a circle, use only a circle
362  const int min_len = Millimeter2iu( 0.0001);
363 
364  if( half_size.x < min_len && half_size.y < min_len )
365  {
366  add( new SHAPE_CIRCLE( shapePos, r ) );
367  break;
368  }
369  }
370  else if( effectiveShape == PAD_SHAPE::TRAPEZOID )
371  {
372  trap_delta = m_deltaSize / 2;
373  }
374 
375  SHAPE_LINE_CHAIN corners;
376 
377  corners.Append( -half_size.x - trap_delta.y, half_size.y + trap_delta.x );
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 
382  corners.Rotate( -DECIDEG2RAD( m_orient ) );
383  corners.Move( shapePos );
384 
385  // GAL renders rectangles faster than 4-point polygons so it's worth checking if our
386  // body shape is a rectangle.
387  if( corners.PointCount() == 4
388  &&
389  ( ( corners.CPoint( 0 ).y == corners.CPoint( 1 ).y
390  && corners.CPoint( 1 ).x == corners.CPoint( 2 ).x
391  && corners.CPoint( 2 ).y == corners.CPoint( 3 ).y
392  && corners.CPoint( 3 ).x == corners.CPoint( 0 ).x )
393  ||
394  ( corners.CPoint( 0 ).x == corners.CPoint( 1 ).x
395  && corners.CPoint( 1 ).y == corners.CPoint( 2 ).y
396  && corners.CPoint( 2 ).x == corners.CPoint( 3 ).x
397  && corners.CPoint( 3 ).y == corners.CPoint( 0 ).y )
398  )
399  )
400  {
401  int width = std::abs( corners.CPoint( 2 ).x - corners.CPoint( 0 ).x );
402  int height = std::abs( corners.CPoint( 2 ).y - corners.CPoint( 0 ).y );
403  VECTOR2I pos( std::min( corners.CPoint( 2 ).x, corners.CPoint( 0 ).x ),
404  std::min( corners.CPoint( 2 ).y, corners.CPoint( 0 ).y ) );
405 
406  add( new SHAPE_RECT( pos, width, height ) );
407  }
408  else
409  {
410  add( new SHAPE_SIMPLE( corners ) );
411  }
412 
413  if( r )
414  {
415  add( new SHAPE_SEGMENT( corners.CPoint( 0 ), corners.CPoint( 1 ), r * 2 ) );
416  add( new SHAPE_SEGMENT( corners.CPoint( 1 ), corners.CPoint( 2 ), r * 2 ) );
417  add( new SHAPE_SEGMENT( corners.CPoint( 2 ), corners.CPoint( 3 ), r * 2 ) );
418  add( new SHAPE_SEGMENT( corners.CPoint( 3 ), corners.CPoint( 0 ), r * 2 ) );
419  }
420  }
421  break;
422 
424  {
425  SHAPE_POLY_SET outline;
426 
429  GetChamferPositions(), maxError, ERROR_INSIDE );
430 
431  add( new SHAPE_SIMPLE( outline.COutline( 0 ) ) );
432  }
433  break;
434 
435  default:
436  wxFAIL_MSG( "PAD::buildEffectiveShapes: Unsupported pad shape: "
437  + PAD_SHAPE_T_asString( effectiveShape ) );
438  break;
439  }
440 
441  if( GetShape() == PAD_SHAPE::CUSTOM )
442  {
443  for( const std::shared_ptr<PCB_SHAPE>& primitive : m_editPrimitives )
444  {
445  for( SHAPE* shape : primitive->MakeEffectiveShapes() )
446  {
447  shape->Rotate( -DECIDEG2RAD( m_orient ) );
448  shape->Move( shapePos );
449  add( shape );
450  }
451  }
452  }
453 
454  BOX2I bbox = m_effectiveShape->BBox();
455  m_effectiveBoundingBox = EDA_RECT( (wxPoint) bbox.GetPosition(),
456  wxSize( bbox.GetWidth(), bbox.GetHeight() ) );
457 
458  // Hole shape
459  //
460  wxSize half_size = m_drill / 2;
461  int half_width = std::min( half_size.x, half_size.y );
462  wxPoint half_len( half_size.x - half_width, half_size.y - half_width );
463 
464  RotatePoint( &half_len, m_orient );
465 
466  m_effectiveHoleShape = std::make_shared<SHAPE_SEGMENT>( m_pos - half_len, m_pos + half_len,
467  half_width * 2 );
468 
469  // All done
470  //
471  m_shapesDirty = false;
472 }
473 
474 
476 {
477  std::lock_guard<std::mutex> RAII_lock( m_polyBuildingLock );
478 
479  // If we had to wait for the lock then we were probably waiting for someone else to
480  // finish rebuilding the shapes. So check to see if they're clean now.
481  if( !m_polyDirty )
482  return;
483 
484  BOARD* board = GetBoard();
485  int maxError = board ? board->GetDesignSettings().m_MaxError : ARC_HIGH_DEF;
486 
487  // Polygon
488  //
489  m_effectivePolygon = std::make_shared<SHAPE_POLY_SET>();
491  ERROR_INSIDE );
492 
493  // Bounding radius
494  //
495  // PADSTACKS TODO: these will both need to cycle through all layers to get the largest
496  // values....
497  //
499 
500  for( int cnt = 0; cnt < m_effectivePolygon->OutlineCount(); ++cnt )
501  {
502  const SHAPE_LINE_CHAIN& poly = m_effectivePolygon->COutline( cnt );
503 
504  for( int ii = 0; ii < poly.PointCount(); ++ii )
505  {
506  int dist = KiROUND( ( poly.CPoint( ii ) - m_pos ).EuclideanNorm() );
508  }
509  }
510 
511  // All done
512  //
513  m_polyDirty = false;
514 }
515 
516 
518 {
519  if( m_shapesDirty )
521 
522  return m_effectiveBoundingBox;
523 }
524 
525 
527 {
528  FOOTPRINT* parentFootprint = static_cast<FOOTPRINT*>( m_parent );
529 
530  m_pos = m_pos0;
531 
532  if( parentFootprint == NULL )
533  return;
534 
535  double angle = parentFootprint->GetOrientation();
536 
537  RotatePoint( &m_pos.x, &m_pos.y, angle );
538  m_pos += parentFootprint->GetPosition();
539 
540  SetDirty();
541 }
542 
543 
545 {
546  FOOTPRINT* parentFootprint = static_cast<FOOTPRINT*>( m_parent );
547 
548  if( parentFootprint == NULL )
549  {
550  m_pos0 = m_pos;
551  return;
552  }
553 
554  m_pos0 = m_pos - parentFootprint->GetPosition();
555  RotatePoint( &m_pos0.x, &m_pos0.y, -parentFootprint->GetOrientation() );
556 }
557 
558 
559 void PAD::SetAttribute( PAD_ATTRIB aAttribute )
560 {
561  m_attribute = aAttribute;
562 
563  if( aAttribute == PAD_ATTRIB::SMD )
564  m_drill = wxSize( 0, 0 );
565 
566  SetDirty();
567 }
568 
569 
570 void PAD::SetProperty( PAD_PROP aProperty )
571 {
572  m_property = aProperty;
573 
574  SetDirty();
575 }
576 
577 
578 void PAD::SetOrientation( double aAngle )
579 {
580  NORMALIZE_ANGLE_POS( aAngle );
581  m_orient = aAngle;
582 
583  SetDirty();
584 }
585 
586 
587 void PAD::Flip( const wxPoint& aCentre, bool aFlipLeftRight )
588 {
589  if( aFlipLeftRight )
590  {
591  MIRROR( m_pos.x, aCentre.x );
592  MIRROR( m_pos0.x, 0 );
593  MIRROR( m_offset.x, 0 );
594  MIRROR( m_deltaSize.x, 0 );
595  }
596  else
597  {
598  MIRROR( m_pos.y, aCentre.y );
599  MIRROR( m_pos0.y, 0 );
600  MIRROR( m_offset.y, 0 );
601  MIRROR( m_deltaSize.y, 0 );
602  }
603 
605 
606  auto mirrorBitFlags = []( int& aBitfield, int a, int b )
607  {
608  bool temp = aBitfield & a;
609 
610  if( aBitfield & b )
611  aBitfield |= a;
612  else
613  aBitfield &= ~a;
614 
615  if( temp )
616  aBitfield |= b;
617  else
618  aBitfield &= ~b;
619  };
620 
621  if( aFlipLeftRight )
622  {
625  }
626  else
627  {
630  }
631 
632  // flip pads layers
633  // PADS items are currently on all copper layers, or
634  // currently, only on Front or Back layers.
635  // So the copper layers count is not taken in account
637 
638  // Flip the basic shapes, in custom pads
639  FlipPrimitives( aFlipLeftRight );
640 
641  SetDirty();
642 }
643 
644 
645 // Flip (mirror) the basic shapes (primitives), in custom pads
646 void PAD::FlipPrimitives( bool aFlipLeftRight )
647 {
648  for( std::shared_ptr<PCB_SHAPE>& primitive : m_editPrimitives )
649  primitive->Flip( wxPoint( 0, 0 ), aFlipLeftRight );
650 
651  SetDirty();
652 }
653 
654 
655 // Returns the position of the pad.
656 wxPoint PAD::ShapePos() const
657 {
658  if( m_offset.x == 0 && m_offset.y == 0 )
659  return m_pos;
660 
661  wxPoint loc_offset = m_offset;
662 
663  RotatePoint( &loc_offset, m_orient );
664 
665  wxPoint shape_pos = m_pos + loc_offset;
666 
667  return shape_pos;
668 }
669 
670 
671 int PAD::GetLocalClearanceOverrides( wxString* aSource ) const
672 {
673  // A pad can have specific clearance that overrides its NETCLASS clearance value
674  if( GetLocalClearance() )
675  return GetLocalClearance( aSource );
676 
677  // A footprint can have a specific clearance value
678  if( GetParent() && GetParent()->GetLocalClearance() )
679  return GetParent()->GetLocalClearance( aSource );
680 
681  return 0;
682 }
683 
684 
685 int PAD::GetLocalClearance( wxString* aSource ) const
686 {
687  if( aSource )
688  *aSource = wxString::Format( _( "pad %s" ), GetName() );
689 
690  return m_localClearance;
691 }
692 
693 
694 // Mask margins handling:
695 
697 {
698  // The pad inherits the margin only to calculate a default shape,
699  // therefore only if it is also a copper layer
700  // Pads defined only on mask layers (and perhaps on other tech layers) use the shape
701  // defined by the pad settings only
702  bool isOnCopperLayer = ( m_layerMask & LSET::AllCuMask() ).any();
703 
704  if( !isOnCopperLayer )
705  return 0;
706 
707  int margin = m_localSolderMaskMargin;
708 
709  FOOTPRINT* parentFootprint = GetParent();
710 
711  if( parentFootprint )
712  {
713  if( margin == 0 )
714  {
715  if( parentFootprint->GetLocalSolderMaskMargin() )
716  margin = parentFootprint->GetLocalSolderMaskMargin();
717  }
718 
719  if( margin == 0 )
720  {
721  BOARD* brd = GetBoard();
722 
723  if( brd )
724  margin = brd->GetDesignSettings().m_SolderMaskMargin;
725  }
726  }
727 
728  // ensure mask have a size always >= 0
729  if( margin < 0 )
730  {
731  int minsize = -std::min( m_size.x, m_size.y ) / 2;
732 
733  if( margin < minsize )
734  margin = minsize;
735  }
736 
737  return margin;
738 }
739 
740 
742 {
743  // The pad inherits the margin only to calculate a default shape,
744  // therefore only if it is also a copper layer.
745  // Pads defined only on mask layers (and perhaps on other tech layers) use the shape
746  // defined by the pad settings only
747  bool isOnCopperLayer = ( m_layerMask & LSET::AllCuMask() ).any();
748 
749  if( !isOnCopperLayer )
750  return wxSize( 0, 0 );
751 
752  int margin = m_localSolderPasteMargin;
753  double mratio = m_localSolderPasteMarginRatio;
754 
755  FOOTPRINT* parentFootprint = GetParent();
756 
757  if( parentFootprint )
758  {
759  if( margin == 0 )
760  margin = parentFootprint->GetLocalSolderPasteMargin();
761 
762  auto brd = GetBoard();
763 
764  if( margin == 0 && brd )
765  margin = brd->GetDesignSettings().m_SolderPasteMargin;
766 
767  if( mratio == 0.0 )
768  mratio = parentFootprint->GetLocalSolderPasteMarginRatio();
769 
770  if( mratio == 0.0 && brd )
771  {
772  mratio = brd->GetDesignSettings().m_SolderPasteMarginRatio;
773  }
774  }
775 
776  wxSize pad_margin;
777  pad_margin.x = margin + KiROUND( m_size.x * mratio );
778  pad_margin.y = margin + KiROUND( m_size.y * mratio );
779 
780  // ensure mask have a size always >= 0
781  if( pad_margin.x < -m_size.x / 2 )
782  pad_margin.x = -m_size.x / 2;
783 
784  if( pad_margin.y < -m_size.y / 2 )
785  pad_margin.y = -m_size.y / 2;
786 
787  return pad_margin;
788 }
789 
790 
792 {
793  FOOTPRINT* parentFootprint = GetParent();
794 
795  if( m_zoneConnection == ZONE_CONNECTION::INHERITED && parentFootprint )
796  {
797  if( aSource )
798  *aSource = _( "parent footprint" );
799 
800  return parentFootprint->GetZoneConnection();
801  }
802  else
803  {
804  if( aSource )
805  *aSource = _( "pad" );
806 
807  return m_zoneConnection;
808  }
809 }
810 
811 
812 int PAD::GetEffectiveThermalSpokeWidth( wxString* aSource ) const
813 {
814  FOOTPRINT* parentFootprint = GetParent();
815 
816  if( m_thermalWidth == 0 && parentFootprint )
817  {
818  if( aSource )
819  *aSource = _( "parent footprint" );
820 
821  return parentFootprint->GetThermalWidth();
822  }
823 
824  if( aSource )
825  *aSource = _( "pad" );
826 
827  return m_thermalWidth;
828 }
829 
830 
831 int PAD::GetEffectiveThermalGap( wxString* aSource ) const
832 {
833  FOOTPRINT* parentFootprint = GetParent();
834 
835  if( m_thermalGap == 0 && parentFootprint )
836  {
837  if( aSource )
838  *aSource = _( "parent footprint" );
839 
840  return parentFootprint->GetThermalGap();
841  }
842 
843  if( aSource )
844  *aSource = _( "pad" );
845 
846  return m_thermalGap;
847 }
848 
849 
850 void PAD::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
851 {
852  EDA_UNITS units = aFrame->GetUserUnits();
853  wxString msg;
854  FOOTPRINT* parentFootprint = static_cast<FOOTPRINT*>( m_parent );
855 
856  if( parentFootprint )
857  aList.emplace_back( _( "Footprint" ), parentFootprint->GetReference() );
858 
859  aList.emplace_back( _( "Pad" ), m_name );
860 
861  if( !GetPinFunction().IsEmpty() )
862  aList.emplace_back( _( "Pin Name" ), GetPinFunction() );
863 
864  if( !GetPinType().IsEmpty() )
865  aList.emplace_back( _( "Pin Type" ), GetPinType() );
866 
867  aList.emplace_back( _( "Net" ), UnescapeString( GetNetname() ) );
868 
869  aList.emplace_back( _( "NetClass" ), UnescapeString( GetNetClass()->GetName() ) );
870 
871  if( IsLocked() )
872  aList.emplace_back( _( "Status" ), _( "Locked" ) );
873 
875  aList.emplace_back( _( "Layer" ), layerMaskDescribe() );
876 
877  // Show the pad shape, attribute and property
878  wxString props = ShowPadAttr();
879 
880  if( GetProperty() != PAD_PROP::NONE )
881  props += ',';
882 
883  switch( GetProperty() )
884  {
885  case PAD_PROP::NONE: break;
886  case PAD_PROP::BGA: props += _("BGA" ); break;
887  case PAD_PROP::FIDUCIAL_GLBL: props += _("Fiducial global" ); break;
888  case PAD_PROP::FIDUCIAL_LOCAL: props += _("Fiducial local" ); break;
889  case PAD_PROP::TESTPOINT: props += _("Test point" ); break;
890  case PAD_PROP::HEATSINK: props += _("Heat sink" ); break;
891  case PAD_PROP::CASTELLATED: props += _("Castellated" ); break;
892  }
893 
894  aList.emplace_back( ShowPadShape(), props );
895 
896  if( ( GetShape() == PAD_SHAPE::CIRCLE || GetShape() == PAD_SHAPE::OVAL ) && m_size.x == m_size.y )
897  {
898  aList.emplace_back( _( "Diameter" ), MessageTextFromValue( units, m_size.x ) );
899  }
900  else
901  {
902  aList.emplace_back( _( "Width" ), MessageTextFromValue( units, m_size.x ) );
903  aList.emplace_back( _( "Height" ), MessageTextFromValue( units, m_size.y ) );
904  }
905 
906  double fp_orient_degrees = parentFootprint ? parentFootprint->GetOrientationDegrees() : 0;
907  double pad_orient_degrees = GetOrientationDegrees() - fp_orient_degrees;
908  pad_orient_degrees = NormalizeAngleDegrees( pad_orient_degrees, -180.0, +180.0 );
909 
910  if( fp_orient_degrees != 0.0 )
911  msg.Printf( wxT( "%g(+ %g)" ), pad_orient_degrees, fp_orient_degrees );
912  else
913  msg.Printf( wxT( "%g" ), GetOrientationDegrees() );
914 
915  aList.emplace_back( _( "Rotation" ), msg );
916 
917  if( GetPadToDieLength() )
918  {
919  msg = MessageTextFromValue(units, GetPadToDieLength() );
920  aList.emplace_back( _( "Length in Package" ), msg );
921  }
922 
923  if( m_drill.x > 0 || m_drill.y > 0 )
924  {
926  {
927  aList.emplace_back( _( "Hole" ),
928  wxString::Format( "%s",
929  MessageTextFromValue( units, m_drill.x ) ) );
930  }
931  else
932  {
933  aList.emplace_back( _( "Hole X / Y" ),
934  wxString::Format( "%s / %s",
935  MessageTextFromValue( units, m_drill.x ),
936  MessageTextFromValue( units, m_drill.y ) ) );
937  }
938  }
939 
940  wxString source;
941  int clearance = GetOwnClearance( GetLayer(), &source );
942 
943  aList.emplace_back( wxString::Format( _( "Min Clearance: %s" ),
944  MessageTextFromValue( units, clearance ) ),
945  wxString::Format( _( "(from %s)" ), source ) );
946 #if 0
947  // useful for debug only
948  aList.emplace_back( "UUID", m_Uuid.AsString() );
949 #endif
950 }
951 
952 
953 bool PAD::HitTest( const wxPoint& aPosition, int aAccuracy ) const
954 {
955  VECTOR2I delta = aPosition - GetPosition();
956  int boundingRadius = GetBoundingRadius() + aAccuracy;
957 
958  if( delta.SquaredEuclideanNorm() > SEG::Square( boundingRadius ) )
959  return false;
960 
961  return GetEffectivePolygon()->Contains( aPosition, -1, aAccuracy );
962 }
963 
964 
965 bool PAD::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
966 {
967  auto getArea = []( const SHAPE_POLY_SET& aPoly ) -> double
968  {
969  return aPoly.OutlineCount() ? aPoly.COutline( 0 ).Area() : 0;
970  };
971 
972  EDA_RECT arect = aRect;
973  arect.Normalize();
974  arect.Inflate( aAccuracy );
975 
976  EDA_RECT bbox = GetBoundingBox();
977 
978  if( !arect.Intersects( bbox ) )
979  return false;
980 
981  // This covers total containment for all test cases
982  if( arect.Contains( bbox ) )
983  return true;
984 
985  SHAPE_POLY_SET selRect;
986  selRect.NewOutline();
987  selRect.Append( arect.GetOrigin() );
988  selRect.Append( VECTOR2I( arect.GetRight(), arect.GetTop() ) );
989  selRect.Append( VECTOR2I( arect.GetRight(), arect.GetBottom() ) );
990  selRect.Append( VECTOR2I( arect.GetLeft(), arect.GetBottom() ) );
991 
993 
994  double padArea = getArea( *GetEffectivePolygon() );
995  double intersection = getArea( selRect );
996 
997  if( intersection > ( padArea * 0.99 ) )
998  return true;
999  else
1000  return !aContained && intersection > 0;
1001 }
1002 
1003 
1004 int PAD::Compare( const PAD* padref, const PAD* padcmp )
1005 {
1006  int diff;
1007 
1008  if( ( diff = static_cast<int>( padref->GetShape() ) - static_cast<int>( padcmp->GetShape() ) ) != 0 )
1009  return diff;
1010 
1011  if( ( diff = padref->GetDrillShape() - padcmp->GetDrillShape() ) != 0)
1012  return diff;
1013 
1014  if( ( diff = padref->m_drill.x - padcmp->m_drill.x ) != 0 )
1015  return diff;
1016 
1017  if( ( diff = padref->m_drill.y - padcmp->m_drill.y ) != 0 )
1018  return diff;
1019 
1020  if( ( diff = padref->m_size.x - padcmp->m_size.x ) != 0 )
1021  return diff;
1022 
1023  if( ( diff = padref->m_size.y - padcmp->m_size.y ) != 0 )
1024  return diff;
1025 
1026  if( ( diff = padref->m_offset.x - padcmp->m_offset.x ) != 0 )
1027  return diff;
1028 
1029  if( ( diff = padref->m_offset.y - padcmp->m_offset.y ) != 0 )
1030  return diff;
1031 
1032  if( ( diff = padref->m_deltaSize.x - padcmp->m_deltaSize.x ) != 0 )
1033  return diff;
1034 
1035  if( ( diff = padref->m_deltaSize.y - padcmp->m_deltaSize.y ) != 0 )
1036  return diff;
1037 
1038 // TODO: test custom shapes
1039 
1040  // Dick: specctra_export needs this
1041  // Lorenzo: gencad also needs it to implement padstacks!
1042 
1043 #if __cplusplus >= 201103L
1044  long long d = padref->m_layerMask.to_ullong() - padcmp->m_layerMask.to_ullong();
1045  if( d < 0 )
1046  return -1;
1047  else if( d > 0 )
1048  return 1;
1049 
1050  return 0;
1051 #else
1052  // these strings are not typically constructed, since we don't get here often.
1053  std::string s1 = padref->m_layerMask.to_string();
1054  std::string s2 = padcmp->m_layerMask.to_string();
1055  return s1.compare( s2 );
1056 #endif
1057 }
1058 
1059 
1060 void PAD::Rotate( const wxPoint& aRotCentre, double aAngle )
1061 {
1062  RotatePoint( &m_pos, aRotCentre, aAngle );
1063 
1064  m_orient = NormalizeAngle360Min( m_orient + aAngle );
1065 
1066  SetLocalCoord();
1067 
1068  SetDirty();
1069 }
1070 
1071 
1072 wxString PAD::ShowPadShape() const
1073 {
1074  switch( GetShape() )
1075  {
1076  case PAD_SHAPE::CIRCLE: return _( "Circle" );
1077  case PAD_SHAPE::OVAL: return _( "Oval" );
1078  case PAD_SHAPE::RECT: return _( "Rect" );
1079  case PAD_SHAPE::TRAPEZOID: return _( "Trap" );
1080  case PAD_SHAPE::ROUNDRECT: return _( "Roundrect" );
1081  case PAD_SHAPE::CHAMFERED_RECT: return _( "Chamferedrect" );
1082  case PAD_SHAPE::CUSTOM: return _( "CustomShape" );
1083  default: return wxT( "???" );
1084  }
1085 }
1086 
1087 
1088 wxString PAD::ShowPadAttr() const
1089 {
1090  switch( GetAttribute() )
1091  {
1092  case PAD_ATTRIB::PTH: return _( "PTH" );
1093  case PAD_ATTRIB::SMD: return _( "SMD" );
1094  case PAD_ATTRIB::CONN: return _( "Conn" );
1095  case PAD_ATTRIB::NPTH: return _( "NPTH" );
1096  default: return wxT( "???" );
1097  }
1098 }
1099 
1100 
1101 wxString PAD::GetSelectMenuText( EDA_UNITS aUnits ) const
1102 {
1103  if( GetName().IsEmpty() )
1104  {
1106  {
1107  return wxString::Format( _( "Pad of %s on %s" ),
1108  GetParent()->GetReference(),
1109  layerMaskDescribe() );
1110  }
1111  else
1112  {
1113  return wxString::Format( _( "Through hole pad of %s" ),
1114  GetParent()->GetReference() );
1115  }
1116  }
1117  else
1118  {
1120  {
1121  return wxString::Format( _( "Pad %s of %s on %s" ),
1122  GetName(),
1123  GetParent()->GetReference(),
1124  layerMaskDescribe() );
1125  }
1126  else
1127  {
1128  return wxString::Format( _( "Through hole pad %s of %s" ),
1129  GetName(),
1130  GetParent()->GetReference() );
1131  }
1132  }
1133 }
1134 
1135 
1137 {
1138  return BITMAPS::pad;
1139 }
1140 
1141 
1143 {
1144  return new PAD( *this );
1145 }
1146 
1147 
1148 void PAD::ViewGetLayers( int aLayers[], int& aCount ) const
1149 {
1150  aCount = 0;
1151 
1152  // These 2 types of pads contain a hole
1153  if( m_attribute == PAD_ATTRIB::PTH )
1154  {
1155  aLayers[aCount++] = LAYER_PAD_PLATEDHOLES;
1156  aLayers[aCount++] = LAYER_PAD_HOLEWALLS;
1157  }
1158 
1159  if( m_attribute == PAD_ATTRIB::NPTH )
1160  aLayers[aCount++] = LAYER_NON_PLATEDHOLES;
1161 
1162  if( IsOnLayer( F_Cu ) && IsOnLayer( B_Cu ) )
1163  {
1164  // Multi layer pad
1165  aLayers[aCount++] = LAYER_PADS_TH;
1166  aLayers[aCount++] = LAYER_PAD_NETNAMES;
1167  }
1168  else if( IsOnLayer( F_Cu ) )
1169  {
1170  aLayers[aCount++] = LAYER_PAD_FR;
1171 
1172  // Is this a PTH pad that has only front copper? If so, we need to also display the
1173  // net name on the PTH netname layer so that it isn't blocked by the drill hole.
1174  if( m_attribute == PAD_ATTRIB::PTH )
1175  aLayers[aCount++] = LAYER_PAD_NETNAMES;
1176  else
1177  aLayers[aCount++] = LAYER_PAD_FR_NETNAMES;
1178  }
1179  else if( IsOnLayer( B_Cu ) )
1180  {
1181  aLayers[aCount++] = LAYER_PAD_BK;
1182 
1183  // Is this a PTH pad that has only back copper? If so, we need to also display the
1184  // net name on the PTH netname layer so that it isn't blocked by the drill hole.
1185  if( m_attribute == PAD_ATTRIB::PTH )
1186  aLayers[aCount++] = LAYER_PAD_NETNAMES;
1187  else
1188  aLayers[aCount++] = LAYER_PAD_BK_NETNAMES;
1189  }
1190  else
1191  {
1192  // Internal layers only. (Not yet supported in GUI, but is being used by Python
1193  // footprint generators and will be needed anyway once pad stacks are supported.)
1194  for ( int internal = In1_Cu; internal < In30_Cu; ++internal )
1195  {
1196  if( IsOnLayer( (PCB_LAYER_ID) internal ) )
1197  aLayers[aCount++] = internal;
1198  }
1199  }
1200 
1201  // Check non-copper layers. This list should include all the layers that the
1202  // footprint editor allows a pad to be placed on.
1203  static const PCB_LAYER_ID layers_mech[] = { F_Mask, B_Mask, F_Paste, B_Paste,
1205 
1206  for( PCB_LAYER_ID each_layer : layers_mech )
1207  {
1208  if( IsOnLayer( each_layer ) )
1209  aLayers[aCount++] = each_layer;
1210  }
1211 
1212 #ifdef __WXDEBUG__
1213  if( aCount == 0 ) // Should not occur
1214  {
1215  wxString msg;
1216  msg.Printf( wxT( "footprint %s, pad %s: could not find valid layer for pad" ),
1217  GetParent() ? GetParent()->GetReference() : "<null>",
1218  GetName().IsEmpty() ? "(unnamed)" : GetName() );
1219  wxLogWarning( msg );
1220  }
1221 #endif
1222 }
1223 
1224 
1225 double PAD::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const
1226 {
1227  constexpr double HIDE = std::numeric_limits<double>::max();
1228 
1229  PCB_PAINTER* painter = static_cast<PCB_PAINTER*>( aView->GetPainter() );
1230  PCB_RENDER_SETTINGS* renderSettings = painter->GetSettings();
1231  BOARD* board = GetBoard();
1232  LSET visible = LSET::AllLayersMask();
1233 
1234  // Meta control for hiding all pads
1235  if( !aView->IsLayerVisible( LAYER_PADS ) )
1236  return HIDE;
1237 
1238  // Handle board visibility (unless printing)
1239  if( board && !aView->GetPrintMode() )
1240  visible = board->GetVisibleLayers() & board->GetEnabledLayers();
1241 
1242  // Handle Render tab switches
1244  && !aView->IsLayerVisible( LAYER_PADS_TH ) )
1245  {
1246  return HIDE;
1247  }
1248 
1249  if( !IsFlipped() && !aView->IsLayerVisible( LAYER_MOD_FR ) )
1250  return HIDE;
1251 
1252  if( IsFlipped() && !aView->IsLayerVisible( LAYER_MOD_BK ) )
1253  return HIDE;
1254 
1255  if( IsFrontLayer( (PCB_LAYER_ID) aLayer ) && !aView->IsLayerVisible( LAYER_PAD_FR ) )
1256  return HIDE;
1257 
1258  if( IsBackLayer( (PCB_LAYER_ID) aLayer ) && !aView->IsLayerVisible( LAYER_PAD_BK ) )
1259  return HIDE;
1260 
1261  if( aLayer == LAYER_PADS_TH )
1262  {
1263  if( !FlashLayer( visible ) )
1264  return HIDE;
1265  }
1266  else if( IsHoleLayer( aLayer ) )
1267  {
1268  if( !( visible & LSET::PhysicalLayersMask() ).any() )
1269  return HIDE;
1270  }
1271  else if( IsNetnameLayer( aLayer ) )
1272  {
1273  if( renderSettings->GetHighContrast() )
1274  {
1275  // Hide netnames unless pad is flashed to a high-contrast layer
1276  if( !FlashLayer( renderSettings->GetPrimaryHighContrastLayer() ) )
1277  return HIDE;
1278  }
1279  else
1280  {
1281  // Hide netnames unless pad is flashed to a visible layer
1282  if( !FlashLayer( visible ) )
1283  return HIDE;
1284  }
1285 
1286  // Netnames will be shown only if zoom is appropriate
1287  int divisor = std::min( GetBoundingBox().GetWidth(), GetBoundingBox().GetHeight() );
1288 
1289  // Pad sizes can be zero briefly when someone is typing a number like "0.5"
1290  // in the pad properties dialog
1291  if( divisor == 0 )
1292  return HIDE;
1293 
1294  return ( double ) Millimeter2iu( 5 ) / divisor;
1295  }
1296 
1297  if( aLayer == LAYER_PADS_TH
1298  && GetShape() != PAD_SHAPE::CUSTOM
1299  && GetSizeX() <= GetDrillSizeX()
1300  && GetSizeY() <= GetDrillSizeY() )
1301  {
1302  // Don't tweak the drawing code with a degenerate pad
1303  return HIDE;
1304  }
1305 
1306  // Passed all tests; show.
1307  return 0.0;
1308 }
1309 
1310 
1311 const BOX2I PAD::ViewBBox() const
1312 {
1313  // Bounding box includes soldermask too. Remember mask and/or paste
1314  // margins can be < 0
1315  int solderMaskMargin = std::max( GetSolderMaskMargin(), 0 );
1316  VECTOR2I solderPasteMargin = VECTOR2D( GetSolderPasteMargin() );
1317  EDA_RECT bbox = GetBoundingBox();
1318 
1319  // get the biggest possible clearance
1320  int clearance = 0;
1321 
1322  for( PCB_LAYER_ID layer : GetLayerSet().Seq() )
1323  clearance = std::max( clearance, GetOwnClearance( layer ) );
1324 
1325  // Look for the biggest possible bounding box
1326  int xMargin = std::max( solderMaskMargin, solderPasteMargin.x ) + clearance;
1327  int yMargin = std::max( solderMaskMargin, solderPasteMargin.y ) + clearance;
1328 
1329  return BOX2I( VECTOR2I( bbox.GetOrigin() ) - VECTOR2I( xMargin, yMargin ),
1330  VECTOR2I( bbox.GetSize() ) + VECTOR2I( 2 * xMargin, 2 * yMargin ) );
1331 }
1332 
1333 
1335 {
1336  return dynamic_cast<FOOTPRINT*>( m_parent );
1337 }
1338 
1339 
1340 void PAD::ImportSettingsFrom( const PAD& aMasterPad )
1341 {
1342  SetShape( aMasterPad.GetShape() );
1343  SetLayerSet( aMasterPad.GetLayerSet() );
1344  SetAttribute( aMasterPad.GetAttribute() );
1345  SetProperty( aMasterPad.GetProperty() );
1346 
1347  // I am not sure the m_LengthPadToDie must be imported, because this is
1348  // a parameter really specific to a given pad (JPC).
1349  // So this is currently non imported
1350  #if 0
1351  SetPadToDieLength( aMasterPad.GetPadToDieLength() );
1352  #endif
1353 
1354  // The pad orientation, for historical reasons is the
1355  // pad rotation + parent rotation.
1356  // So we have to manage this parent rotation
1357  double pad_rot = aMasterPad.GetOrientation();
1358 
1359  if( aMasterPad.GetParent() )
1360  pad_rot -= aMasterPad.GetParent()->GetOrientation();
1361 
1362  if( GetParent() )
1363  pad_rot += GetParent()->GetOrientation();
1364 
1365  SetOrientation( pad_rot );
1366 
1367  SetSize( aMasterPad.GetSize() );
1368  SetDelta( wxSize( 0, 0 ) );
1369  SetOffset( aMasterPad.GetOffset() );
1370  SetDrillSize( aMasterPad.GetDrillSize() );
1371  SetDrillShape( aMasterPad.GetDrillShape() );
1373  SetChamferRectRatio( aMasterPad.GetChamferRectRatio() );
1374  SetChamferPositions( aMasterPad.GetChamferPositions() );
1375 
1376  switch( aMasterPad.GetShape() )
1377  {
1378  case PAD_SHAPE::TRAPEZOID:
1379  SetDelta( aMasterPad.GetDelta() );
1380  break;
1381 
1382  case PAD_SHAPE::CIRCLE:
1383  // ensure size.y == size.x
1384  SetSize( wxSize( GetSize().x, GetSize().x ) );
1385  break;
1386 
1387  default:
1388  ;
1389  }
1390 
1391  switch( aMasterPad.GetAttribute() )
1392  {
1393  case PAD_ATTRIB::SMD:
1394  case PAD_ATTRIB::CONN:
1395  // These pads do not have hole (they are expected to be only on one
1396  // external copper layer)
1397  SetDrillSize( wxSize( 0, 0 ) );
1398  break;
1399 
1400  default:
1401  ;
1402  }
1403 
1404  // copy also local settings:
1405  SetLocalClearance( aMasterPad.GetLocalClearance() );
1409 
1412  SetThermalGap( aMasterPad.GetThermalGap() );
1413 
1415 
1416  // Add or remove custom pad shapes:
1417  ReplacePrimitives( aMasterPad.GetPrimitives() );
1418  SetAnchorPadShape( aMasterPad.GetAnchorPadShape() );
1419 
1420  SetDirty();
1421 }
1422 
1423 
1424 void PAD::SwapData( BOARD_ITEM* aImage )
1425 {
1426  assert( aImage->Type() == PCB_PAD_T );
1427 
1428  std::swap( *((FOOTPRINT*) this), *((FOOTPRINT*) aImage) );
1429 }
1430 
1431 
1432 static struct PAD_DESC
1433 {
1435  {
1437  .Map( PAD_ATTRIB::PTH, _HKI( "Through-hole" ) )
1438  .Map( PAD_ATTRIB::SMD, _HKI( "SMD" ) )
1439  .Map( PAD_ATTRIB::CONN, _HKI( "Edge connector" ) )
1440  .Map( PAD_ATTRIB::NPTH, _HKI( "NPTH, mechanical" ) );
1441 
1443  .Map( PAD_SHAPE::CIRCLE, _HKI( "Circle" ) )
1444  .Map( PAD_SHAPE::RECT, _HKI( "Rectangle" ) )
1445  .Map( PAD_SHAPE::OVAL, _HKI( "Oval" ) )
1446  .Map( PAD_SHAPE::TRAPEZOID, _HKI( "Trapezoid" ) )
1447  .Map( PAD_SHAPE::ROUNDRECT, _HKI( "Rounded rectangle" ) )
1448  .Map( PAD_SHAPE::CHAMFERED_RECT, _HKI( "Chamfered rectangle" ) )
1449  .Map( PAD_SHAPE::CUSTOM, _HKI( "Custom" ) );
1450 
1452  .Map( PAD_PROP::NONE, _HKI( "None" ) )
1453  .Map( PAD_PROP::BGA, _HKI( "BGA pad" ) )
1454  .Map( PAD_PROP::FIDUCIAL_GLBL, _HKI( "Fiducial, global to board" ) )
1455  .Map( PAD_PROP::FIDUCIAL_LOCAL, _HKI( "Fiducial, local to footprint" ) )
1456  .Map( PAD_PROP::TESTPOINT, _HKI( "Test point pad" ) )
1457  .Map( PAD_PROP::HEATSINK, _HKI( "Heatsink pad" ) )
1458  .Map( PAD_PROP::CASTELLATED, _HKI( "Castellated pad" ) );
1459 
1461  REGISTER_TYPE( PAD );
1463 
1464  auto padType = new PROPERTY_ENUM<PAD, PAD_ATTRIB>( _HKI( "Pad Type" ),
1466  propMgr.AddProperty( padType );
1467 
1468  auto shape = new PROPERTY_ENUM<PAD, PAD_SHAPE>( _HKI( "Shape" ),
1470  propMgr.AddProperty( shape );
1471 
1472  propMgr.AddProperty( new PROPERTY<PAD, wxString>( _HKI( "Pad Number" ),
1473  &PAD::SetName, &PAD::GetName ) );
1474  propMgr.AddProperty( new PROPERTY<PAD, wxString>( _HKI( "Pin Name" ),
1476  propMgr.AddProperty( new PROPERTY<PAD, wxString>( _HKI( "Pin Type" ),
1478  propMgr.AddProperty( new PROPERTY<PAD, double>( _HKI( "Orientation" ),
1481  propMgr.AddProperty( new PROPERTY<PAD, int>( _HKI( "Size X" ),
1484  propMgr.AddProperty( new PROPERTY<PAD, int>( _HKI( "Size Y" ),
1487  propMgr.AddProperty( new PROPERTY<PAD, int>( _HKI( "Hole Size X" ),
1490  propMgr.AddProperty( new PROPERTY<PAD, int>( _HKI( "Hole Size Y" ),
1493  propMgr.AddProperty( new PROPERTY<PAD, int>( _HKI( "Pad To Die Length" ),
1496  propMgr.AddProperty( new PROPERTY<PAD, int>( _HKI( "Local Soldermask Margin" ),
1499  propMgr.AddProperty( new PROPERTY<PAD, int>( _HKI( "Local Solderpaste Margin" ),
1502  propMgr.AddProperty( new PROPERTY<PAD, double>( _HKI( "Local Solderpaste Margin Ratio" ),
1504  propMgr.AddProperty( new PROPERTY<PAD, int>( _HKI( "Thermal Relief Spoke Width" ),
1507  propMgr.AddProperty( new PROPERTY<PAD, int>( _HKI( "Thermal Relief" ),
1510  propMgr.AddProperty( new PROPERTY_ENUM<PAD, PAD_PROP>( _HKI( "Fabrication Property" ),
1512 
1513  auto roundRadiusRatio = new PROPERTY<PAD, double>( _HKI( "Round Radius Ratio" ),
1515  roundRadiusRatio->SetAvailableFunc(
1516  [=]( INSPECTABLE* aItem ) -> bool
1517  {
1518  return aItem->Get( shape ) == static_cast<int>( PAD_SHAPE::ROUNDRECT );
1519  } );
1520  propMgr.AddProperty( roundRadiusRatio );
1521 
1522  propMgr.AddProperty( new PROPERTY<PAD, int>( _HKI( "Local Clearance" ),
1525  propMgr.AddProperty( new PROPERTY<PAD, wxString>( _HKI( "Parent" ),
1526  NO_SETTER( PAD, wxString ), &PAD::GetParentAsString ) );
1527 
1528  // TODO delta, dirill shape offset, layerset, zone connection
1529  }
1530 } _PAD_DESC;
1531 
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:54
BITMAPS GetMenuImage() const override
Return a pointer to an image to be used in menus.
Definition: pad.cpp:1136
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:646
EDA_ITEM * m_parent
Linked list: Link (parent struct)
Definition: eda_item.h:529
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:90
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:390
SHAPE_SIMPLE.
Definition: shape_simple.h:43
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:161
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:559
const int GetDrillSizeX() const
Definition: pad.h:244
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:1148
multilayer pads, usually with holes
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:82
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:245
int GetTop() const
Definition: eda_rect.h:118
PAD_PROP GetProperty() const
Definition: pad.h:374
wxSize m_drill
Definition: pad.h:714
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: pad.cpp:671
static int Compare(const PAD *padref, const PAD *padcmp)
Compare two pads and return 0 if they are equal.
Definition: pad.cpp:1004
virtual NETCLASS * GetNetClass() const
Return the NETCLASS for this item.
int GetLeft() const
Definition: eda_rect.h:117
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:953
void SetOrientationDegrees(double aOrientation)
Set orientation in degrees.
Definition: pad.h:343
Smd pad, appears on the solder paste layer (default)
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: pad.cpp:138
void SetSubRatsnest(int aSubRatsnest)
Definition: pad.h:548
static ENUM_MAP< T > & Instance()
Definition: property.h:510
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:567
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...
const SHAPE_SEGMENT * GetEffectiveHoleShape() const
Return a SHAPE object representing the pad's hole.
Definition: pad.cpp:285
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
wxString AsString() const
Definition: kiid.cpp:218
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.h:593
class PAD, a pad in a footprint
Definition: typeinfo.h:89
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:681
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: pad.cpp:831
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
wxPoint m_pos0
Definition: pad.h:744
The base class for create windows for drawing purpose.
VECTOR2< int > VECTOR2I
Definition: vector2d.h:623
a test point pad
#define NO_SETTER(owner, type)
Definition: property.h:621
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:696
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:499
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
wxString ShowPadShape() const
Definition: pad.cpp:1072
#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:182
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:207
class 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)
Function Append()
Plated through hole pad.
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
int m_localSolderMaskMargin
Definition: pad.h:772
void SetPadToDieLength(int aLength)
Definition: pad.h:383
void SetProperty(PAD_PROP aProperty)
Definition: pad.cpp:570
void ImportSettingsFrom(const PAD &aMasterPad)
Import the pad settings from aMasterPad.
Definition: pad.cpp:1340
std::shared_ptr< SHAPE_SEGMENT > m_effectiveHoleShape
Definition: pad.h:697
show footprints on front
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:812
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:1225
const VECTOR2I & CPoint(int aIndex) const
Function Point()
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:249
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:850
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.
Definition: pad.cpp:1424
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: pad.cpp:656
like PAD_PTH, but not plated
double m_chamferScale
Definition: pad.h:721
PCB_LAYER_ID
A quick note on layer IDs:
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:202
LSET is a set of PCB_LAYER_IDs.
int m_thermalGap
Definition: pad.h:779
int GetThermalSpokeWidth() const
Definition: pad.h:491
#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:349
VECTOR2< double > VECTOR2D
Definition: vector2d.h:622
void SetPos0(const wxPoint &aPos)
Definition: pad.h:225
void SetLocalCoord()
< Set relative coordinates.
Definition: pad.cpp:544
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:587
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: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: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:791
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
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:1311
std::shared_ptr< CONNECTIVITY_DATA > GetConnectivity() const
Return a list of missing connections between components/tracks.
Definition: board.h:416
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: pad.cpp:147
const EDA_RECT GetBoundingBox() const override
The bounding box is cached, so this will be efficient most of the time.
Definition: pad.cpp:517
double m_orient
Definition: pad.h:751
int GetLocalClearance() const
Definition: footprint.h:205
const wxString & GetPinType() const
Definition: pad.h:145
PAD_SHAPE GetShape() const
Definition: pad.h:169
const wxString & GetReference() const
Definition: footprint.h:426
a fiducial (usually a smd) local to the parent footprint
PAD & operator=(const PAD &aOther)
Definition: 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: pad.cpp:276
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:526
ZONE_CONNECTION m_zoneConnection
Definition: pad.h:777
void SetPinFunction(const wxString &aName)
Set the pad function (pin name in schematic)
Definition: pad.h:138
void BuildEffectivePolygon() const
Definition: pad.cpp:475
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 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,...
Class that other classes need to inherit from, in order to be inspectable.
Definition: inspectable.h:35
int NewOutline()
Creates a new hole in a given outline.
void SetRoundRectRadiusRatio(double aRadiusScale)
Has meaning only for rounded rectangle pads.
Definition: pad.cpp:251
PAD_ATTRIB
The set of pad shapes, used with PAD::{Set,Get}Attribute().
Definition: pad_shapes.h:79
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:177
int GetLocalClearance(wxString *aSource) const override
Return any local clearances set in the "classic" (ie: pre-rule) system.
Definition: pad.cpp:685
int GetPrintMode() const
Get the current print mode.
Definition: view.h:690
void SetDrillShape(PAD_DRILL_SHAPE_T aShape)
Definition: pad.h:353
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:303
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:242
const KIID m_Uuid
Definition: eda_item.h:525
const Vec & GetPosition() const
Definition: box2.h:194
Some functions to handle hotkeys in KiCad.
int GetRoundRectCornerRadius() const
Definition: pad.cpp:236
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:715
int GetSolderMaskMargin() const
Definition: pad.cpp:696
FOOTPRINT * GetParent() const
Definition: pad.cpp:1334
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:541
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:735
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: pad.cpp:294
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: pad.cpp:175
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:1434
CUST_PAD_SHAPE_IN_ZONE GetCustomShapeInZoneOpt() const
Definition: pad.h:187
smd pads, front layer
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:741
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:177
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:246
#define _(s)
Definition: 3d_actions.cpp:33
SHAPE_LINE_CHAIN.
PAD_ATTRIB GetAttribute() const
Definition: pad.h:371
double GetOrientationDegrees() const
Definition: pad.h:350
wxString UnescapeString(const wxString &aSource)
Definition: string.cpp:151
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: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:1142
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
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:267
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:150
coord_type GetHeight() const
Definition: box2.h:198
wxString m_name
Definition: pad.h:677
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...
Definition: pad.cpp:1101
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
void SetShape(PAD_SHAPE aShape)
Set the new shape of this pad.
Definition: pad.h:160
int GetChamferPositions() const
Definition: pad.h:542
wxString GetParentAsString() const
Definition: pad.h:110
int m_lengthPadToDie
Definition: pad.h:753
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 VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:96
wxString ShowPadAttr() const
Definition: pad.cpp:1088
ZONE_CONNECTION GetZoneConnection() const
Definition: footprint.h:223
static LSET UnplatedHoleMask()
layer set for a mechanical unplated through hole pad
Definition: pad.cpp:168
CUST_PAD_SHAPE_IN_ZONE m_customShapeClearanceArea
Definition: pad.h:709
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: pad.cpp:259
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:154
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:173
PAD(FOOTPRINT *parent)
Definition: pad.cpp:53
const wxString & GetPinFunction() const
Definition: pad.h:139
bool m_polyDirty
Definition: pad.h:699
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:301
PAD_SHAPE GetAnchorPadShape() const
Definition: pad.h:182
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: pad.cpp:578
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
PAD_PROP m_property
Definition: pad.h:749
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:163
void SetAnchorPadShape(PAD_SHAPE aShape)
Set the shape of the anchor pad for custom shaped pads.
Definition: pad.h:208
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.
Definition: pad.cpp:1060
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...