You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

801 lines
30 KiB

5 years ago
5 years ago
8 years ago
5 years ago
5 years ago
5 years ago
11 years ago
5 years ago
5 years ago
14 years ago
14 years ago
14 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
18 years ago
18 years ago
18 years ago
5 years ago
5 years ago
5 years ago
5 years ago
Introduction of Graphics Abstraction Layer based rendering for pcbnew. New classes: - VIEW - represents view that is seen by user, takes care of layer ordering & visibility and how it is displayed (which location, how much zoomed, etc.) - VIEW_ITEM - Base class for every item that can be displayed on VIEW (the biggest change is that now it may be necessary to override ViewBBox & ViewGetLayers method for derived classes). - EDA_DRAW_PANEL_GAL - Inherits after EDA_DRAW_PANEL, displays VIEW output, right now it is not editable (in opposite to usual EDA_DRAW_PANEL). - GAL/OPENGL_GAL/CAIRO_GAL - Base Graphics Abstraction Layer class + two different flavours (Cairo is not fully supported yet), that offers methods to draw primitives using different libraries. - WX_VIEW_CONTROLS - Controller for VIEW, handles user events, allows zooming, panning, etc. - PAINTER/PCB_PAINTER - Classes that uses GAL interface to draw items (as you may have already guessed - PCB_PAINTER is a class for drawing PCB specific object, PAINTER is an abstract class). Its methods are invoked by VIEW, when an item has to be drawn. To display a new type of item - you need to implement draw(ITEM_TYPE*) method that draws it using GAL methods. - STROKE_FONT - Implements stroke font drawing using GAL methods. Most important changes to Kicad original code: * EDA_ITEM now inherits from VIEW_ITEM, which is a base class for all drawable objects. * EDA_DRAW_FRAME contains both usual EDA_DRAW_PANEL and new EDA_DRAW_PANEL_GAL, that can be switched anytime. * There are some new layers for displaying multilayer pads, vias & pads holes (these are not shown yet on the right sidebar in pcbnew) * Display order of layers is different than in previous versions (if you are curious - you may check m_galLayerOrder@pcbnew/basepcbframe.cpp). Preserving usual order would result in not very natural display, such as showing silkscreen texts on the bottom. * Introduced new hotkey (Alt+F12) and new menu option (View->Switch canvas) for switching canvas during runtime. * Some of classes (mostly derived from BOARD_ITEM) now includes ViewBBox & ViewGetLayers methods. * Removed tools/class_painter.h, as now it is extended and included in source code. Build changes: * GAL-based rendering option is turned on by a new compilation CMake option KICAD_GAL. * When compiling with CMake option KICAD_GAL=ON, GLEW and Cairo libraries are required. * GAL-related code is compiled into a static library (common/libgal). * Build with KICAD_GAL=OFF should not need any new libraries and should come out as a standard version of Kicad Currently most of items in pcbnew can be displayed using OpenGL (to be done are DIMENSIONS and MARKERS). More details about GAL can be found in: http://www.ohwr.org/attachments/1884/view-spec.pdf
13 years ago
14 years ago
14 years ago
14 years ago
5 years ago
5 years ago
5 years ago
14 years ago
14 years ago
5 years ago
5 years ago
14 years ago
5 years ago
14 years ago
14 years ago
5 years ago
14 years ago
5 years ago
14 years ago
14 years ago
14 years ago
14 years ago
5 years ago
5 years ago
5 years ago
14 years ago
14 years ago
5 years ago
  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) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License
  9. * as published by the Free Software Foundation; either version 2
  10. * of the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, you may find one here:
  19. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  20. * or you may search the http://www.gnu.org website for the version 2 license,
  21. * or you may write to the Free Software Foundation, Inc.,
  22. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  23. */
  24. #ifndef PAD_H
  25. #define PAD_H
  26. #include <mutex>
  27. #include <zones.h>
  28. #include <board_connected_item.h>
  29. #include <convert_to_biu.h>
  30. #include <geometry/shape_poly_set.h>
  31. #include <geometry/shape_compound.h>
  32. #include <pad_shapes.h>
  33. #include <geometry/eda_angle.h>
  34. class PCB_SHAPE;
  35. class PARAM_CFG;
  36. class SHAPE;
  37. class SHAPE_SEGMENT;
  38. enum CUST_PAD_SHAPE_IN_ZONE
  39. {
  40. CUST_PAD_SHAPE_IN_ZONE_OUTLINE,
  41. CUST_PAD_SHAPE_IN_ZONE_CONVEXHULL
  42. };
  43. class LINE_READER;
  44. class EDA_3D_CANVAS;
  45. class FOOTPRINT;
  46. class FP_SHAPE;
  47. namespace KIGFX
  48. {
  49. class VIEW;
  50. }
  51. class PAD : public BOARD_CONNECTED_ITEM
  52. {
  53. public:
  54. PAD( FOOTPRINT* parent );
  55. // Copy constructor & operator= are needed because the list of basic shapes
  56. // must be duplicated in copy.
  57. PAD( const PAD& aPad );
  58. PAD& operator=( const PAD &aOther );
  59. /*
  60. * Default layers used for pads, according to the pad type.
  61. *
  62. * This is default values only, they can be changed for a given pad.
  63. */
  64. static LSET PTHMask(); ///< layer set for a through hole pad
  65. static LSET SMDMask(); ///< layer set for a SMD pad on Front layer
  66. static LSET ConnSMDMask(); ///< layer set for a SMD pad on Front layer
  67. ///< used for edge board connectors
  68. static LSET UnplatedHoleMask(); ///< layer set for a mechanical unplated through hole pad
  69. static LSET ApertureMask(); ///< layer set for an aperture pad
  70. static inline bool ClassOf( const EDA_ITEM* aItem )
  71. {
  72. return aItem && PCB_PAD_T == aItem->Type();
  73. }
  74. bool IsType( const KICAD_T aScanTypes[] ) const override
  75. {
  76. if( BOARD_CONNECTED_ITEM::IsType( aScanTypes ) )
  77. return true;
  78. for( const KICAD_T* p = aScanTypes; *p != EOT; ++p )
  79. {
  80. if( m_drill.x > 0 && m_drill.y > 0 )
  81. {
  82. if( *p == PCB_LOCATE_HOLE_T )
  83. return true;
  84. else if( *p == PCB_LOCATE_PTH_T && m_attribute != PAD_ATTRIB::NPTH )
  85. return true;
  86. else if( *p == PCB_LOCATE_NPTH_T && m_attribute == PAD_ATTRIB::NPTH )
  87. return true;
  88. }
  89. }
  90. return false;
  91. }
  92. FOOTPRINT* GetParent() const;
  93. wxString GetParentAsString() const { return m_parent->m_Uuid.AsString(); }
  94. bool IsLocked() const override;
  95. /**
  96. * Import the pad settings from \a aMasterPad.
  97. *
  98. * The result is "this" has the same settings (sizes, shapes ... ) as \a aMasterPad.
  99. *
  100. * @param aMasterPad the template pad.
  101. */
  102. void ImportSettingsFrom( const PAD& aMasterPad );
  103. /**
  104. * @return true if the pad has a footprint parent flipped on the back/bottom layer.
  105. */
  106. bool IsFlipped() const;
  107. /**
  108. * Set the pad number (note that it can be alphanumeric, such as the array reference "AA12").
  109. */
  110. void SetNumber( const wxString& aNumber ) { m_number = aNumber; }
  111. const wxString& GetNumber() const { return m_number; }
  112. /**
  113. * Indicates whether or not the pad can have a number. (NPTH and SMD aperture pads can not.)
  114. */
  115. bool CanHaveNumber() const;
  116. /**
  117. * Set the pad function (pin name in schematic)
  118. */
  119. void SetPinFunction( const wxString& aName ) { m_pinFunction = aName; }
  120. const wxString& GetPinFunction() const { return m_pinFunction; }
  121. /**
  122. * Set the pad electrical type
  123. */
  124. void SetPinType( const wxString& aType ) { m_pinType = aType; }
  125. const wxString& GetPinType() const { return m_pinType; }
  126. /**
  127. * Before we had custom pad shapes it was common to have multiple overlapping pads to
  128. * represent a more complex shape.
  129. */
  130. bool SameLogicalPadAs( const PAD* other ) const
  131. {
  132. // hide tricks behind sensible API
  133. return GetParent() == other->GetParent() && m_number == other->m_number;
  134. }
  135. /**
  136. * Set the new shape of this pad.
  137. */
  138. void SetShape( PAD_SHAPE aShape )
  139. {
  140. m_padShape = aShape;
  141. SetDirty();
  142. }
  143. /**
  144. * @return the shape of this pad.
  145. */
  146. PAD_SHAPE GetShape() const { return m_padShape; }
  147. void SetPosition( const VECTOR2I& aPos ) override
  148. {
  149. m_pos = aPos;
  150. SetDirty();
  151. }
  152. VECTOR2I GetPosition() const override { return m_pos; }
  153. /**
  154. * @return the shape of the anchor pad shape, for custom shaped pads.
  155. */
  156. PAD_SHAPE GetAnchorPadShape() const { return m_anchorPadShape; }
  157. /**
  158. * @return the option for the custom pad shape to use as clearance area in copper zones.
  159. */
  160. CUST_PAD_SHAPE_IN_ZONE GetCustomShapeInZoneOpt() const
  161. {
  162. return m_customShapeClearanceArea;
  163. }
  164. /**
  165. * Set the option for the custom pad shape to use as clearance area in copper zones.
  166. *
  167. * @param aOption is the clearance area shape CUST_PAD_SHAPE_IN_ZONE option
  168. */
  169. void SetCustomShapeInZoneOpt( CUST_PAD_SHAPE_IN_ZONE aOption )
  170. {
  171. m_customShapeClearanceArea = aOption;
  172. }
  173. /**
  174. * Set the shape of the anchor pad for custom shaped pads.
  175. *
  176. * @param aShape is the shape of the anchor pad shape( currently, only #PAD_SHAPE::RECT or
  177. * #PAD_SHAPE::CIRCLE.
  178. */
  179. void SetAnchorPadShape( PAD_SHAPE aShape )
  180. {
  181. m_anchorPadShape = ( aShape == PAD_SHAPE::RECT ) ? PAD_SHAPE::RECT : PAD_SHAPE::CIRCLE;
  182. SetDirty();
  183. }
  184. /**
  185. * @return true if the pad is on any copper layer, false otherwise.
  186. */
  187. bool IsOnCopperLayer() const override
  188. {
  189. return ( GetLayerSet() & LSET::AllCuMask() ) != 0;
  190. }
  191. void SetY( int y ) { m_pos.y = y; SetDirty(); }
  192. void SetX( int x ) { m_pos.x = x; SetDirty(); }
  193. void SetPos0( const VECTOR2I& aPos ) { m_pos0 = aPos; }
  194. const VECTOR2I& GetPos0() const { return m_pos0; }
  195. void SetY0( int y ) { m_pos0.y = y; }
  196. void SetX0( int x ) { m_pos0.x = x; }
  197. void SetSize( const VECTOR2I& aSize ) { m_size = aSize; SetDirty(); }
  198. const VECTOR2I& GetSize() const { return m_size; }
  199. void SetSizeX( const int aX ) { m_size.x = aX; SetDirty(); }
  200. const int GetSizeX() const { return m_size.x; }
  201. void SetSizeY( const int aY ) { m_size.y = aY; SetDirty(); }
  202. const int GetSizeY() const { return m_size.y; }
  203. void SetDelta( const VECTOR2I& aSize ) { m_deltaSize = aSize; SetDirty(); }
  204. const VECTOR2I& GetDelta() const { return m_deltaSize; }
  205. void SetDrillSize( const VECTOR2I& aSize ) { m_drill = aSize; SetDirty(); }
  206. const VECTOR2I& GetDrillSize() const { return m_drill; }
  207. void SetDrillSizeX( const int aX ) { m_drill.x = aX; SetDirty(); }
  208. const int GetDrillSizeX() const { return m_drill.x; }
  209. void SetDrillSizeY( const int aY ) { m_drill.y = aY; SetDirty(); }
  210. const int GetDrillSizeY() const { return m_drill.y; }
  211. void SetOffset( const VECTOR2I& aOffset ) { m_offset = aOffset; SetDirty(); }
  212. const VECTOR2I& GetOffset() const { return m_offset; }
  213. VECTOR2I GetCenter() const override { return GetPosition(); }
  214. /**
  215. * Has meaning only for custom shape pads.
  216. * add a free shape to the shape list.
  217. * the shape can be
  218. * - a polygon (outline can have a thickness)
  219. * - a thick segment
  220. * - a filled circle (thickness == 0) or ring
  221. * - a filled rect (thickness == 0) or rectangular outline
  222. * - a arc
  223. * - a bezier curve
  224. */
  225. void AddPrimitivePoly( const SHAPE_POLY_SET& aPoly, int aThickness, bool aFilled );
  226. void AddPrimitivePoly( const std::vector<VECTOR2I>& aPoly, int aThickness, bool aFilled );
  227. void AddPrimitiveSegment( const VECTOR2I& aStart, const VECTOR2I& aEnd, int aThickness );
  228. void AddPrimitiveCircle( const VECTOR2I& aCenter, int aRadius, int aThickness, bool aFilled );
  229. void AddPrimitiveRect( const VECTOR2I& aStart, const VECTOR2I& aEnd, int aThickness,
  230. bool aFilled );
  231. void AddPrimitiveArc( const VECTOR2I& aCenter, const VECTOR2I& aStart,
  232. const EDA_ANGLE& aArcAngle, int aThickness );
  233. void AddPrimitiveCurve( const VECTOR2I& aStart, const VECTOR2I& aEnd, const VECTOR2I& aCtrl1,
  234. const VECTOR2I& aCtrl2, int aThickness );
  235. bool GetBestAnchorPosition( VECTOR2I& aPos );
  236. /**
  237. * Merge all basic shapes to a #SHAPE_POLY_SET.
  238. *
  239. * @note The results are relative to the pad position, orientation 0.
  240. *
  241. * @param aMergedPolygon will store the final polygon
  242. * @param aErrorLoc is used when a circle (or arc) is approximated by segments
  243. * = ERROR_INSIDE to build a polygon inside the arc/circle (usual shape to raw/plot)
  244. * = ERROR_OUIDE to build a polygon outside the arc/circle
  245. * (for instance when building a clearance area)
  246. */
  247. void MergePrimitivesAsPolygon( SHAPE_POLY_SET* aMergedPolygon,
  248. ERROR_LOC aErrorLoc = ERROR_INSIDE ) const;
  249. /**
  250. * Clear the basic shapes list.
  251. */
  252. void DeletePrimitivesList();
  253. /**
  254. * Accessor to the basic shape list for custom-shaped pads.
  255. */
  256. const std::vector<std::shared_ptr<PCB_SHAPE>>& GetPrimitives() const
  257. {
  258. return m_editPrimitives;
  259. }
  260. void Flip( const VECTOR2I& VECTOR2I, bool aFlipLeftRight ) override;
  261. /**
  262. * Flip (mirror) the primitives left to right or top to bottom, around the anchor position
  263. * in custom pads.
  264. */
  265. void FlipPrimitives( bool aFlipLeftRight );
  266. /**
  267. * Clear the current custom shape primitives list and import a new list. Copies the input,
  268. * which is not altered.
  269. */
  270. void ReplacePrimitives( const std::vector<std::shared_ptr<PCB_SHAPE>>& aPrimitivesList );
  271. /**
  272. * Import a custom shape primitive list (composed of basic shapes) and add items to the
  273. * current list. Copies the input, which is not altered.
  274. */
  275. void AppendPrimitives( const std::vector<std::shared_ptr<PCB_SHAPE>>& aPrimitivesList );
  276. /**
  277. * Add item to the custom shape primitives list
  278. */
  279. void AddPrimitive( PCB_SHAPE* aPrimitive );
  280. /**
  281. * Set the rotation angle of the pad.
  282. *
  283. * If \a aAngle is outside of 0 - 360, then it will be normalized.
  284. */
  285. void SetOrientation( const EDA_ANGLE& aAngle );
  286. /**
  287. * Return the rotation angle of the pad.
  288. */
  289. EDA_ANGLE GetOrientation() const { return m_orient; }
  290. // For property system
  291. void SetOrientationDegrees( double aOrientation )
  292. {
  293. SetOrientation( EDA_ANGLE( aOrientation, DEGREES_T ) );
  294. }
  295. double GetOrientationDegrees() const
  296. {
  297. return m_orient.AsDegrees();
  298. }
  299. void SetDrillShape( PAD_DRILL_SHAPE_T aShape ) { m_drillShape = aShape; m_shapesDirty = true; }
  300. PAD_DRILL_SHAPE_T GetDrillShape() const { return m_drillShape; }
  301. bool IsDirty() const
  302. {
  303. return m_shapesDirty || m_polyDirty;
  304. }
  305. void SetDirty()
  306. {
  307. m_shapesDirty = true;
  308. m_polyDirty = true;
  309. }
  310. void SetLayerSet( LSET aLayers ) override { m_layerMask = aLayers; }
  311. LSET GetLayerSet() const override { return m_layerMask; }
  312. void SetAttribute( PAD_ATTRIB aAttribute );
  313. PAD_ATTRIB GetAttribute() const { return m_attribute; }
  314. void SetProperty( PAD_PROP aProperty );
  315. PAD_PROP GetProperty() const { return m_property; }
  316. // We don't currently have an attribute for APERTURE, and adding one will change the file
  317. // format, so for now just infer a copper-less pad to be an APERTURE pad.
  318. bool IsAperturePad() const
  319. {
  320. return ( m_layerMask & LSET::AllCuMask() ).none();
  321. }
  322. void SetPadToDieLength( int aLength ) { m_lengthPadToDie = aLength; }
  323. int GetPadToDieLength() const { return m_lengthPadToDie; }
  324. int GetLocalSolderMaskMargin() const { return m_localSolderMaskMargin; }
  325. void SetLocalSolderMaskMargin( int aMargin ) { m_localSolderMaskMargin = aMargin; }
  326. int GetLocalClearance( wxString* aSource ) const override;
  327. int GetLocalClearance() const { return m_localClearance; }
  328. void SetLocalClearance( int aClearance ) { m_localClearance = aClearance; }
  329. int GetLocalSolderPasteMargin() const { return m_localSolderPasteMargin; }
  330. void SetLocalSolderPasteMargin( int aMargin ) { m_localSolderPasteMargin = aMargin; }
  331. double GetLocalSolderPasteMarginRatio() const { return m_localSolderPasteMarginRatio; }
  332. void SetLocalSolderPasteMarginRatio( double aRatio ) { m_localSolderPasteMarginRatio = aRatio; }
  333. int GetOwnClearance( PCB_LAYER_ID aLayer, wxString* aSource = nullptr ) const override;
  334. /**
  335. * Convert the pad shape to a closed polygon. Circles and arcs are approximated by segments.
  336. *
  337. * @param aCornerBuffer a buffer to store the polygon.
  338. * @param aClearanceValue the clearance around the pad.
  339. * @param aMaxError maximum error from true when converting arcs.
  340. * @param aErrorLoc should the approximation error be placed outside or inside the polygon?
  341. * @param ignoreLineWidth used for edge cuts where the line width is only for visualization.
  342. */
  343. void TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
  344. PCB_LAYER_ID aLayer, int aClearanceValue,
  345. int aMaxError, ERROR_LOC aErrorLoc,
  346. bool ignoreLineWidth = false ) const override;
  347. /**
  348. * Build the corner list of the polygonal drill shape in the board coordinate system.
  349. *
  350. * @param aCornerBuffer a buffer to fill.
  351. * @param aInflateValue the clearance or margin value.
  352. * @param aError maximum deviation of an arc from the polygon approximation.
  353. * @param aErrorLoc = should the approximation error be placed outside or inside the polygon?
  354. * @return false if the pad has no hole, true otherwise.
  355. */
  356. bool TransformHoleWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer, int aInflateValue,
  357. int aError, ERROR_LOC aErrorLoc ) const;
  358. // @copydoc BOARD_ITEM::GetEffectiveShape
  359. virtual std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER,
  360. FLASHING aFlash = FLASHING::DEFAULT ) const override;
  361. const std::shared_ptr<SHAPE_POLY_SET>& GetEffectivePolygon() const;
  362. /**
  363. * Return a SHAPE object representing the pad's hole.
  364. */
  365. const SHAPE_SEGMENT* GetEffectiveHoleShape() const;
  366. /**
  367. * Return the radius of a minimum sized circle which fully encloses this pad.
  368. *
  369. * The center is the pad position NOT THE SHAPE POS!
  370. */
  371. int GetBoundingRadius() const;
  372. /**
  373. * Return any local clearance overrides set in the "classic" (ie: pre-rule) system.
  374. *
  375. * @param aSource [out] optionally reports the source as a user-readable string.
  376. * @return the clearance in internal units.
  377. */
  378. int GetLocalClearanceOverrides( wxString* aSource ) const override;
  379. /**
  380. * @return the expansion for the solder mask layer
  381. *
  382. * Usually > 0 (mask shape bigger than pad). For pads **not** on copper layers, the value
  383. * is the local value because there is no default shape to build. For pads also on copper
  384. * layers, the value (used to build a default shape) is:
  385. * 1 the local value
  386. * 2 if 0, the parent footprint value
  387. * 3 if 0, the global value
  388. */
  389. int GetSolderMaskExpansion() const;
  390. /**
  391. * Usually < 0 (mask shape smaller than pad)because the margin can be dependent on the pad
  392. * size, the margin has a x and a y value. For pads **not** on copper layers, the value is
  393. * the local value because there is no default shape to build. For pads also on copper
  394. * layers, the value (used to build a default shape) is:
  395. * 1 the local value
  396. * 2 if 0, the parent footprint value
  397. * 3 if 0, the global value
  398. *
  399. * @return the margin for the solder mask layer.
  400. */
  401. VECTOR2I GetSolderPasteMargin() const;
  402. void SetZoneConnection( ZONE_CONNECTION aType ) { m_zoneConnection = aType; }
  403. ZONE_CONNECTION GetZoneConnection() const { return m_zoneConnection; }
  404. ZONE_CONNECTION GetLocalZoneConnectionOverride( wxString* aSource = nullptr ) const;
  405. /**
  406. * Set the width of the thermal spokes connecting the pad to a zone. If != 0 this will
  407. * override similar settings in the parent footprint and zone.
  408. */
  409. void SetThermalSpokeWidth( int aWidth ) { m_thermalSpokeWidth = aWidth; }
  410. int GetThermalSpokeWidth() const { return m_thermalSpokeWidth; }
  411. int GetLocalSpokeWidthOverride( wxString* aSource = nullptr ) const;
  412. /**
  413. * The orientation of the thermal spokes. 45° will produce an X (the default for circular
  414. * pads and circular-anchored custom shaped pads), while 90° will produce a + (the default
  415. * for all other shapes).
  416. */
  417. void SetThermalSpokeAngle( const EDA_ANGLE& aAngle ) { m_thermalSpokeAngle = aAngle; }
  418. EDA_ANGLE GetThermalSpokeAngle() const { return m_thermalSpokeAngle; }
  419. // For property system
  420. void SetThermalSpokeAngleDegrees( double aAngle )
  421. {
  422. m_thermalSpokeAngle = EDA_ANGLE( aAngle, DEGREES_T );
  423. }
  424. double GetThermalSpokeAngleDegrees() const
  425. {
  426. return m_thermalSpokeAngle.AsDegrees();
  427. }
  428. void SetThermalGap( int aGap ) { m_thermalGap = aGap; }
  429. int GetThermalGap() const { return m_thermalGap; }
  430. int GetLocalThermalGapOverride( wxString* aSource = nullptr ) const;
  431. /**
  432. * Has meaning only for rounded rectangle pads.
  433. *
  434. * @return The radius of the rounded corners for this pad.
  435. */
  436. void SetRoundRectCornerRadius( double aRadius );
  437. int GetRoundRectCornerRadius() const;
  438. VECTOR2I ShapePos() const;
  439. /**
  440. * Has meaning only for rounded rectangle pads.
  441. *
  442. * Set the ratio between the smaller X or Y size and the rounded corner radius.
  443. * Cannot be > 0.5; the normalized IPC-7351C value is 0.25
  444. */
  445. void SetRoundRectRadiusRatio( double aRadiusScale );
  446. double GetRoundRectRadiusRatio() const { return m_roundedCornerScale; }
  447. /**
  448. * Has meaning only for chamfered rectangular pads.
  449. *
  450. * Set the ratio between the smaller X or Y size and chamfered corner size.
  451. * Cannot be < 0.5.
  452. */
  453. void SetChamferRectRatio( double aChamferScale );
  454. double GetChamferRectRatio() const { return m_chamferScale; }
  455. /**
  456. * Has meaning only for chamfered rectangular pads.
  457. *
  458. * Set the position of the chamfers for orientation 0.
  459. *
  460. * @param aPositions a bit-set of #RECT_CHAMFER_POSITIONS.
  461. */
  462. void SetChamferPositions( int aPositions ) { m_chamferPositions = aPositions; }
  463. int GetChamferPositions() const { return m_chamferPositions; }
  464. /**
  465. * @return the netcode.
  466. */
  467. int GetSubRatsnest() const { return m_subRatsnest; }
  468. void SetSubRatsnest( int aSubRatsnest ) { m_subRatsnest = aSubRatsnest; }
  469. /**
  470. * Set the unconnected removal property.
  471. *
  472. * If true, the copper is removed on zone fill or when specifically requested when the pad
  473. * is not connected on a layer. This requires that there be a through hole.
  474. */
  475. void SetRemoveUnconnected( bool aSet ) { m_removeUnconnectedLayer = aSet; }
  476. bool GetRemoveUnconnected() const { return m_removeUnconnectedLayer; }
  477. /**
  478. * Set whether we keep the top and bottom connections even if they are not connected.
  479. */
  480. void SetKeepTopBottom( bool aSet ) { m_keepTopBottomLayer = aSet; }
  481. bool GetKeepTopBottom() const { return m_keepTopBottomLayer; }
  482. void GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList ) override;
  483. bool IsOnLayer( PCB_LAYER_ID aLayer ) const override
  484. {
  485. return m_layerMask[aLayer];
  486. }
  487. /**
  488. * Check to see whether the pad should be flashed on the specific layer.
  489. *
  490. * @param aLayer Layer to check for connectivity
  491. * @return true if connected by pad or track (or optionally zone)
  492. */
  493. bool FlashLayer( int aLayer ) const;
  494. PCB_LAYER_ID GetLayer() const override;
  495. /**
  496. * @return the principal copper layer for SMD and CONN pads.
  497. */
  498. PCB_LAYER_ID GetPrincipalLayer() const;
  499. /**
  500. * Check to see if the pad should be flashed to any of the layers in the set.
  501. *
  502. * @param aLayers set of layers to check the via against
  503. * @return true if connected by pad or track (or optionally zone) on any of the associated
  504. * layers
  505. */
  506. bool FlashLayer( LSET aLayers ) const;
  507. bool HitTest( const VECTOR2I& aPosition, int aAccuracy = 0 ) const override;
  508. bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override;
  509. wxString GetClass() const override
  510. {
  511. return wxT( "PAD" );
  512. }
  513. /**
  514. * The bounding box is cached, so this will be efficient most of the time.
  515. */
  516. const EDA_RECT GetBoundingBox() const override;
  517. ///< Set absolute coordinates.
  518. void SetDrawCoord();
  519. //todo: Remove SetLocalCoord along with m_pos
  520. ///< Set relative coordinates.
  521. void SetLocalCoord();
  522. /**
  523. * Compare two pads and return 0 if they are equal.
  524. *
  525. * @return less than 0 if left less than right, 0 if equal, or greater than 0 if left
  526. * greater than right.
  527. */
  528. static int Compare( const PAD* aPadRef, const PAD* aPadCmp );
  529. void Move( const VECTOR2I& aMoveVector ) override
  530. {
  531. m_pos += aMoveVector;
  532. SetLocalCoord();
  533. SetDirty();
  534. }
  535. void Rotate( const VECTOR2I& aRotCentre, const EDA_ANGLE& aAngle ) override;
  536. wxString GetSelectMenuText( EDA_UNITS aUnits ) const override;
  537. BITMAPS GetMenuImage() const override;
  538. /**
  539. * @return the GUI-appropriate name of the shape.
  540. */
  541. wxString ShowPadShape() const;
  542. /**
  543. * @return the GUI-appropriate description of the pad type (attribute) : Std, SMD ...
  544. */
  545. wxString ShowPadAttr() const;
  546. EDA_ITEM* Clone() const override;
  547. /**
  548. * Same as Clone, but returns a PAD item.
  549. *
  550. * Useful mainly for python scripts, because Clone returns an EDA_ITEM.
  551. */
  552. PAD* ClonePad() const
  553. {
  554. return (PAD*) Clone();
  555. }
  556. /**
  557. * Rebuild the effective shape cache (and bounding box and radius) for the pad and clears
  558. * the dirty bit.
  559. */
  560. void BuildEffectiveShapes( PCB_LAYER_ID aLayer ) const;
  561. void BuildEffectivePolygon() const;
  562. virtual void ViewGetLayers( int aLayers[], int& aCount ) const override;
  563. double ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const override;
  564. virtual const BOX2I ViewBBox() const override;
  565. virtual void SwapData( BOARD_ITEM* aImage ) override;
  566. #if defined(DEBUG)
  567. virtual void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); }
  568. #endif
  569. private:
  570. void addPadPrimitivesToPolygon( SHAPE_POLY_SET* aMergedPolygon, int aError,
  571. ERROR_LOC aErrorLoc ) const;
  572. private:
  573. wxString m_number; // Pad name (pin number in schematic)
  574. wxString m_pinFunction; // Pin name in schematic
  575. wxString m_pinType; // Pin electrical type in schematic
  576. VECTOR2I m_pos; // Pad Position on board
  577. PAD_SHAPE m_padShape; // Shape: PAD_SHAPE::CIRCLE, PAD_SHAPE::RECT,
  578. // PAD_SHAPE::OVAL, PAD_SHAPE::TRAPEZOID,
  579. // PAD_SHAPE::ROUNDRECT, PAD_SHAPE_POLYGON
  580. /*
  581. * Editing definitions of primitives for custom pad shapes. In local coordinates relative
  582. * to m_Pos (NOT shapePos) at orient 0.
  583. */
  584. std::vector<std::shared_ptr<PCB_SHAPE>> m_editPrimitives;
  585. // Must be set to true to force rebuild shapes to draw (after geometry change for instance)
  586. mutable bool m_shapesDirty;
  587. mutable std::mutex m_shapesBuildingLock;
  588. mutable EDA_RECT m_effectiveBoundingBox;
  589. mutable std::shared_ptr<SHAPE_COMPOUND> m_effectiveShape;
  590. mutable std::shared_ptr<SHAPE_SEGMENT> m_effectiveHoleShape;
  591. mutable bool m_polyDirty;
  592. mutable std::mutex m_polyBuildingLock;
  593. mutable std::shared_ptr<SHAPE_POLY_SET> m_effectivePolygon;
  594. mutable int m_effectiveBoundingRadius;
  595. /*
  596. * How to build the custom shape in zone, to create the clearance area:
  597. * CUST_PAD_SHAPE_IN_ZONE_OUTLINE = use pad shape
  598. * CUST_PAD_SHAPE_IN_ZONE_CONVEXHULL = use the convex hull of the pad shape
  599. */
  600. CUST_PAD_SHAPE_IN_ZONE m_customShapeClearanceArea;
  601. int m_subRatsnest; // Variable used to handle subnet (block) number in
  602. // ratsnest computations
  603. VECTOR2I m_drill; // Drill diameter (x == y) or slot dimensions (x != y)
  604. VECTOR2I m_size; // X and Y size (relative to orient 0)
  605. PAD_DRILL_SHAPE_T m_drillShape; // PAD_DRILL_SHAPE_CIRCLE, PAD_DRILL_SHAPE_OBLONG
  606. double m_roundedCornerScale; // Scaling factor of min(width, height) to corner
  607. // radius, default 0.25
  608. double m_chamferScale; // Scaling factor of min(width, height) to chamfer
  609. // size, default 0.25
  610. int m_chamferPositions; // The positions of the chamfers (at orient 0)
  611. PAD_SHAPE m_anchorPadShape; // For custom shaped pads: shape of pad anchor,
  612. // PAD_SHAPE::RECT, PAD_SHAPE::CIRCLE
  613. /*
  614. * Most of the time the hole is the center of the shape (m_Offset = 0). But some designers
  615. * use oblong/rect pads with a hole moved to one of the oblong/rect pad shape ends.
  616. * In all cases the hole is at the pad position. This offset is from the hole to the center
  617. * of the pad shape (ie: the copper area around the hole).
  618. * ShapePos() returns the board shape position according to the offset and the pad rotation.
  619. */
  620. VECTOR2I m_offset;
  621. LSET m_layerMask; // Bitwise layer: 1 = copper layer, 15 = cmp,
  622. // 2..14 = internal layers, 16..31 = technical layers
  623. VECTOR2I m_deltaSize; // Delta for PAD_SHAPE::TRAPEZOID; half the delta squeezes
  624. // one end and half expands the other. It is only valid
  625. // to have a single axis be non-0.
  626. VECTOR2I m_pos0; // Initial Pad position (i.e. pad position relative to the
  627. // footprint anchor, orientation 0)
  628. PAD_ATTRIB m_attribute; // PAD_ATTRIB_NORMAL, PAD_ATTRIB::SMD, PAD_ATTRIB::CONN,
  629. // PAD_ATTRIB::NPTH
  630. PAD_PROP m_property; // Property in fab files (BGA, FIDUCIAL, TESTPOINT, etc.)
  631. EDA_ANGLE m_orient;
  632. int m_lengthPadToDie; // Length net from pad to die, inside the package
  633. ///< If true, the pad copper is removed for layers that are not connected.
  634. bool m_removeUnconnectedLayer;
  635. ///< When removing unconnected pads, keep the top and bottom pads.
  636. bool m_keepTopBottomLayer;
  637. /*
  638. * Pad clearances, margins, etc. exist in a hierarchy. If a given level is specified then
  639. * the remaining levels are NOT consulted.
  640. *
  641. * LEVEL 1: (highest priority) local overrides (pad, footprint, etc.)
  642. * LEVEL 2: Rules
  643. * LEVEL 3: Accumulated local settings, netclass settings, & board design settings
  644. *
  645. * These are the LEVEL 1 settings for a pad.
  646. */
  647. int m_localClearance;
  648. int m_localSolderMaskMargin; // Local solder mask margin
  649. int m_localSolderPasteMargin; // Local solder paste margin absolute value
  650. double m_localSolderPasteMarginRatio; // Local solder mask margin ratio of pad size
  651. // The final margin is the sum of these 2 values
  652. ZONE_CONNECTION m_zoneConnection; // No connection, thermal relief, etc.
  653. int m_thermalSpokeWidth; // Thermal spoke width.
  654. EDA_ANGLE m_thermalSpokeAngle; // Rotation of the spokes. 45° will produce an X,
  655. // while 90° will produce a +.
  656. int m_thermalGap;
  657. };
  658. #endif // PAD_H