KiCad PCB EDA Suite
class_pad.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2018 Jean-Pierre Charras, jp.charras at wanadoo.fr
5  * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
6  * Copyright (C) 1992-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 
31 #include <fctsys.h>
32 #include <trigo.h>
33 #include <macros.h>
34 #include <msgpanel.h>
35 #include <base_units.h>
36 #include <bitmaps.h>
37 #include <math/util.h> // for KiROUND
38 #include <eda_draw_frame.h>
39 #include <geometry/shape_circle.h>
40 #include <geometry/shape_segment.h>
41 #include <geometry/shape_simple.h>
42 #include <geometry/shape_rect.h>
44 #include <pcbnew.h>
45 #include <view/view.h>
46 #include <class_board.h>
47 #include <class_module.h>
48 #include <class_drawsegment.h>
51 #include <convert_to_biu.h>
53 
54 #include <memory>
55 
56 D_PAD::D_PAD( MODULE* parent ) :
58 {
59  m_size.x = m_size.y = Mils2iu( 60 ); // Default pad size 60 mils.
60  m_drill.x = m_drill.y = Mils2iu( 30 ); // Default drill size 30 mils.
61  m_orient = 0; // Pad rotation in 1/10 degrees.
62  m_lengthPadToDie = 0;
63 
64  if( m_Parent && m_Parent->Type() == PCB_MODULE_T )
65  {
67  }
68 
69  SetShape( PAD_SHAPE_CIRCLE ); // Default pad shape is PAD_CIRCLE.
70  SetAnchorPadShape( PAD_SHAPE_CIRCLE ); // Default shape for custom shaped pads
71  // is PAD_CIRCLE.
72  SetDrillShape( PAD_DRILL_SHAPE_CIRCLE ); // Default pad drill shape is a circle.
73  m_attribute = PAD_ATTRIB_STANDARD; // Default pad type is NORMAL (thru hole)
74  SetProperty( PAD_PROP_NONE ); // no special fabrication property
75  m_localClearance = 0;
79  // Parameters for round rect only:
80  m_roundedCornerScale = 0.25; // from IPC-7351C standard
81  // Parameters for chamfered rect only:
82  m_chamferScale = 0.2; // Size of chamfer: ratio of smallest of X,Y size
83  m_chamferPositions = RECT_NO_CHAMFER; // No chamfered corner
84 
85  m_zoneConnection = ZONE_CONNECTION::INHERITED; // Use parent setting by default
86  m_thermalWidth = 0; // Use parent setting by default
87  m_thermalGap = 0; // Use parent setting by default
88 
90 
91  // Set layers mask to default for a standard thru hole pad.
93 
94  SetSubRatsnest( 0 ); // used in ratsnest calculations
95 
96  m_shapesDirty = true;
99  m_keepTopBottomLayer = true;
100 }
101 
102 
103 D_PAD::D_PAD( const D_PAD& aOther ) :
104  BOARD_CONNECTED_ITEM( aOther.GetParent(), PCB_PAD_T )
105 {
107 
108  ImportSettingsFrom( aOther );
110  SetPosition( aOther.GetPosition() );
111  SetPos0( aOther.GetPos0() );
112  SetName( aOther.GetName() );
113  SetPinFunction( aOther.GetPinFunction() );
114  SetSubRatsnest( aOther.GetSubRatsnest() );
118  const_cast<KIID&>( m_Uuid ) = aOther.m_Uuid;
119 }
120 
121 
122 D_PAD& D_PAD::operator=( const D_PAD &aOther )
123 {
125 
126  ImportSettingsFrom( aOther );
128  SetPosition( aOther.GetPosition() );
129  SetPos0( aOther.GetPos0() );
130  SetName( aOther.GetName() );
131  SetPinFunction( aOther.GetPinFunction() );
132  SetSubRatsnest( aOther.GetSubRatsnest() );
136 
137  return *this;
138 }
139 
140 
142 {
143  static LSET saved = LSET::AllCuMask() | LSET( 2, F_Mask, B_Mask );
144  return saved;
145 }
146 
147 
149 {
150  static LSET saved( 3, F_Cu, F_Paste, F_Mask );
151  return saved;
152 }
153 
154 
156 {
157  static LSET saved( 2, F_Cu, F_Mask );
158  return saved;
159 }
160 
161 
163 {
164  static LSET saved = LSET( 4, F_Cu, B_Cu, F_Mask, B_Mask );
165  return saved;
166 }
167 
168 
170 {
171  static LSET saved( 1, F_Paste );
172  return saved;
173 }
174 
175 
176 bool D_PAD::IsFlipped() const
177 {
178  if( GetParent() && GetParent()->GetLayer() == B_Cu )
179  return true;
180  return false;
181 }
182 
183 
184 bool D_PAD::IsPadOnLayer( LSET aLayers ) const
185 {
186  for( auto layer : aLayers.Seq() )
187  {
188  if( IsPadOnLayer( layer ) )
189  return true;
190  }
191 
192  return false;
193 }
194 
195 
196 bool D_PAD::IsPadOnLayer( int aLayer ) const
197 {
198  BOARD* board = GetBoard();
199 
200  if( !board )
201  return false;
202 
205  return IsOnLayer( static_cast<PCB_LAYER_ID>( aLayer ) );
206 
208  if( GetProperty() == PAD_PROP_HEATSINK )
209  return IsOnLayer( static_cast<PCB_LAYER_ID>( aLayer ) );
210 
212  return IsOnLayer( static_cast<PCB_LAYER_ID>( aLayer ) );
213 
216  if( aLayer == F_Cu || aLayer == B_Cu )
217  return IsOnLayer( static_cast<PCB_LAYER_ID>( aLayer ) );
218 
219  return board->GetConnectivity()->IsConnectedOnLayer( this, static_cast<int>( aLayer ),
221 }
222 
223 
225 {
226  return KiROUND( std::min( m_size.x, m_size.y ) * m_roundedCornerScale );
227 }
228 
229 
230 void D_PAD::SetRoundRectCornerRadius( double aRadius )
231 {
232  int min_r = std::min( m_size.x, m_size.y );
233 
234  if( min_r > 0 )
235  SetRoundRectRadiusRatio( aRadius / min_r );
236 }
237 
238 
239 void D_PAD::SetRoundRectRadiusRatio( double aRadiusScale )
240 {
241  m_roundedCornerScale = std::max( 0.0, std::min( aRadiusScale, 0.5 ) );
242 
243  m_shapesDirty = true;
244 }
245 
246 
247 void D_PAD::SetChamferRectRatio( double aChamferScale )
248 {
249  m_chamferScale = std::max( 0.0, std::min( aChamferScale, 0.5 ) );
250 
251  m_shapesDirty = true;
252 }
253 
254 
255 const std::shared_ptr<SHAPE_POLY_SET>& D_PAD::GetEffectivePolygon( PCB_LAYER_ID aLayer ) const
256 {
257  if( m_shapesDirty )
258  BuildEffectiveShapes( aLayer );
259 
260  return m_effectivePolygon;
261 }
262 
263 
264 std::shared_ptr<SHAPE> D_PAD::GetEffectiveShape( PCB_LAYER_ID aLayer ) const
265 {
266  if( m_shapesDirty )
267  BuildEffectiveShapes( aLayer );
268 
269  return m_effectiveShape;
270 }
271 
272 
274 {
275  if( m_shapesDirty )
277 
278  return m_effectiveHoleShape.get();
279 }
280 
281 
283 {
284  if( m_shapesDirty )
286 
288 }
289 
290 
292 {
293  m_effectiveShape = std::make_shared<SHAPE_COMPOUND>();
294  m_effectiveHoleShape = nullptr;
295 
296  auto add = [this]( SHAPE* aShape )
297  {
298  m_effectiveShape->AddShape( aShape );
299  };
300 
301  wxPoint shapePos = ShapePos(); // Fetch only once; rotation involves trig
302  PAD_SHAPE_T effectiveShape = GetShape();
303 
304  if( GetShape() == PAD_SHAPE_CUSTOM )
305  effectiveShape = GetAnchorPadShape();
306 
307  switch( effectiveShape )
308  {
309  case PAD_SHAPE_CIRCLE:
310  add( new SHAPE_CIRCLE( shapePos, m_size.x / 2 ) );
311  break;
312 
313  case PAD_SHAPE_OVAL:
314  if( m_size.x == m_size.y ) // the oval pad is in fact a circle
315  add( new SHAPE_CIRCLE( shapePos, m_size.x / 2 ) );
316  else
317  {
318  wxSize half_size = m_size / 2;
319  int half_width = std::min( half_size.x, half_size.y );
320  wxPoint half_len( half_size.x - half_width, half_size.y - half_width );
321  RotatePoint( &half_len, m_orient );
322  add( new SHAPE_SEGMENT( shapePos - half_len, shapePos + half_len, half_width * 2 ) );
323  }
324  break;
325 
326  case PAD_SHAPE_RECT:
327  if( m_orient == 0 || m_orient == 1800 )
328  {
329  add( new SHAPE_RECT( shapePos - m_size / 2, m_size.x, m_size.y ) );
330  break;
331  }
332  else if( m_orient == 900 || m_orient == -900 )
333  {
334  wxSize rot_size( m_size.y, m_size.x );
335  add( new SHAPE_RECT( shapePos - rot_size / 2, rot_size.x, rot_size.y ) );
336  break;
337  }
338 
339  // Not at a cartesian angle; fall through to general case
341 
342  case PAD_SHAPE_TRAPEZOID:
343  case PAD_SHAPE_ROUNDRECT:
344  {
345  int r = GetRoundRectCornerRadius();
346  wxPoint half_size( m_size.x / 2, m_size.y / 2 );
347  wxSize trap_delta( 0, 0 );
348 
349  if( effectiveShape == PAD_SHAPE_ROUNDRECT )
350  half_size -= wxPoint( r, r );
351  else if( effectiveShape == PAD_SHAPE_TRAPEZOID )
352  trap_delta = m_deltaSize / 2;
353 
354  SHAPE_LINE_CHAIN corners;
355 
356  corners.Append( -half_size.x - trap_delta.y, half_size.y + trap_delta.x );
357  corners.Append( half_size.x + trap_delta.y, half_size.y - trap_delta.x );
358  corners.Append( half_size.x - trap_delta.y, -half_size.y + trap_delta.x );
359  corners.Append( -half_size.x + trap_delta.y, -half_size.y - trap_delta.x );
360 
361  corners.Rotate( -DECIDEG2RAD( m_orient ) );
362  corners.Move( shapePos );
363 
364  add( new SHAPE_SIMPLE( corners ) );
365 
366  if( effectiveShape == PAD_SHAPE_ROUNDRECT )
367  {
368  add( new SHAPE_SEGMENT( corners.CPoint( 0 ), corners.CPoint( 1 ), r * 2 ) );
369  add( new SHAPE_SEGMENT( corners.CPoint( 1 ), corners.CPoint( 2 ), r * 2 ) );
370  add( new SHAPE_SEGMENT( corners.CPoint( 2 ), corners.CPoint( 3 ), r * 2 ) );
371  add( new SHAPE_SEGMENT( corners.CPoint( 3 ), corners.CPoint( 0 ), r * 2 ) );
372  }
373  }
374  break;
375 
377  {
378  SHAPE_POLY_SET outline;
379  auto board = GetBoard();
380  int maxError = ARC_HIGH_DEF;
381 
382  if( board )
383  maxError = board->GetDesignSettings().m_MaxError;
384 
387  GetChamferPositions(), maxError );
388 
389  add( new SHAPE_SIMPLE( outline.COutline( 0 ) ) );
390  }
391  break;
392 
393  default:
394  wxFAIL_MSG( "D_PAD::buildEffectiveShapes: Unsupported pad shape: "
395  + PAD_SHAPE_T_asString( effectiveShape ) );
396  break;
397  }
398 
399  if( GetShape() == PAD_SHAPE_CUSTOM )
400  {
401  for( const std::shared_ptr<DRAWSEGMENT>& primitive : m_editPrimitives )
402  {
403  for( SHAPE* shape : primitive->MakeEffectiveShapes() )
404  {
405  shape->Rotate( -DECIDEG2RAD( m_orient ) );
406  shape->Move( shapePos );
407  add( shape );
408  }
409  }
410  }
411 
412  // Polygon
413  //
414  m_effectivePolygon = std::make_shared<SHAPE_POLY_SET>();
416 
417  // Bounding box and radius
418  //
419  // PADSTACKS TODO: these will both need to cycle through all layers to get the largest
420  // values....
421  //
423 
424  for( int cnt = 0; cnt < m_effectivePolygon->OutlineCount(); ++cnt )
425  {
426  const SHAPE_LINE_CHAIN& poly = m_effectivePolygon->COutline( cnt );
427 
428  for( int ii = 0; ii < poly.PointCount(); ++ii )
429  {
430  int dist = KiROUND( ( poly.CPoint( ii ) - m_pos ).EuclideanNorm() );
432  }
433  }
434 
436 
437  BOX2I bbox = m_effectiveShape->BBox();
439  wxSize( bbox.GetWidth(), bbox.GetHeight() ) );
440 
441  // Hole shape
442  //
443  wxSize half_size = m_drill / 2;
444  int half_width = std::min( half_size.x, half_size.y );
445  wxPoint half_len( half_size.x - half_width, half_size.y - half_width );
446 
447  RotatePoint( &half_len, m_orient );
448 
449  m_effectiveHoleShape = std::make_shared<SHAPE_SEGMENT>( m_pos - half_len, m_pos + half_len,
450  half_width * 2 );
451 
452  // All done
453  //
454  m_shapesDirty = false;
455 }
456 
457 
459 {
460  if( m_shapesDirty )
462 
463  return m_effectiveBoundingBox;
464 }
465 
466 
468 {
469  MODULE* module = (MODULE*) m_Parent;
470 
471  m_pos = m_pos0;
472 
473  if( module == NULL )
474  return;
475 
476  double angle = module->GetOrientation();
477 
478  RotatePoint( &m_pos.x, &m_pos.y, angle );
479  m_pos += module->GetPosition();
480 
481  m_shapesDirty = true;
482 }
483 
484 
486 {
487  MODULE* module = (MODULE*) m_Parent;
488 
489  if( module == NULL )
490  {
491  m_pos0 = m_pos;
492  return;
493  }
494 
495  m_pos0 = m_pos - module->GetPosition();
496  RotatePoint( &m_pos0.x, &m_pos0.y, -module->GetOrientation() );
497 }
498 
499 
500 void D_PAD::SetAttribute( PAD_ATTR_T aAttribute )
501 {
502  m_attribute = aAttribute;
503 
504  if( aAttribute == PAD_ATTRIB_SMD )
505  m_drill = wxSize( 0, 0 );
506 
507  m_shapesDirty = true;
508 }
509 
510 
512 {
513  m_property = aProperty;
514 
515  m_shapesDirty = true;
516 }
517 
518 
519 void D_PAD::SetOrientation( double aAngle )
520 {
521  NORMALIZE_ANGLE_POS( aAngle );
522  m_orient = aAngle;
523 
524  m_shapesDirty = true;
525 }
526 
527 
528 void D_PAD::Flip( const wxPoint& aCentre, bool aFlipLeftRight )
529 {
530  if( aFlipLeftRight )
531  {
532  MIRROR( m_pos.x, aCentre.x );
533  MIRROR( m_pos0.x, 0 );
534  MIRROR( m_offset.x, 0 );
535  MIRROR( m_deltaSize.x, 0 );
536  }
537  else
538  {
539  MIRROR( m_pos.y, aCentre.y );
540  MIRROR( m_pos0.y, 0 );
541  MIRROR( m_offset.y, 0 );
542  MIRROR( m_deltaSize.y, 0 );
543  }
544 
546 
547  auto mirrorBitFlags = []( int& aBitfield, int a, int b )
548  {
549  bool temp = aBitfield & a;
550 
551  if( aBitfield & b )
552  aBitfield |= a;
553  else
554  aBitfield &= ~a;
555 
556  if( temp )
557  aBitfield |= b;
558  else
559  aBitfield &= ~b;
560  };
561 
562  if( aFlipLeftRight )
563  {
566  }
567  else
568  {
571  }
572 
573  // flip pads layers
574  // PADS items are currently on all copper layers, or
575  // currently, only on Front or Back layers.
576  // So the copper layers count is not taken in account
578 
579  // Flip the basic shapes, in custom pads
580  FlipPrimitives( aFlipLeftRight );
581 
582  m_shapesDirty = true;
583 }
584 
585 
586 // Flip (mirror) the basic shapes (primitives), in custom pads
587 void D_PAD::FlipPrimitives( bool aFlipLeftRight )
588 {
589  for( std::shared_ptr<DRAWSEGMENT>& primitive : m_editPrimitives )
590  primitive->Flip( wxPoint( 0, 0 ), aFlipLeftRight );
591 
592  m_shapesDirty = true;
593 }
594 
595 
596 // Returns the position of the pad.
598 {
599  if( m_offset.x == 0 && m_offset.y == 0 )
600  return m_pos;
601 
602  wxPoint loc_offset = m_offset;
603 
604  RotatePoint( &loc_offset, m_orient );
605 
606  wxPoint shape_pos = m_pos + loc_offset;
607 
608  return shape_pos;
609 }
610 
611 
612 int D_PAD::GetLocalClearanceOverrides( wxString* aSource ) const
613 {
614  // A pad can have specific clearance that overrides its NETCLASS clearance value
615  if( GetLocalClearance() )
616  return GetLocalClearance( aSource );
617 
618  // A footprint can have a specific clearance value
619  if( GetParent() && GetParent()->GetLocalClearance() )
620  return GetParent()->GetLocalClearance( aSource );
621 
622  return 0;
623 }
624 
625 
626 int D_PAD::GetLocalClearance( wxString* aSource ) const
627 {
628  if( aSource )
629  *aSource = wxString::Format( _( "pad %s" ), GetName() );
630 
631  return m_localClearance;
632 }
633 
634 
635 // Mask margins handling:
636 
638 {
639  // The pad inherits the margin only to calculate a default shape,
640  // therefore only if it is also a copper layer
641  // Pads defined only on mask layers (and perhaps on other tech layers) use the shape
642  // defined by the pad settings only
643  bool isOnCopperLayer = ( m_layerMask & LSET::AllCuMask() ).any();
644 
645  if( !isOnCopperLayer )
646  return 0;
647 
648  int margin = m_localSolderMaskMargin;
649 
650  MODULE* module = GetParent();
651 
652  if( module )
653  {
654  if( margin == 0 )
655  {
656  if( module->GetLocalSolderMaskMargin() )
657  margin = module->GetLocalSolderMaskMargin();
658  }
659 
660  if( margin == 0 )
661  {
662  BOARD* brd = GetBoard();
663 
664  if( brd )
665  margin = brd->GetDesignSettings().m_SolderMaskMargin;
666  }
667  }
668 
669  // ensure mask have a size always >= 0
670  if( margin < 0 )
671  {
672  int minsize = -std::min( m_size.x, m_size.y ) / 2;
673 
674  if( margin < minsize )
675  margin = minsize;
676  }
677 
678  return margin;
679 }
680 
681 
683 {
684  // The pad inherits the margin only to calculate a default shape,
685  // therefore only if it is also a copper layer.
686  // Pads defined only on mask layers (and perhaps on other tech layers) use the shape
687  // defined by the pad settings only
688  bool isOnCopperLayer = ( m_layerMask & LSET::AllCuMask() ).any();
689 
690  if( !isOnCopperLayer )
691  return wxSize( 0, 0 );
692 
693  int margin = m_localSolderPasteMargin;
694  double mratio = m_localSolderPasteMarginRatio;
695 
696  MODULE* module = GetParent();
697 
698  if( module )
699  {
700  if( margin == 0 )
701  margin = module->GetLocalSolderPasteMargin();
702 
703  auto brd = GetBoard();
704 
705  if( margin == 0 && brd )
706  {
707  margin = brd->GetDesignSettings().m_SolderPasteMargin;
708  }
709 
710  if( mratio == 0.0 )
711  mratio = module->GetLocalSolderPasteMarginRatio();
712 
713  if( mratio == 0.0 && brd )
714  {
715  mratio = brd->GetDesignSettings().m_SolderPasteMarginRatio;
716  }
717  }
718 
719  wxSize pad_margin;
720  pad_margin.x = margin + KiROUND( m_size.x * mratio );
721  pad_margin.y = margin + KiROUND( m_size.y * mratio );
722 
723  // ensure mask have a size always >= 0
724  if( pad_margin.x < -m_size.x / 2 )
725  pad_margin.x = -m_size.x / 2;
726 
727  if( pad_margin.y < -m_size.y / 2 )
728  pad_margin.y = -m_size.y / 2;
729 
730  return pad_margin;
731 }
732 
733 
735 {
736  MODULE* module = GetParent();
737 
739  {
740  if( aSource )
741  *aSource = _( "parent footprint" );
742 
743  return module->GetZoneConnection();
744  }
745  else
746  {
747  if( aSource )
748  *aSource = _( "pad" );
749 
750  return m_zoneConnection;
751  }
752 }
753 
754 
755 int D_PAD::GetEffectiveThermalSpokeWidth( wxString* aSource ) const
756 {
757  MODULE* module = GetParent();
758 
759  if( m_thermalWidth == 0 && module )
760  {
761  if( aSource )
762  *aSource = _( "parent footprint" );
763 
764  return module->GetThermalWidth();
765  }
766 
767  if( aSource )
768  *aSource = _( "pad" );
769 
770  return m_thermalWidth;
771 }
772 
773 
774 int D_PAD::GetEffectiveThermalGap( wxString* aSource ) const
775 {
776  MODULE* module = GetParent();
777 
778  if( m_thermalGap == 0 && module )
779  {
780  if( aSource )
781  *aSource = _( "parent footprint" );
782 
783  return module->GetThermalGap();
784  }
785 
786  if( aSource )
787  *aSource = _( "pad" );
788 
789  return m_thermalGap;
790 }
791 
792 
793 void D_PAD::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
794 {
795  EDA_UNITS units = aFrame->GetUserUnits();
796  wxString msg, msg2;
797  BOARD* board = GetBoard();
799  MODULE* module = (MODULE*) m_Parent;
800 
801  if( module )
802  aList.emplace_back( _( "Footprint" ), module->GetReference(), DARKCYAN );
803 
804  aList.emplace_back( _( "Pad" ), m_name, BROWN );
805 
806  if( !GetPinFunction().IsEmpty() )
807  aList.emplace_back( _( "Pin Name" ), GetPinFunction(), BROWN );
808 
809  aList.emplace_back( _( "Net" ), UnescapeString( GetNetname() ), DARKCYAN );
810 
811  // Display the netclass name (a pad having a netcode = 0 (no net) use the
812  // default netclass for clearance):
813  if( m_netinfo->GetNet() <= 0 )
814  msg = bds.GetDefault()->GetName();
815  else
816  msg = GetNetClassName();
817 
818  aList.emplace_back( _( "NetClass" ), msg, CYAN );
819 
820  aList.emplace_back( _( "Layer" ), LayerMaskDescribe(), DARKGREEN );
821 
822  // Show the pad shape, attribute and property
823  wxString props = ShowPadAttr();
824 
825  if( GetProperty() != PAD_PROP_NONE )
826  props += ',';
827 
828  switch( GetProperty() )
829  {
830  case PAD_PROP_NONE: break;
831  case PAD_PROP_BGA: props += _("BGA" ); break;
832  case PAD_PROP_FIDUCIAL_GLBL: props += _("Fiducial global" ); break;
833  case PAD_PROP_FIDUCIAL_LOCAL: props += _("Fiducial local" ); break;
834  case PAD_PROP_TESTPOINT: props += _("Test point" ); break;
835  case PAD_PROP_HEATSINK: props += _("Heat sink" ); break;
836  case PAD_PROP_CASTELLATED: props += _("Castellated" ); break;
837  }
838 
839  aList.emplace_back( ShowPadShape(), props, DARKGREEN );
840 
842  && m_size.x == m_size.y )
843  {
844  msg = MessageTextFromValue( units, m_size.x, true );
845  aList.emplace_back( _( "Diameter" ), msg, RED );
846  }
847  else
848  {
849  msg = MessageTextFromValue( units, m_size.x, true );
850  aList.emplace_back( _( "Width" ), msg, RED );
851 
852  msg = MessageTextFromValue( units, m_size.y, true );
853  aList.emplace_back( _( "Height" ), msg, RED );
854  }
855 
856  double module_orient_degrees = module ? module->GetOrientationDegrees() : 0;
857  double pad_orient_degrees = GetOrientationDegrees() - module_orient_degrees;
858  pad_orient_degrees = NormalizeAngleDegrees( pad_orient_degrees, -180.0, +180.0 );
859 
860  if( module_orient_degrees != 0.0 )
861  msg.Printf( wxT( "%.2f(+ %.2f)" ), pad_orient_degrees, module_orient_degrees );
862  else
863  msg.Printf( wxT( "%.1f" ), GetOrientationDegrees() );
864 
865  aList.push_back( MSG_PANEL_ITEM( _( "Rotation" ), msg, LIGHTBLUE ) );
866 
867  if( GetPadToDieLength() )
868  {
869  msg = MessageTextFromValue(units, GetPadToDieLength(), true );
870  aList.emplace_back( _( "Length in Package" ), msg, CYAN );
871  }
872 
873  msg = MessageTextFromValue( units, m_drill.x, true );
874 
876  {
877  aList.emplace_back( _( "Drill" ), msg, RED );
878  }
879  else
880  {
881  msg = MessageTextFromValue( units, m_drill.x, true )
882  + wxT( "/" )
883  + MessageTextFromValue( units, m_drill.y, true );
884  aList.emplace_back( _( "Drill X / Y" ), msg, RED );
885  }
886 
887  wxString source;
888  int clearance = GetClearance( GetLayer(), nullptr, &source );
889 
890  msg.Printf( _( "Min Clearance: %s" ), MessageTextFromValue( units, clearance, true ) );
891  msg2.Printf( _( "(from %s)" ), source );
892  aList.emplace_back( msg, msg2, BLACK );
893 }
894 
895 
896 bool D_PAD::HitTest( const wxPoint& aPosition, int aAccuracy ) const
897 {
898  VECTOR2I delta = aPosition - GetPosition();
899  int boundingRadius = GetBoundingRadius() + aAccuracy;
900 
901  if( delta.SquaredEuclideanNorm() > SEG::Square( boundingRadius ) )
902  return false;
903 
904  return GetEffectivePolygon()->Contains( aPosition, -1, aAccuracy );
905 }
906 
907 
908 bool D_PAD::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
909 {
910  auto getArea = []( const SHAPE_POLY_SET& aPoly ) -> double
911  {
912  return aPoly.OutlineCount() ? aPoly.COutline( 0 ).Area() : 0;
913  };
914 
915  EDA_RECT arect = aRect;
916  arect.Normalize();
917  arect.Inflate( aAccuracy );
918 
919  EDA_RECT bbox = GetBoundingBox();
920 
921  if( !arect.Intersects( bbox ) )
922  return false;
923 
924  // This covers total containment for all test cases
925  if( arect.Contains( bbox ) )
926  return true;
927 
928  SHAPE_POLY_SET selRect;
929  selRect.NewOutline();
930  selRect.Append( arect.GetOrigin() );
931  selRect.Append( VECTOR2I( arect.GetRight(), arect.GetTop() ) );
932  selRect.Append( VECTOR2I( arect.GetRight(), arect.GetBottom() ) );
933  selRect.Append( VECTOR2I( arect.GetLeft(), arect.GetBottom() ) );
934 
936 
937  double padArea = getArea( *GetEffectivePolygon() );
938  double intersection = getArea( selRect );
939 
940  if( intersection > ( padArea * 0.99 ) )
941  return true;
942  else
943  return !aContained && intersection > 0;
944 }
945 
946 
947 bool D_PAD::Collide( const D_PAD* aPad, int aMinClearance, int* aActual )
948 {
949  int center2center = KiROUND( EuclideanNorm( aPad->ShapePos() - ShapePos() ) );
950 
951  // Quick test: Clearance is OK if the bounding circles are further away than aMinClearance
952  if( center2center - GetBoundingRadius() - aPad->GetBoundingRadius() >= aMinClearance )
953  return false;
954 
955 
956  return GetEffectiveShape()->Collide( aPad->GetEffectiveShape().get(), aMinClearance, aActual );
957 }
958 
959 
960 bool D_PAD::Collide( const SHAPE_SEGMENT* aSeg, int aMinClearance, int* aActual )
961 {
962  return aSeg->Collide( GetEffectiveShape().get(), aMinClearance, aActual );
963 }
964 
965 
966 int D_PAD::Compare( const D_PAD* padref, const D_PAD* padcmp )
967 {
968  int diff;
969 
970  if( ( diff = padref->GetShape() - padcmp->GetShape() ) != 0 )
971  return diff;
972 
973  if( ( diff = padref->GetDrillShape() - padcmp->GetDrillShape() ) != 0)
974  return diff;
975 
976  if( ( diff = padref->m_drill.x - padcmp->m_drill.x ) != 0 )
977  return diff;
978 
979  if( ( diff = padref->m_drill.y - padcmp->m_drill.y ) != 0 )
980  return diff;
981 
982  if( ( diff = padref->m_size.x - padcmp->m_size.x ) != 0 )
983  return diff;
984 
985  if( ( diff = padref->m_size.y - padcmp->m_size.y ) != 0 )
986  return diff;
987 
988  if( ( diff = padref->m_offset.x - padcmp->m_offset.x ) != 0 )
989  return diff;
990 
991  if( ( diff = padref->m_offset.y - padcmp->m_offset.y ) != 0 )
992  return diff;
993 
994  if( ( diff = padref->m_deltaSize.x - padcmp->m_deltaSize.x ) != 0 )
995  return diff;
996 
997  if( ( diff = padref->m_deltaSize.y - padcmp->m_deltaSize.y ) != 0 )
998  return diff;
999 
1000 // TODO: test custom shapes
1001 
1002  // Dick: specctra_export needs this
1003  // Lorenzo: gencad also needs it to implement padstacks!
1004 
1005 #if __cplusplus >= 201103L
1006  long long d = padref->m_layerMask.to_ullong() - padcmp->m_layerMask.to_ullong();
1007  if( d < 0 )
1008  return -1;
1009  else if( d > 0 )
1010  return 1;
1011 
1012  return 0;
1013 #else
1014  // these strings are not typically constructed, since we don't get here often.
1015  std::string s1 = padref->m_layerMask.to_string();
1016  std::string s2 = padcmp->m_layerMask.to_string();
1017  return s1.compare( s2 );
1018 #endif
1019 }
1020 
1021 
1022 void D_PAD::Rotate( const wxPoint& aRotCentre, double aAngle )
1023 {
1024  RotatePoint( &m_pos, aRotCentre, aAngle );
1025 
1026  m_orient = NormalizeAngle360Min( m_orient + aAngle );
1027 
1028  SetLocalCoord();
1029 
1030  m_shapesDirty = true;
1031 }
1032 
1033 
1034 wxString D_PAD::ShowPadShape() const
1035 {
1036  switch( GetShape() )
1037  {
1038  case PAD_SHAPE_CIRCLE: return _( "Circle" );
1039  case PAD_SHAPE_OVAL: return _( "Oval" );
1040  case PAD_SHAPE_RECT: return _( "Rect" );
1041  case PAD_SHAPE_TRAPEZOID: return _( "Trap" );
1042  case PAD_SHAPE_ROUNDRECT: return _( "Roundrect" );
1043  case PAD_SHAPE_CHAMFERED_RECT: return _( "Chamferedrect" );
1044  case PAD_SHAPE_CUSTOM: return _( "CustomShape" );
1045  default: return wxT( "???" );
1046  }
1047 }
1048 
1049 
1050 wxString D_PAD::ShowPadAttr() const
1051 {
1052  switch( GetAttribute() )
1053  {
1054  case PAD_ATTRIB_STANDARD: return _( "Std" );
1055  case PAD_ATTRIB_SMD: return _( "SMD" );
1056  case PAD_ATTRIB_CONN: return _( "Conn" );
1057  case PAD_ATTRIB_HOLE_NOT_PLATED: return _( "Not Plated" );
1058  default: return wxT( "???" );
1059  }
1060 }
1061 
1062 
1063 wxString D_PAD::GetSelectMenuText( EDA_UNITS aUnits ) const
1064 {
1065  if( GetName().IsEmpty() )
1066  {
1067  return wxString::Format( _( "Pad of %s on %s" ),
1068  GetParent()->GetReference(),
1069  LayerMaskDescribe() );
1070  }
1071  else
1072  {
1073  return wxString::Format( _( "Pad %s of %s on %s" ),
1074  GetName(),
1075  GetParent()->GetReference(),
1076  LayerMaskDescribe() );
1077  }
1078 }
1079 
1080 
1082 {
1083  return pad_xpm;
1084 }
1085 
1086 
1088 {
1089  return new D_PAD( *this );
1090 }
1091 
1092 
1094 {
1095  return( m_attribute == PAD_ATTRIB_STANDARD
1096  && m_drill.x >= m_size.x && m_drill.y >= m_size.y );
1097 }
1098 
1099 
1100 void D_PAD::ViewGetLayers( int aLayers[], int& aCount ) const
1101 {
1102  aCount = 0;
1103 
1104  // These 2 types of pads contain a hole
1106  aLayers[aCount++] = LAYER_PADS_PLATEDHOLES;
1107 
1109  aLayers[aCount++] = LAYER_NON_PLATEDHOLES;
1110 
1111  if( IsOnLayer( F_Cu ) && IsOnLayer( B_Cu ) )
1112  {
1113  // Multi layer pad
1114  aLayers[aCount++] = LAYER_PADS_TH;
1115  aLayers[aCount++] = LAYER_PADS_NETNAMES;
1116  }
1117  else if( IsOnLayer( F_Cu ) )
1118  {
1119  aLayers[aCount++] = LAYER_PAD_FR;
1120 
1121  // Is this a PTH pad that has only front copper? If so, we need to also display the
1122  // net name on the PTH netname layer so that it isn't blocked by the drill hole.
1124  aLayers[aCount++] = LAYER_PADS_NETNAMES;
1125  else
1126  aLayers[aCount++] = LAYER_PAD_FR_NETNAMES;
1127  }
1128  else if( IsOnLayer( B_Cu ) )
1129  {
1130  aLayers[aCount++] = LAYER_PAD_BK;
1131 
1132  // Is this a PTH pad that has only back copper? If so, we need to also display the
1133  // net name on the PTH netname layer so that it isn't blocked by the drill hole.
1135  aLayers[aCount++] = LAYER_PADS_NETNAMES;
1136  else
1137  aLayers[aCount++] = LAYER_PAD_BK_NETNAMES;
1138  }
1139  else
1140  {
1141  // Internal layers only. (Not yet supported in GUI, but is being used by Python
1142  // footprint generators and will be needed anyway once pad stacks are supported.)
1143  for ( int internal = In1_Cu; internal < In30_Cu; ++internal )
1144  {
1145  if( IsOnLayer( (PCB_LAYER_ID) internal ) )
1146  aLayers[aCount++] = internal;
1147  }
1148  }
1149 
1150  // Check non-copper layers. This list should include all the layers that the
1151  // footprint editor allows a pad to be placed on.
1152  static const PCB_LAYER_ID layers_mech[] = { F_Mask, B_Mask, F_Paste, B_Paste,
1154 
1155  for( PCB_LAYER_ID each_layer : layers_mech )
1156  {
1157  if( IsOnLayer( each_layer ) )
1158  aLayers[aCount++] = each_layer;
1159  }
1160 
1161 #ifdef __WXDEBUG__
1162  if( aCount == 0 ) // Should not occur
1163  {
1164  wxString msg;
1165  msg.Printf( wxT( "footprint %s, pad %s: could not find valid layer for pad" ),
1166  GetParent() ? GetParent()->GetReference() : "<null>",
1167  GetName().IsEmpty() ? "(unnamed)" : GetName() );
1168  wxLogWarning( msg );
1169  }
1170 #endif
1171 }
1172 
1173 
1174 double D_PAD::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const
1175 {
1176  if( aView->GetPrintMode() > 0 ) // In printing mode the pad is always drawable
1177  return 0.0;
1178 
1179  constexpr double HIDE = std::numeric_limits<double>::max();
1180  BOARD* board = GetBoard();
1181 
1182  // Meta control for hiding all pads
1183  if( !aView->IsLayerVisible( LAYER_PADS ) )
1184  return HIDE;
1185 
1186  // Handle Render tab switches
1188  && !aView->IsLayerVisible( LAYER_PADS_TH ) )
1189  return HIDE;
1190 
1191  if( !IsFlipped() && !aView->IsLayerVisible( LAYER_MOD_FR ) )
1192  return HIDE;
1193 
1194  if( IsFlipped() && !aView->IsLayerVisible( LAYER_MOD_BK ) )
1195  return HIDE;
1196 
1197  if( IsFrontLayer( (PCB_LAYER_ID) aLayer ) && !aView->IsLayerVisible( LAYER_PAD_FR ) )
1198  return HIDE;
1199 
1200  if( IsBackLayer( (PCB_LAYER_ID) aLayer ) && !aView->IsLayerVisible( LAYER_PAD_BK ) )
1201  return HIDE;
1202 
1203  // Only draw the pad if at least one of the layers it crosses is being displayed
1204  if( board && !IsPadOnLayer( board->GetVisibleLayers() ) )
1205  return HIDE;
1206 
1207  // Netnames will be shown only if zoom is appropriate
1208  if( IsNetnameLayer( aLayer ) )
1209  {
1210  int divisor = std::min( GetBoundingBox().GetWidth(), GetBoundingBox().GetHeight() );
1211 
1212  // Pad sizes can be zero briefly when someone is typing a number like "0.5"
1213  // in the pad properties dialog
1214  if( divisor == 0 )
1215  return HIDE;
1216 
1217  return ( double ) Millimeter2iu( 5 ) / divisor;
1218  }
1219 
1220  // Other layers are shown without any conditions
1221  return 0;
1222 }
1223 
1224 
1225 const BOX2I D_PAD::ViewBBox() const
1226 {
1227  // Bounding box includes soldermask too
1228  int solderMaskMargin = GetSolderMaskMargin();
1229  VECTOR2I solderPasteMargin = VECTOR2D( GetSolderPasteMargin() );
1230  EDA_RECT bbox = GetBoundingBox();
1231 
1232  // Look for the biggest possible bounding box
1233  int xMargin = std::max( solderMaskMargin, solderPasteMargin.x );
1234  int yMargin = std::max( solderMaskMargin, solderPasteMargin.y );
1235 
1236  return BOX2I( VECTOR2I( bbox.GetOrigin() ) - VECTOR2I( xMargin, yMargin ),
1237  VECTOR2I( bbox.GetSize() ) + VECTOR2I( 2 * xMargin, 2 * yMargin ) );
1238 }
1239 
1240 
1241 void D_PAD::ImportSettingsFrom( const D_PAD& aMasterPad )
1242 {
1243  SetShape( aMasterPad.GetShape() );
1244  SetLayerSet( aMasterPad.GetLayerSet() );
1245  SetAttribute( aMasterPad.GetAttribute() );
1246  SetProperty( aMasterPad.GetProperty() );
1247 
1248  // I am not sure the m_LengthPadToDie must be imported, because this is
1249  // a parameter really specific to a given pad (JPC).
1250  // So this is currently non imported
1251  #if 0
1252  SetPadToDieLength( aMasterPad.GetPadToDieLength() );
1253  #endif
1254 
1255  // The pad orientation, for historical reasons is the
1256  // pad rotation + parent rotation.
1257  // So we have to manage this parent rotation
1258  double pad_rot = aMasterPad.GetOrientation();
1259 
1260  if( aMasterPad.GetParent() )
1261  pad_rot -= aMasterPad.GetParent()->GetOrientation();
1262 
1263  if( GetParent() )
1264  pad_rot += GetParent()->GetOrientation();
1265 
1266  SetOrientation( pad_rot );
1267 
1268  SetSize( aMasterPad.GetSize() );
1269  SetDelta( wxSize( 0, 0 ) );
1270  SetOffset( aMasterPad.GetOffset() );
1271  SetDrillSize( aMasterPad.GetDrillSize() );
1272  SetDrillShape( aMasterPad.GetDrillShape() );
1274  SetChamferRectRatio( aMasterPad.GetChamferRectRatio() );
1275  SetChamferPositions( aMasterPad.GetChamferPositions() );
1276 
1277  switch( aMasterPad.GetShape() )
1278  {
1279  case PAD_SHAPE_TRAPEZOID:
1280  SetDelta( aMasterPad.GetDelta() );
1281  break;
1282 
1283  case PAD_SHAPE_CIRCLE:
1284  // ensure size.y == size.x
1285  SetSize( wxSize( GetSize().x, GetSize().x ) );
1286  break;
1287 
1288  default:
1289  ;
1290  }
1291 
1292  switch( aMasterPad.GetAttribute() )
1293  {
1294  case PAD_ATTRIB_SMD:
1295  case PAD_ATTRIB_CONN:
1296  // These pads do not have hole (they are expected to be only on one
1297  // external copper layer)
1298  SetDrillSize( wxSize( 0, 0 ) );
1299  break;
1300 
1301  default:
1302  ;
1303  }
1304 
1305  // copy also local settings:
1306  SetLocalClearance( aMasterPad.GetLocalClearance() );
1310 
1313  SetThermalGap( aMasterPad.GetThermalGap() );
1314 
1316 
1317  // Add or remove custom pad shapes:
1318  ReplacePrimitives( aMasterPad.GetPrimitives() );
1319  SetAnchorPadShape( aMasterPad.GetAnchorPadShape() );
1320 
1321  m_shapesDirty = true;
1322 }
1323 
1324 
1326 {
1327  assert( aImage->Type() == PCB_PAD_T );
1328 
1329  std::swap( *((MODULE*) this), *((MODULE*) aImage) );
1330 }
1331 
1332 
1333 static struct PAD_DESC
1334 {
1336  {
1338  .Map( PAD_SHAPE_CIRCLE, _( "Circle" ) )
1339  .Map( PAD_SHAPE_RECT, _( "Rectangle" ) )
1340  .Map( PAD_SHAPE_OVAL, _( "Oval" ) )
1341  .Map( PAD_SHAPE_TRAPEZOID, _( "Trapezoid" ) )
1342  .Map( PAD_SHAPE_ROUNDRECT, _( "Rounded rectangle" ) )
1343  .Map( PAD_SHAPE_CHAMFERED_RECT, _( "Chamfered rectangle" ) )
1344  .Map( PAD_SHAPE_CUSTOM, _( "Custom" ) );
1345 
1347  .Map( PAD_PROP_NONE, _( "None" ) )
1348  .Map( PAD_PROP_BGA, _( "BGA pad" ) )
1349  .Map( PAD_PROP_FIDUCIAL_GLBL, _( "Fiducial, global to board" ) )
1350  .Map( PAD_PROP_FIDUCIAL_LOCAL, _( "Fiducial, local to footprint" ) )
1351  .Map( PAD_PROP_TESTPOINT, _( "Test point pad" ) )
1352  .Map( PAD_PROP_HEATSINK, _( "Heatsink pad" ) )
1353  .Map( PAD_PROP_CASTELLATED, _( "Castellated pad" ) );
1354 
1356  REGISTER_TYPE( D_PAD );
1358 
1359  auto shape = new PROPERTY_ENUM<D_PAD, PAD_SHAPE_T>( _( "Shape" ),
1361  propMgr.AddProperty( shape );
1362 
1363  propMgr.AddProperty( new PROPERTY<D_PAD, wxString>( _( "Name" ),
1365  propMgr.AddProperty( new PROPERTY<D_PAD, double>( _( "Orientation" ),
1368  propMgr.AddProperty( new PROPERTY<D_PAD, int>( _( "Pad To Die Length" ),
1371  propMgr.AddProperty( new PROPERTY<D_PAD, int>( _( "Local Soldermask Margin" ),
1374  propMgr.AddProperty( new PROPERTY<D_PAD, int>( _( "Local Solderpaste Margin" ),
1377  propMgr.AddProperty( new PROPERTY<D_PAD, double>( _( "Local Solderpaste Margin Ratio" ),
1379  propMgr.AddProperty( new PROPERTY<D_PAD, int>( _( "Thermal Relief Spoke Width" ),
1382  propMgr.AddProperty( new PROPERTY<D_PAD, int>( _( "Thermal Relief" ),
1385  propMgr.AddProperty( new PROPERTY_ENUM<D_PAD, PAD_PROP_T>( _( "Fabrication Property" ),
1387 
1388  auto roundRadiusRatio = new PROPERTY<D_PAD, double>( _( "Round Radius Ratio" ),
1390  roundRadiusRatio->SetAvailableFunc(
1391  [=]( INSPECTABLE* aItem ) -> bool
1392  {
1393  return aItem->Get( shape ) == PAD_SHAPE_ROUNDRECT;
1394  } );
1395  propMgr.AddProperty( roundRadiusRatio );
1396 
1397  propMgr.AddProperty( new PROPERTY<D_PAD, int>( _( "Local Clearance" ),
1400  // TODO delta, size, drill size, dirill shape offset, layerset, zone connection
1401  }
1402 } _PAD_DESC;
1403 
double EuclideanNorm(const wxPoint &vector)
Euclidean norm of a 2D vector.
Definition: trigo.h:133
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Function AllCuMask returns a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:719
Display value expressed in degrees.
Definition: property.h:48
EDA_UNITS
Definition: common.h:198
BITMAP_DEF GetMenuImage() const override
Function GetMenuImage returns a pointer to an image to be used in menus.
Definition: class_pad.cpp:1081
ZONE_CONNECTION
How pads are covered by copper in zone.
Definition: zones.h:41
std::vector< std::shared_ptr< DRAWSEGMENT > > m_editPrimitives
Definition: class_pad.h:646
double m_roundedCornerScale
Definition: class_pad.h:671
int GetLocalSolderMaskMargin() const
Definition: class_pad.h:347
double GetOrientation() const
Definition: class_module.h:224
EDA_ITEM * Clone() const override
Function Clone creates a duplicate of this item with linked list members set to NULL.
Definition: class_pad.cpp:1087
bool Collide(const SHAPE_SEGMENT *aSeg, int aMinClearance, int *aActual=nullptr)
Definition: class_pad.cpp:960
BOX2< VECTOR2I > BOX2I
Definition: box2.h:522
SHAPE_SIMPLE.
Definition: shape_simple.h:43
static PROPERTY_MANAGER & Instance()
Definition: property_mgr.h:61
EDA_ITEM * m_Parent
Linked list: Link (parent struct)
Definition: base_struct.h:174
#define TYPE_HASH(x)
Macro to generate unique identifier for a type
Definition: property.h:53
LSET FlipLayerMask(LSET aMask, int aCopperLayersCount)
Calculate the mask layer when flipping a footprint BACK and FRONT copper layers, mask,...
Definition: lset.cpp:536
const wxPoint & GetPos0() const
Definition: class_pad.h:218
static LSET StandardMask()
layer set for a through hole pad
Definition: class_pad.cpp:141
bool HitTest(const wxPoint &aPosition, int aAccuracy=0) const override
Function HitTest tests if aPosition is contained within or on the bounding box of an item.
Definition: class_pad.cpp:896
PNG memory record (file in memory).
Definition: bitmap_def.h:29
no special fabrication property
Definition: pad_shapes.h:97
like PAD_STANDARD, but not plated mechanical use only, no connection allowed
Definition: pad_shapes.h:85
void Rotate(const wxPoint &aRotCentre, double aAngle) override
Function Rotate Rotate this object.
Definition: class_pad.cpp:1022
PAD_ATTR_T
Enum PAD_ATTR_T is the set of pad shapes, used with D_PAD::{Set,Get}Attribute() The double name is fo...
Definition: pad_shapes.h:78
static std::string PAD_SHAPE_T_asString(PAD_SHAPE_T a)
Definition: pad_shapes.h:45
const BITMAP_OPAQUE pad_xpm[1]
Definition: pad.cpp:41
multilayer pads, usually with holes
Implementation of conversion functions that require both schematic and board internal units.
static LSET UnplatedHoleMask()
layer set for a mechanical unplated through hole pad
Definition: class_pad.cpp:162
BOARD_ITEM is a base class for any item which can be embedded within the BOARD container class,...
PAD_SHAPE_T GetAnchorPadShape() const
Function GetAnchorPadShape.
Definition: class_pad.h:171
static LSET SMDMask()
layer set for a SMD pad on Front layer
Definition: class_pad.cpp:148
wxPoint GetPosition() const override
Definition: class_pad.h:165
int GetTop() const
Definition: eda_rect.h:123
const wxString & GetName() const
Definition: netclass.h:96
const SHAPE_SEGMENT * GetEffectiveHoleShape() const
Function GetEffectiveHoleShape Returns a SHAPE object representing the pad's hole.
Definition: class_pad.cpp:273
PAD_PROP_T m_property
Definition: class_pad.h:701
handle color for not plated holes (holes, not pads)
bool IsBackLayer(PCB_LAYER_ID aLayerId)
Layer classification: check if it's a back layer.
wxPoint m_pos0
Definition: class_pad.h:696
void FlipPrimitives(bool aFlipLeftRight)
Flip (mirror) the primitives left to right or top to bottom, around the anchor position in custom pad...
Definition: class_pad.cpp:587
bool m_shapesDirty
Definition: class_pad.h:649
D_PAD(MODULE *parent)
Definition: class_pad.cpp:56
a fiducial (usually a smd) for the full board
Definition: pad_shapes.h:99
int GetLeft() const
Definition: eda_rect.h:122
double GetOrientationDegrees() const
Definition: class_pad.h:322
void Move(const VECTOR2I &aVector) override
ZONE_CONNECTION GetZoneConnection() const
Definition: class_module.h:261
void SetChamferPositions(int aPositions)
has meaning only for chamfered rect pads set the position of the chamfers for orientation 0.
Definition: class_pad.h:502
bool IsFlipped() const
Definition: class_pad.cpp:176
int GetPadToDieLength() const
Definition: class_pad.h:345
Smd pad, appears on the solder paste layer (default)
Definition: pad_shapes.h:81
double m_orient
Definition: class_pad.h:703
static ENUM_MAP< T > & Instance()
Definition: property.h:517
Definition: color4d.h:61
LSET GetVisibleLayers() const
Function GetVisibleLayers is a proxy function that calls the correspondent function in m_BoardSetting...
class ARC, an arc track segment on a copper layer
Definition: typeinfo.h:98
virtual wxString LayerMaskDescribe() const
Helper function Return a string (to be shown to the user) describing a layer mask.
std::shared_ptr< SHAPE_SEGMENT > m_effectiveHoleShape
Definition: class_pad.h:653
Smd pad, used in BGA footprints.
Definition: pad_shapes.h:98
void SetPosition(const wxPoint &aPos) override
Definition: class_pad.h:159
extended_type SquaredEuclideanNorm() const
Function Squared Euclidean Norm computes the squared euclidean norm of the vector,...
Definition: vector2d.h:306
wxString GetNetname() const
Function GetNetname.
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:537
wxSize m_size
Definition: class_pad.h:667
class D_PAD, a pad in a footprint
Definition: typeinfo.h:90
#define KI_FALLTHROUGH
The KI_FALLTHROUGH macro is to be used when switch statement cases should purposely fallthrough from ...
Definition: macros.h:88
void SetSubRatsnest(int aSubRatsnest)
Definition: class_pad.h:510
void SetDrillSize(const wxSize &aSize)
Definition: class_pad.h:229
int m_localSolderPasteMargin
Definition: class_pad.h:722
const std::shared_ptr< SHAPE_POLY_SET > & GetEffectivePolygon(PCB_LAYER_ID=UNDEFINED_LAYER) const
Definition: class_pad.cpp:255
Definition: color4d.h:44
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:208
void NORMALIZE_ANGLE_POS(T &Angle)
Definition: trigo.h:276
a pad used as heat sink, usually in SMD footprints
Definition: pad_shapes.h:102
void SetRoundRectRadiusRatio(double aRadiusScale)
has meaning only for rounded rect pads Set the ratio between the smaller X or Y size and the rounded ...
Definition: class_pad.cpp:239
const wxString & GetPinFunction() const
Definition: class_pad.h:138
wxString ShowPadAttr() const
Function ShowPadAttr.
Definition: class_pad.cpp:1050
The base class for create windows for drawing purpose.
VECTOR2< int > VECTOR2I
Definition: vector2d.h:594
int GetThermalGap() const
Definition: class_pad.h:464
int GetLocalSolderMaskMargin() const
Definition: class_module.h:240
int PointCount() const
Function PointCount()
LSEQ Seq(const PCB_LAYER_ID *aWishListSequence, unsigned aCount) const
Function Seq returns an LSEQ from the union of this LSET and a desired sequence.
Definition: lset.cpp:380
static SEG::ecoord Square(int a)
Definition: seg.h:116
BOARD_CONNECTED_ITEM is a base class derived from BOARD_ITEM for items that can be connected and have...
int GetLocalClearance() const
Definition: class_pad.h:351
#define REGISTER_TYPE(x)
Helper macro to map type hashes to names
Definition: property_mgr.h:244
bool Contains(const wxPoint &aPoint) const
Function Contains.
wxString GetNetClassName() const
Function GetNetClassName returns a pointer to the netclass of the zone.
PAD_SHAPE_T
Enum PAD_SHAPE_T is the set of pad shapes, used with D_PAD::{Set,Get}Shape()
Definition: pad_shapes.h:33
int m_localClearance
Definition: class_pad.h:720
void SetLocalCoord()
Set relative coordinates.
Definition: class_pad.cpp:485
PAD_ATTR_T GetAttribute() const
Definition: class_pad.h:335
class TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:96
void Append(int aX, int aY, bool aAllowDuplication=false)
Function Append()
int m_localSolderMaskMargin
Definition: class_pad.h:721
This file contains miscellaneous commonly used macros and functions.
int GetBottom() const
Definition: eda_rect.h:124
const wxString GetReference() const
Function GetReference.
Definition: class_module.h:451
int GetChamferPositions() const
Definition: class_pad.h:503
a pad with a castellated through hole
Definition: pad_shapes.h:103
show modules on front
bool m_keepTopBottomLayer
Definition: class_pad.h:708
int m_thermalGap
Definition: class_pad.h:728
void MIRROR(T &aPoint, const T &aMirrorRef)
Definition: macros.h:175
void SetThermalSpokeWidth(int aWidth)
Set the width of the thermal spokes connecting the pad to a zone.
Definition: class_pad.h:455
const VECTOR2I & CPoint(int aIndex) const
Function Point()
class MODULE, a footprint
Definition: typeinfo.h:89
virtual int GetClearance(PCB_LAYER_ID aLayer, BOARD_ITEM *aItem=nullptr, wxString *aSource=nullptr) const
Function GetClearance returns the clearance in internal units.
void SetAnchorPadShape(PAD_SHAPE_T aShape)
Function SetAnchorPadShape Set the shape of the anchor pad for custm shped pads.
Definition: class_pad.h:198
int GetSolderMaskMargin() const
Function GetSolderMaskMargin.
Definition: class_pad.cpp:637
PCB_LAYER_ID
A quick note on layer IDs:
wxString m_name
Definition: class_pad.h:634
Display value expressed in distance units (mm/inch)
Definition: property.h:47
virtual const BOX2I ViewBBox() const override
Function ViewBBox() returns the bounding box of the item covering all its layers.
Definition: class_pad.cpp:1225
LSET is a set of PCB_LAYER_IDs.
int GetLocalClearance() const
Definition: class_module.h:243
#define NULL
VECTOR2< double > VECTOR2D
Definition: vector2d.h:593
double m_chamferScale
Definition: class_pad.h:673
void SetName(const wxString &aName)
Set the pad name (sometimes called pad number, although it can be an array reference like AA12).
Definition: class_pad.h:131
void BuildEffectiveShapes(PCB_LAYER_ID aLayer) const
Rebuilds the effective shape cache (and bounding box and radius) for the pad and clears the dirty bit...
Definition: class_pad.cpp:291
SHAPE_POLY_SET.
void SetPos0(const wxPoint &aPos)
Definition: class_pad.h:217
const wxPoint GetOrigin() const
Definition: eda_rect.h:114
wxString ShowPadShape() const
Function ShowPadShape.
Definition: class_pad.cpp:1034
D_PAD & operator=(const D_PAD &aOther)
Definition: class_pad.cpp:122
wxString GetSelectMenuText(EDA_UNITS aUnits) const override
Function GetSelectMenuText returns the text to display to be used in the selection clarification cont...
Definition: class_pad.cpp:1063
coord_type GetWidth() const
Definition: box2.h:197
double ViewGetLOD(int aLayer, KIGFX::VIEW *aView) const override
Function ViewGetLOD() Returns the level of detail (LOD) of the item.
Definition: class_pad.cpp:1174
PAD_ATTR_T m_attribute
Definition: class_pad.h:699
static int Compare(const D_PAD *padref, const D_PAD *padcmp)
Function Compare compares two pads and return 0 if they are equal.
Definition: class_pad.cpp:966
const wxPoint & GetOffset() const
Definition: class_pad.h:233
Meta control for all pads opacity/visibility (color ignored)
PAD_DRILL_SHAPE_T GetDrillShape() const
Definition: class_pad.h:326
double GetChamferRectRatio() const
Definition: class_pad.h:495
wxAny Get(PROPERTY_BASE *aProperty)
Definition: inspectable.h:84
LSET GetLayerSet() const override
Function GetLayerSet returns a std::bitset of all layers on which the item physically resides.
Definition: class_pad.h:332
virtual BOARD * GetBoard() const
Function GetBoard returns the BOARD in which this BOARD_ITEM resides, or NULL if none.
int GetRight() const
Definition: eda_rect.h:121
CUST_PAD_SHAPE_IN_ZONE m_customShapeClearanceArea
Definition: class_pad.h:661
std::shared_ptr< CONNECTIVITY_DATA > GetConnectivity() const
Function GetConnectivity() returns list of missing connections between components/tracks.
Definition: class_board.h:345
void InheritsAfter(TYPE_ID aDerived, TYPE_ID aBase)
Declares an inheritance relationship between types.
int m_effectiveBoundingRadius
Definition: class_pad.h:650
int GetLocalClearance(wxString *aSource) const override
Function GetLocalClearance returns any local clearances set in the "classic" (ie: pre-rule) system.
Definition: class_pad.cpp:626
const wxString & GetName() const
Definition: class_pad.h:132
void SetSize(const wxSize &aSize)
Definition: class_pad.h:223
int GetBoundingRadius() const
Function GetBoundingRadius returns the radius of a minimum sized circle which fully encloses this pad...
Definition: class_pad.cpp:282
double GetOrientationDegrees() const
Definition: class_module.h:225
void SetOrientationDegrees(double aOrientation)
Set orientation in degrees.
Definition: class_pad.h:314
Definition: color4d.h:58
void SetRoundRectCornerRadius(double aRadius)
Function SetRoundRectCornerRadius has meaning only for rounded rect pads.
Definition: class_pad.cpp:230
virtual void ViewGetLayers(int aLayers[], int &aCount) const override
Function ViewGetLayers() Returns the all the layers within the VIEW the object is painted on.
Definition: class_pad.cpp:1100
PAD_PROP_T
Enum PAD_PROP_T is the set of pad properties used in Gerber files (Draw files, and P&P files) to defi...
Definition: pad_shapes.h:95
SHAPE.
Definition: shape.h:120
void SetZoneConnection(ZONE_CONNECTION aType)
Definition: class_pad.h:440
virtual std::shared_ptr< SHAPE > GetEffectiveShape(PCB_LAYER_ID aLayer=UNDEFINED_LAYER) const override
Function GetEffectiveShape Some pad shapes can be complex (rounded/chamfered rectangle),...
Definition: class_pad.cpp:264
PAD_PROP_T GetProperty() const
Definition: class_pad.h:338
void SetPadToDieLength(int aLength)
Definition: class_pad.h:344
const wxSize & GetDelta() const
Definition: class_pad.h:227
void SetDrawCoord()
Set absolute coordinates.
Definition: class_pad.cpp:467
ZONE_CONNECTION GetEffectiveZoneConnection(wxString *aSource=nullptr) const
Return the zone connection in effect (either locally overridden or overridden in the parent module).
Definition: class_pad.cpp:734
void BooleanIntersection(const SHAPE_POLY_SET &b, POLYGON_MODE aFastMode)
Performs boolean polyset intersection For aFastMode meaning, see function booleanOp
Like smd, does not appear on the solder paste layer (default) note also has a special attribute in Ge...
Definition: pad_shapes.h:82
double m_localSolderPasteMarginRatio
Definition: class_pad.h:723
Class that other classes need to inherit from, in order to be inspectable.
Definition: inspectable.h:33
int NewOutline()
Creates a new empty polygon in the set and returns its index
static struct PAD_DESC _PAD_DESC
Definition: color4d.h:59
EDA_ITEM & operator=(const EDA_ITEM &aItem)
Operator assignment is used to assign the members of aItem to another object.
wxPoint m_offset
Definition: class_pad.h:687
void SetAttribute(PAD_ATTR_T aAttribute)
Definition: class_pad.cpp:500
void TransformShapeWithClearanceToPolygon(SHAPE_POLY_SET &aCornerBuffer, PCB_LAYER_ID aLayer, int aClearanceValue, int aMaxError=ARC_HIGH_DEF, bool ignoreLineWidth=false) const override
Function TransformShapeWithClearanceToPolygon Convert the pad shape to a closed polygon.
int GetLocalClearanceOverrides(wxString *aSource) const override
Function GetLocalClearanceOverrides returns any local clearance overrides set in the "classic" (ie: p...
Definition: class_pad.cpp:612
int GetLocalSolderPasteMargin() const
Definition: class_module.h:254
void SetLocalClearance(int aClearance)
Definition: class_pad.h:352
int m_chamferPositions
Definition: class_pad.h:675
const KIID m_Uuid
Definition: base_struct.h:162
void ReplacePrimitives(const std::vector< std::shared_ptr< DRAWSEGMENT >> &aPrimitivesList)
Clear the current custom shape primitives list and import a new list.
const Vec & GetPosition() const
Definition: box2.h:194
MODULE * GetParent() const
Definition: class_pad.h:111
void SetLocalSolderPasteMarginRatio(double aRatio)
Definition: class_pad.h:358
CUST_PAD_SHAPE_IN_ZONE GetCustomShapeInZoneOpt() const
Definition: class_pad.h:177
std::shared_ptr< SHAPE_POLY_SET > m_effectivePolygon
Definition: class_pad.h:654
void Rotate(double aAngle, const VECTOR2I &aCenter=VECTOR2I(0, 0)) override
Function Rotate rotates all vertices by a given angle.
bool IsFrontLayer(PCB_LAYER_ID aLayerId)
Layer classification: check if it's a front layer.
void Normalize()
Function Normalize ensures that the height ant width are positive.
wxString MessageTextFromValue(EDA_UNITS aUnits, int aValue, bool aUseMils, EDA_DATA_TYPE aType)
Definition: base_units.cpp:124
void SetDrillShape(PAD_DRILL_SHAPE_T aShape)
Definition: class_pad.h:325
LSET m_layerMask
Definition: class_pad.h:689
ZONE_CONNECTION m_zoneConnection
Definition: class_pad.h:726
virtual void SwapData(BOARD_ITEM *aImage) override
Swap data between aItem and aImage.
Definition: class_pad.cpp:1325
int GetPrintMode()
Definition: view.h:688
double GetLocalSolderPasteMarginRatio() const
Definition: class_module.h:257
int m_thermalWidth
Definition: class_pad.h:727
smd pads, front layer
a fiducial (usually a smd) local to the parent footprint
Definition: pad_shapes.h:100
Class to handle a graphic segment.
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:201
wxSize GetSolderPasteMargin() const
Function GetSolderPasteMargin.
Definition: class_pad.cpp:682
int GetNet() const
Function GetNet.
Definition: netinfo.h:223
BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:178
void SetLocalSolderMaskMargin(int aMargin)
Definition: class_pad.h:348
#define _(s)
Definition: 3d_actions.cpp:33
SHAPE_LINE_CHAIN.
double GetOrientation() const
Function GetOrientation returns the rotation angle of the pad in a variety of units (the basic call r...
Definition: class_pad.h:321
NETINFO_ITEM * m_netinfo
Stores all informations about the net that item belongs to.
wxString UnescapeString(const wxString &aSource)
Definition: string.cpp:152
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
void ImportSettingsFrom(const D_PAD &aMasterPad)
Imports the pad settings from aMasterPad.
Definition: class_pad.cpp:1241
wxSize m_drill
Definition: class_pad.h:666
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
void AddProperty(PROPERTY_BASE *aProperty)
Registers a property.
const wxSize & GetDrillSize() const
Definition: class_pad.h:230
void Flip(const wxPoint &aCentre, bool aFlipLeftRight) override
Function Flip Flip this object, i.e.
Definition: class_pad.cpp:528
wxPoint ShapePos() const
Definition: class_pad.cpp:597
EDA_RECT handles the component boundary box.
Definition: eda_rect.h:44
double DECIDEG2RAD(double deg)
Definition: trigo.h:223
NETCLASS * GetDefault() const
Function GetDefault.
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
int GetSubRatsnest() const
Function GetSubRatsnest.
Definition: class_pad.h:509
EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boards.
Definition: base_struct.h:159
void GetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList) override
Function GetMsgPanelInfo populates aList of MSG_PANEL_ITEM objects with it's internal state for displ...
Definition: class_pad.cpp:793
coord_type GetHeight() const
Definition: box2.h:198
double NormalizeAngleDegrees(double Angle, double aMin, double aMax)
Normalize angle to be aMin < angle <= aMax angle is in degrees.
Definition: trigo.h:311
void SetShape(PAD_SHAPE_T aShape)
Set the new shape of this pad.
Definition: class_pad.h:148
void SetPinFunction(const wxString &aName)
Set the pad function (pin name in schematic)
Definition: class_pad.h:137
bool Intersects(const EDA_RECT &aRect) const
Function Intersects tests for a common area between rectangles.
std::shared_ptr< SHAPE_COMPOUND > m_effectiveShape
Definition: class_pad.h:652
int GetRoundRectCornerRadius() const
Definition: class_pad.cpp:224
void SetOrientation(double aAngle)
Function SetOrientation sets the rotation angle of the pad.
Definition: class_pad.cpp:519
double GetRoundRectRadiusRatio() const
Definition: class_pad.h:487
void SetChamferRectRatio(double aChamferScale)
has meaning only for chamfered rect pads Set the ratio between the smaller X or Y size and chamfered ...
Definition: class_pad.cpp:247
Provides class metadata.
Definition: property_mgr.h:58
void SetLocalSolderPasteMargin(int aMargin)
Definition: class_pad.h:355
EDA_RECT m_effectiveBoundingBox
Definition: class_pad.h:651
static LSET ConnSMDMask()
layer set for a SMD pad on Front layer used for edge board connectors
Definition: class_pad.cpp:155
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: class_pad.h:187
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:97
wxPoint GetPosition() const override
Definition: class_module.h:219
PAD_SHAPE_T GetShape() const
Definition: class_pad.h:157
static LSET ApertureMask()
layer set for an aperture pad
Definition: class_pad.cpp:169
int m_lengthPadToDie
Definition: class_pad.h:705
EDA_MSG_ITEM is used EDA_MSG_PANEL as the item type for displaying messages.
Definition: msgpanel.h:53
VIEW.
Definition: view.h:61
const std::vector< std::shared_ptr< DRAWSEGMENT > > & GetPrimitives() const
Accessor to the basic shape list for custom-shaped pads.
Definition: class_pad.h:273
wxPoint m_pos
Definition: class_pad.h:637
const wxSize & GetSize() const
Definition: class_pad.h:224
void SetProperty(PAD_PROP_T aProperty)
Definition: class_pad.cpp:511
bool IsOnLayer(PCB_LAYER_ID aLayer) const override
Function IsOnLayer tests to see if this object is on the given layer.
Definition: class_pad.h:528
int GetThermalWidth() const
Definition: class_module.h:264
ENUM_TO_WXANY(PAD_SHAPE_T)
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:242
int GetLocalSolderPasteMargin() const
Definition: class_pad.h:354
void TransformRoundChamferedRectToPolygon(SHAPE_POLY_SET &aCornerBuffer, const wxPoint &aPosition, const wxSize &aSize, double aRotation, int aCornerRadius, double aChamferRatio, int aChamferCorners, int aError)
convert a rectangle with rounded corners and/or chamfered corners to a polygon Convert rounded corner...
Message panel definition file.
void SetOffset(const wxPoint &aOffset)
Definition: class_pad.h:232
int GetThermalSpokeWidth() const
Definition: class_pad.h:456
int GetEffectiveThermalGap(wxString *aSource=nullptr) const
Return the effective thermal gap having resolved any inheritance.
Definition: class_pad.cpp:774
a test point pad
Definition: pad_shapes.h:101
bool PadShouldBeNPTH() const
A pad whose hole is the same size as the pad is a NPTH.
Definition: class_pad.cpp:1093
static constexpr int Millimeter2iu(double mm)
bool Collide(const SHAPE *aShape, int aClearance, VECTOR2I *aMTV) const override
Function Collide()
Definition: shape_segment.h:59
virtual PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
int GetEffectiveThermalSpokeWidth(wxString *aSource=nullptr) const
Return the effective thermal spoke width having resolved any inheritance.
Definition: class_pad.cpp:755
void SetThermalGap(int aGap)
Definition: class_pad.h:463
int GetThermalGap() const
Definition: class_module.h:267
void SetLayerSet(LSET aLayers) override
Definition: class_pad.h:331
bool m_removeUnconnectedLayer
Definition: class_pad.h:707
const EDA_RECT GetBoundingBox() const override
Function GetBoundingBox The bounding box is cached, so this will be efficient most of the time.
Definition: class_pad.cpp:458
EDA_UNITS GetUserUnits() const
Return the user units currently in use.
double GetLocalSolderPasteMarginRatio() const
Definition: class_pad.h:357
Additional netnames layers (not associated with a PCB layer)
void SetDelta(const wxSize &aSize)
Definition: class_pad.h:226
bool IsPadOnLayer(int aLayer) const
Definition: class_pad.cpp:196
EDA_RECT & Inflate(wxCoord dx, wxCoord dy)
Function Inflate inflates the rectangle horizontally by dx and vertically by dy.
wxSize m_deltaSize
Definition: class_pad.h:692
const wxSize GetSize() const
Definition: eda_rect.h:103
bool IsNetnameLayer(LAYER_NUM aLayer)
Function IsNetnameLayer tests whether a layer is a netname layer.
KICAD_T Type() const
Function Type()
Definition: base_struct.h:193
BOARD_DESIGN_SETTINGS contains design settings for a BOARD object.
bool IsLayerVisible(int aLayer) const
Function IsLayerVisible() Returns information about visibility of a particular layer.
Definition: view.h:405
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Appends a vertex at the end of the given outline/hole (default: the last outline)