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.

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