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.

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