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.

878 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
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
14 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-2024 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 <lset.h>
  33. #include <padstack.h>
  34. #include <geometry/eda_angle.h>
  35. #include <geometry/geometry_utils.h>
  36. #include <core/arraydim.h>
  37. class PCB_SHAPE;
  38. class SHAPE;
  39. class SHAPE_SEGMENT;
  40. class LINE_READER;
  41. class EDA_3D_CANVAS;
  42. class FOOTPRINT;
  43. namespace KIGFX
  44. {
  45. class VIEW;
  46. }
  47. class PAD : public BOARD_CONNECTED_ITEM
  48. {
  49. public:
  50. PAD( FOOTPRINT* parent );
  51. // Copy constructor & operator= are needed because the list of basic shapes
  52. // must be duplicated in copy.
  53. PAD( const PAD& aPad );
  54. PAD& operator=( const PAD &aOther );
  55. void Serialize( google::protobuf::Any &aContainer ) const override;
  56. bool Deserialize( const google::protobuf::Any &aContainer ) override;
  57. /*
  58. * Default layers used for pads, according to the pad type.
  59. *
  60. * This is default values only, they can be changed for a given pad.
  61. */
  62. static LSET PTHMask(); ///< layer set for a through hole pad
  63. static LSET SMDMask(); ///< layer set for a SMD pad on Front layer
  64. static LSET ConnSMDMask(); ///< layer set for a SMD pad on Front layer
  65. ///< used for edge board connectors
  66. static LSET UnplatedHoleMask(); ///< layer set for a mechanical unplated through hole pad
  67. static LSET ApertureMask(); ///< layer set for an aperture pad
  68. static inline bool ClassOf( const EDA_ITEM* aItem )
  69. {
  70. return aItem && PCB_PAD_T == aItem->Type();
  71. }
  72. bool IsType( const std::vector<KICAD_T>& aScanTypes ) const override
  73. {
  74. if( BOARD_CONNECTED_ITEM::IsType( aScanTypes ) )
  75. return true;
  76. for( KICAD_T scanType : aScanTypes )
  77. {
  78. if( HasHole() )
  79. {
  80. if( scanType == PCB_LOCATE_HOLE_T )
  81. return true;
  82. else if( scanType == PCB_LOCATE_PTH_T && m_attribute != PAD_ATTRIB::NPTH )
  83. return true;
  84. else if( scanType == PCB_LOCATE_NPTH_T && m_attribute == PAD_ATTRIB::NPTH )
  85. return true;
  86. }
  87. }
  88. return false;
  89. }
  90. bool HasHole() const override
  91. {
  92. return GetDrillSizeX() > 0 && GetDrillSizeY() > 0;
  93. }
  94. bool HasDrilledHole() const override
  95. {
  96. return HasHole() && GetDrillSizeX() == GetDrillSizeY();
  97. }
  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* aOther ) const
  135. {
  136. // hide tricks behind sensible API
  137. return GetParentFootprint() == aOther->GetParentFootprint()
  138. && !m_number.IsEmpty() && m_number == aOther->m_number;
  139. }
  140. /**
  141. * @return true if this and \param aOther represent a net-tie.
  142. */
  143. bool SharesNetTieGroup( const PAD* aOther ) const;
  144. /**
  145. * @return true if the pad is associated with an "unconnected" pin (or a no-connect symbol)
  146. * and has no net.
  147. */
  148. bool IsNoConnectPad() const;
  149. /**
  150. * @return true if the pad is associated with a "free" pin (not-internally-connected) and has
  151. * not yet been assigned another net (ie: by being routed to).
  152. */
  153. bool IsFreePad() const;
  154. /**
  155. * Set the new shape of this pad.
  156. */
  157. void SetShape( PAD_SHAPE aShape )
  158. {
  159. m_padStack.SetShape( aShape );
  160. SetDirty();
  161. }
  162. /**
  163. * @return the shape of this pad.
  164. */
  165. PAD_SHAPE GetShape() const { return m_padStack.Shape(); }
  166. void SetPosition( const VECTOR2I& aPos ) override
  167. {
  168. m_pos = aPos;
  169. SetDirty();
  170. }
  171. VECTOR2I GetPosition() const override { return m_pos; }
  172. /**
  173. * @return the shape of the anchor pad shape, for custom shaped pads.
  174. */
  175. PAD_SHAPE GetAnchorPadShape() const
  176. {
  177. return m_padStack.AnchorShape();
  178. }
  179. /**
  180. * @return the option for the custom pad shape to use as clearance area in copper zones.
  181. */
  182. PADSTACK::CUSTOM_SHAPE_ZONE_MODE GetCustomShapeInZoneOpt() const
  183. {
  184. return m_padStack.CustomShapeInZoneMode();
  185. }
  186. /**
  187. * Set the option for the custom pad shape to use as clearance area in copper zones.
  188. *
  189. * @param aOption is the clearance area shape CUST_PAD_SHAPE_IN_ZONE option
  190. */
  191. void SetCustomShapeInZoneOpt( PADSTACK::CUSTOM_SHAPE_ZONE_MODE aOption )
  192. {
  193. m_padStack.SetCustomShapeInZoneMode( aOption );
  194. }
  195. /**
  196. * Set the shape of the anchor pad for custom shaped pads.
  197. *
  198. * @param aShape is the shape of the anchor pad shape( currently, only #PAD_SHAPE::RECTANGLE or
  199. * #PAD_SHAPE::CIRCLE.
  200. */
  201. void SetAnchorPadShape( PAD_SHAPE aShape )
  202. {
  203. m_padStack.SetAnchorShape( aShape == PAD_SHAPE::RECTANGLE
  204. ? PAD_SHAPE::RECTANGLE
  205. : PAD_SHAPE::CIRCLE );
  206. SetDirty();
  207. }
  208. /**
  209. * @return true if the pad is on any copper layer, false otherwise.
  210. */
  211. bool IsOnCopperLayer() const override;
  212. void SetY( int y ) { m_pos.y = y; SetDirty(); }
  213. void SetX( int x ) { m_pos.x = x; SetDirty(); }
  214. void SetSize( const VECTOR2I& aSize )
  215. {
  216. m_padStack.Size() = aSize;
  217. SetDirty();
  218. }
  219. const VECTOR2I& GetSize() const { return m_padStack.Size(); }
  220. void SetSizeX( const int aX ) { if( aX > 0 ) { m_padStack.Size().x = aX; SetDirty(); } }
  221. int GetSizeX() const { return m_padStack.Size().x; }
  222. void SetSizeY( const int aY ) { if( aY > 0 ) { m_padStack.Size().y = aY; SetDirty(); } }
  223. int GetSizeY() const { return m_padStack.Size().y; }
  224. void SetDelta( const VECTOR2I& aSize ) { m_padStack.TrapezoidDeltaSize() = aSize; SetDirty(); }
  225. const VECTOR2I& GetDelta() const { return m_padStack.TrapezoidDeltaSize(); }
  226. void SetDrillSize( const VECTOR2I& aSize ) { m_padStack.Drill().size = aSize; SetDirty(); }
  227. const VECTOR2I& GetDrillSize() const { return m_padStack.Drill().size; }
  228. void SetDrillSizeX( const int aX );
  229. int GetDrillSizeX() const { return m_padStack.Drill().size.x; }
  230. void SetDrillSizeY( const int aY ) { m_padStack.Drill().size.y = aY; SetDirty(); }
  231. int GetDrillSizeY() const { return m_padStack.Drill().size.y; }
  232. void SetOffset( const VECTOR2I& aOffset ) { m_padStack.Offset() = aOffset; SetDirty(); }
  233. const VECTOR2I& GetOffset() const { return m_padStack.Offset(); }
  234. VECTOR2I GetCenter() const override { return GetPosition(); }
  235. const PADSTACK& Padstack() const { return m_padStack; }
  236. PADSTACK& Padstack() { return m_padStack; }
  237. void SetPadstack( const PADSTACK& aPadstack ) { m_padStack = aPadstack; }
  238. /**
  239. * Has meaning only for custom shape pads.
  240. * add a free shape to the shape list.
  241. * the shape can be
  242. * - a polygon (outline can have a thickness)
  243. * - a thick segment
  244. * - a filled circle (thickness == 0) or ring
  245. * - a filled rect (thickness == 0) or rectangular outline
  246. * - a arc
  247. * - a bezier curve
  248. */
  249. void AddPrimitivePoly( const SHAPE_POLY_SET& aPoly, int aThickness, bool aFilled );
  250. void AddPrimitivePoly( const std::vector<VECTOR2I>& aPoly, int aThickness, bool aFilled );
  251. /**
  252. * Merge all basic shapes to a #SHAPE_POLY_SET.
  253. *
  254. * @note The results are relative to the pad position, orientation 0.
  255. *
  256. * @param aMergedPolygon will store the final polygon
  257. * @param aErrorLoc is used when a circle (or arc) is approximated by segments
  258. * = ERROR_INSIDE to build a polygon inside the arc/circle (usual shape to raw/plot)
  259. * = ERROR_OUIDE to build a polygon outside the arc/circle
  260. * (for instance when building a clearance area)
  261. */
  262. void MergePrimitivesAsPolygon( SHAPE_POLY_SET* aMergedPolygon,
  263. ERROR_LOC aErrorLoc = ERROR_INSIDE ) const;
  264. /**
  265. * Clear the basic shapes list.
  266. */
  267. void DeletePrimitivesList();
  268. /**
  269. * Accessor to the basic shape list for custom-shaped pads.
  270. */
  271. const std::vector<std::shared_ptr<PCB_SHAPE>>& GetPrimitives() const
  272. {
  273. return m_padStack.Primitives();
  274. }
  275. void Flip( const VECTOR2I& VECTOR2I, bool aFlipLeftRight ) override;
  276. /**
  277. * Flip (mirror) the primitives left to right or top to bottom, around the anchor position
  278. * in custom pads.
  279. */
  280. void FlipPrimitives( bool aFlipLeftRight );
  281. /**
  282. * Clear the current custom shape primitives list and import a new list. Copies the input,
  283. * which is not altered.
  284. */
  285. void ReplacePrimitives( const std::vector<std::shared_ptr<PCB_SHAPE>>& aPrimitivesList );
  286. /**
  287. * Import a custom shape primitive list (composed of basic shapes) and add items to the
  288. * current list. Copies the input, which is not altered.
  289. */
  290. void AppendPrimitives( const std::vector<std::shared_ptr<PCB_SHAPE>>& aPrimitivesList );
  291. /**
  292. * Add item to the custom shape primitives list
  293. */
  294. void AddPrimitive( PCB_SHAPE* aPrimitive );
  295. /**
  296. * Set the rotation angle of the pad.
  297. *
  298. * If \a aAngle is outside of 0 - 360, then it will be normalized.
  299. */
  300. void SetOrientation( const EDA_ANGLE& aAngle );
  301. void SetFPRelativeOrientation( const EDA_ANGLE& aAngle );
  302. /**
  303. * Return the rotation angle of the pad.
  304. */
  305. EDA_ANGLE GetOrientation() const { return m_padStack.GetOrientation(); }
  306. EDA_ANGLE GetFPRelativeOrientation() const;
  307. // For property system
  308. void SetOrientationDegrees( double aOrientation )
  309. {
  310. SetOrientation( EDA_ANGLE( aOrientation, DEGREES_T ) );
  311. }
  312. double GetOrientationDegrees() const
  313. {
  314. return m_padStack.GetOrientation().AsDegrees();
  315. }
  316. void SetDrillShape( PAD_DRILL_SHAPE aShape );
  317. PAD_DRILL_SHAPE GetDrillShape() const { return m_padStack.Drill().shape; }
  318. bool IsDirty() const
  319. {
  320. return m_shapesDirty || m_polyDirty[ERROR_INSIDE] || m_polyDirty[ERROR_OUTSIDE];
  321. }
  322. void SetDirty()
  323. {
  324. m_shapesDirty = true;
  325. m_polyDirty[ERROR_INSIDE] = true;
  326. m_polyDirty[ERROR_OUTSIDE] = true;
  327. }
  328. void SetLayerSet( const LSET& aLayers ) override { m_padStack.SetLayerSet( aLayers ); }
  329. LSET GetLayerSet() const override { return m_padStack.LayerSet(); }
  330. void SetAttribute( PAD_ATTRIB aAttribute );
  331. PAD_ATTRIB GetAttribute() const { return m_attribute; }
  332. void SetProperty( PAD_PROP aProperty );
  333. PAD_PROP GetProperty() const { return m_property; }
  334. // We don't currently have an attribute for APERTURE, and adding one will change the file
  335. // format, so for now just infer a copper-less pad to be an APERTURE pad.
  336. bool IsAperturePad() const
  337. {
  338. return ( m_padStack.LayerSet() & LSET::AllCuMask() ).none();
  339. }
  340. void SetPadToDieLength( int aLength ) { m_lengthPadToDie = aLength; }
  341. int GetPadToDieLength() const { return m_lengthPadToDie; }
  342. std::optional<int> GetLocalClearance() const override { return m_padStack.Clearance(); }
  343. void SetLocalClearance( std::optional<int> aClearance ) { m_padStack.Clearance() = aClearance; }
  344. std::optional<int> GetLocalSolderMaskMargin() const { return m_padStack.SolderMaskMargin(); }
  345. void SetLocalSolderMaskMargin( std::optional<int> aMargin )
  346. {
  347. m_padStack.SolderMaskMargin() = aMargin;
  348. }
  349. std::optional<int> GetLocalSolderPasteMargin() const { return m_padStack.SolderPasteMargin(); }
  350. void SetLocalSolderPasteMargin( std::optional<int> aMargin )
  351. {
  352. m_padStack.SolderPasteMargin() = aMargin;
  353. }
  354. std::optional<double> GetLocalSolderPasteMarginRatio() const
  355. {
  356. return m_padStack.SolderPasteMarginRatio();
  357. }
  358. void SetLocalSolderPasteMarginRatio( std::optional<double> aRatio )
  359. {
  360. m_padStack.SolderPasteMarginRatio() = aRatio;
  361. }
  362. void SetLocalZoneConnection( ZONE_CONNECTION aType ) { m_padStack.ZoneConnection() = aType; }
  363. ZONE_CONNECTION GetLocalZoneConnection() const
  364. {
  365. return m_padStack.ZoneConnection().value_or( ZONE_CONNECTION::INHERITED );
  366. }
  367. /**
  368. * Return the pad's "own" clearance in internal units.
  369. *
  370. * @param aLayer the layer in question.
  371. * @param aSource [out] optionally reports the source as a user-readable string.
  372. * @return the clearance in internal units.
  373. */
  374. int GetOwnClearance( PCB_LAYER_ID aLayer, wxString* aSource = nullptr ) const override;
  375. /**
  376. * Convert the pad shape to a closed polygon. Circles and arcs are approximated by segments.
  377. *
  378. * @param aBuffer a buffer to store the polygon.
  379. * @param aClearance the clearance around the pad.
  380. * @param aMaxError maximum error from true when converting arcs.
  381. * @param aErrorLoc should the approximation error be placed outside or inside the polygon?
  382. * @param ignoreLineWidth used for edge cuts where the line width is only for visualization.
  383. */
  384. void TransformShapeToPolygon( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aLayer, int aClearance,
  385. int aMaxError, ERROR_LOC aErrorLoc = ERROR_INSIDE,
  386. bool ignoreLineWidth = false ) const override;
  387. /**
  388. * Build the corner list of the polygonal drill shape in the board coordinate system.
  389. *
  390. * @param aBuffer a buffer to fill.
  391. * @param aClearance the clearance or margin value.
  392. * @param aError maximum deviation of an arc from the polygon approximation.
  393. * @param aErrorLoc = should the approximation error be placed outside or inside the polygon?
  394. * @return false if the pad has no hole, true otherwise.
  395. */
  396. bool TransformHoleToPolygon( SHAPE_POLY_SET& aBuffer, int aClearance, int aError,
  397. ERROR_LOC aErrorLoc = ERROR_INSIDE ) const;
  398. /**
  399. * Some pad shapes can be complex (rounded/chamfered rectangle), even without considering
  400. * custom shapes. This routine returns a COMPOUND shape (set of simple shapes which make
  401. * up the pad for use with routing, collision determination, etc).
  402. *
  403. * @note This list can contain a SHAPE_SIMPLE (a simple single-outline non-intersecting
  404. * polygon), but should never contain a SHAPE_POLY_SET (a complex polygon consisting of
  405. * multiple outlines and/or holes).
  406. *
  407. * @param aLayer optional parameter allowing a caller to specify a particular layer (default
  408. * is to return the pad's "natural" shape).
  409. * @param aFlash optional parameter allowing a caller to force the pad to be flashed (or not
  410. * flashed) on the current layer (default is to honour the pad's setting and
  411. * the current connections for the given layer).
  412. */
  413. virtual std::shared_ptr<SHAPE>
  414. GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER,
  415. FLASHING flashPTHPads = FLASHING::DEFAULT ) const override;
  416. const std::shared_ptr<SHAPE_POLY_SET>& GetEffectivePolygon( ERROR_LOC aErrorLoc = ERROR_INSIDE ) const;
  417. /**
  418. * Return a SHAPE_SEGMENT object representing the pad's hole.
  419. */
  420. std::shared_ptr<SHAPE_SEGMENT> GetEffectiveHoleShape() const override;
  421. /**
  422. * Return the radius of a minimum sized circle which fully encloses this pad.
  423. *
  424. * The center is the pad position NOT THE SHAPE POS!
  425. */
  426. int GetBoundingRadius() const;
  427. /**
  428. * Return any local clearance overrides set in the "classic" (ie: pre-rule) system.
  429. *
  430. * @param aSource [out] optionally reports the source as a user-readable string.
  431. * @return the clearance in internal units.
  432. */
  433. std::optional<int> GetLocalClearance( wxString* aSource ) const override;
  434. /**
  435. * Return any clearance overrides set in the "classic" (ie: pre-rule) system.
  436. *
  437. * @param aSource [out] optionally reports the source as a user-readable string.
  438. * @return the clearance in internal units.
  439. */
  440. std::optional<int> GetClearanceOverrides( wxString* aSource ) const override;
  441. /**
  442. * @return the expansion for the solder mask layer
  443. *
  444. * Usually > 0 (mask shape bigger than pad). For pads **not** on copper layers, the value
  445. * is the local value because there is no default shape to build. For pads also on copper
  446. * layers, the value (used to build a default shape) is:
  447. * 1 the local value
  448. * 2 if 0, the parent footprint value
  449. * 3 if 0, the global value
  450. */
  451. int GetSolderMaskExpansion() const;
  452. /**
  453. * Usually < 0 (mask shape smaller than pad)because the margin can be dependent on the pad
  454. * size, the margin has a x and a y value. For pads **not** on copper layers, the value is
  455. * the local value because there is no default shape to build. For pads also on copper
  456. * layers, the value (used to build a default shape) is:
  457. * 1 the local value
  458. * 2 if 0, the parent footprint value
  459. * 3 if 0, the global value
  460. *
  461. * @return the margin for the solder mask layer.
  462. */
  463. VECTOR2I GetSolderPasteMargin() const;
  464. ZONE_CONNECTION GetZoneConnectionOverrides( wxString* aSource = nullptr ) const;
  465. /**
  466. * Set the width of the thermal spokes connecting the pad to a zone. If != 0 this will
  467. * override similar settings in the parent footprint and zone.
  468. */
  469. void SetThermalSpokeWidth( int aWidth ) { m_padStack.ThermalSpokeWidth() = aWidth; }
  470. int GetThermalSpokeWidth() const { return m_padStack.ThermalSpokeWidth().value_or( 0 ); }
  471. int GetLocalSpokeWidthOverride( wxString* aSource = nullptr ) const;
  472. /**
  473. * The orientation of the thermal spokes. 45° will produce an X (the default for circular
  474. * pads and circular-anchored custom shaped pads), while 90° will produce a + (the default
  475. * for all other shapes).
  476. */
  477. void SetThermalSpokeAngle( const EDA_ANGLE& aAngle )
  478. {
  479. m_padStack.SetThermalSpokeAngle( aAngle );
  480. }
  481. EDA_ANGLE GetThermalSpokeAngle() const
  482. {
  483. return m_padStack.ThermalSpokeAngle();
  484. }
  485. // For property system
  486. void SetThermalSpokeAngleDegrees( double aAngle )
  487. {
  488. m_padStack.SetThermalSpokeAngle( EDA_ANGLE( aAngle, DEGREES_T ) );
  489. }
  490. double GetThermalSpokeAngleDegrees() const
  491. {
  492. return m_padStack.ThermalSpokeAngle().AsDegrees();
  493. }
  494. void SetThermalGap( int aGap ) { m_padStack.ThermalGap() = aGap; }
  495. int GetThermalGap() const { return m_padStack.ThermalGap().value_or( 0 ); }
  496. int GetLocalThermalGapOverride( wxString* aSource = nullptr ) const;
  497. /**
  498. * Has meaning only for rounded rectangle pads.
  499. *
  500. * @return The radius of the rounded corners for this pad.
  501. */
  502. void SetRoundRectCornerRadius( double aRadius );
  503. int GetRoundRectCornerRadius() const;
  504. VECTOR2I ShapePos() const;
  505. /**
  506. * Has meaning only for rounded rectangle pads.
  507. *
  508. * Set the ratio between the smaller X or Y size and the rounded corner radius.
  509. * Cannot be > 0.5; the normalized IPC-7351C value is 0.25
  510. */
  511. void SetRoundRectRadiusRatio( double aRadiusScale );
  512. double GetRoundRectRadiusRatio() const { return m_padStack.RoundRectRadiusRatio(); }
  513. /**
  514. * Has meaning only for chamfered rectangular pads.
  515. *
  516. * Set the ratio between the smaller X or Y size and chamfered corner size.
  517. * Cannot be < 0.5.
  518. */
  519. void SetChamferRectRatio( double aChamferScale );
  520. double GetChamferRectRatio() const { return m_padStack.ChamferRatio(); }
  521. /**
  522. * Has meaning only for chamfered rectangular pads.
  523. *
  524. * Set the position of the chamfers for orientation 0.
  525. *
  526. * @param aPositions a bit-set of #RECT_CHAMFER_POSITIONS.
  527. */
  528. void SetChamferPositions( int aPositions ) { m_padStack.SetChamferPositions( aPositions ); }
  529. int GetChamferPositions() const { return m_padStack.ChamferPositions(); }
  530. /**
  531. * @return the netcode.
  532. */
  533. int GetSubRatsnest() const { return m_subRatsnest; }
  534. void SetSubRatsnest( int aSubRatsnest ) { m_subRatsnest = aSubRatsnest; }
  535. /**
  536. * @deprecated - use Padstack().SetUnconnectedLayerMode()
  537. * Sets the unconnected removal property. If true, the copper is removed on zone fill
  538. * or when specifically requested when the via is not connected on a layer.
  539. */
  540. void SetRemoveUnconnected( bool aSet )
  541. {
  542. m_padStack.SetUnconnectedLayerMode( aSet
  543. ? PADSTACK::UNCONNECTED_LAYER_MODE::REMOVE_ALL
  544. : PADSTACK::UNCONNECTED_LAYER_MODE::KEEP_ALL );
  545. }
  546. bool GetRemoveUnconnected() const
  547. {
  548. return m_padStack.UnconnectedLayerMode() != PADSTACK::UNCONNECTED_LAYER_MODE::KEEP_ALL;
  549. }
  550. /**
  551. * @deprecated - use Padstack().SetUnconnectedLayerMode()
  552. * Sets whether we keep the start and end annular rings even if they are not connected
  553. */
  554. void SetKeepTopBottom( bool aSet )
  555. {
  556. m_padStack.SetUnconnectedLayerMode( aSet
  557. ? PADSTACK::UNCONNECTED_LAYER_MODE::REMOVE_EXCEPT_START_AND_END
  558. : PADSTACK::UNCONNECTED_LAYER_MODE::REMOVE_ALL );
  559. }
  560. bool GetKeepTopBottom() const
  561. {
  562. return m_padStack.UnconnectedLayerMode()
  563. == PADSTACK::UNCONNECTED_LAYER_MODE::REMOVE_EXCEPT_START_AND_END;
  564. }
  565. void SetUnconnectedLayerMode( PADSTACK::UNCONNECTED_LAYER_MODE aMode )
  566. {
  567. m_padStack.SetUnconnectedLayerMode( aMode );
  568. }
  569. PADSTACK::UNCONNECTED_LAYER_MODE GetUnconnectedLayerMode() const
  570. {
  571. return m_padStack.UnconnectedLayerMode();
  572. }
  573. bool ConditionallyFlashed( PCB_LAYER_ID aLayer ) const
  574. {
  575. switch( m_padStack.UnconnectedLayerMode() )
  576. {
  577. case PADSTACK::UNCONNECTED_LAYER_MODE::KEEP_ALL:
  578. return false;
  579. case PADSTACK::UNCONNECTED_LAYER_MODE::REMOVE_ALL:
  580. return true;
  581. case PADSTACK::UNCONNECTED_LAYER_MODE::REMOVE_EXCEPT_START_AND_END:
  582. {
  583. if( aLayer == m_padStack.Drill().start || aLayer == m_padStack.Drill().end )
  584. return false;
  585. }
  586. }
  587. return true;
  588. }
  589. void GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList ) override;
  590. bool IsOnLayer( PCB_LAYER_ID aLayer ) const override
  591. {
  592. return m_padStack.LayerSet().test( aLayer );
  593. }
  594. /**
  595. * Check to see whether the pad should be flashed on the specific layer.
  596. *
  597. * @param aLayer Layer to check for connectivity
  598. * @param aOnlyCheckIfPermitted indicates that the routine should just return whether or not
  599. * a flashed connection is permitted on this layer (without checking for a connection)
  600. * @return true if connected by pad or track (or optionally zone)
  601. */
  602. bool FlashLayer( int aLayer, bool aOnlyCheckIfPermitted = false ) const;
  603. bool CanFlashLayer( int aLayer )
  604. {
  605. return FlashLayer( aLayer, true );
  606. }
  607. PCB_LAYER_ID GetLayer() const override;
  608. /**
  609. * @return the principal copper layer for SMD and CONN pads.
  610. */
  611. PCB_LAYER_ID GetPrincipalLayer() const;
  612. /**
  613. * Check to see if the pad should be flashed to any of the layers in the set.
  614. *
  615. * @param aLayers set of layers to check the via against
  616. * @return true if connected by pad or track (or optionally zone) on any of the associated
  617. * layers
  618. */
  619. bool FlashLayer( LSET aLayers ) const;
  620. bool HitTest( const VECTOR2I& aPosition, int aAccuracy = 0 ) const override;
  621. bool HitTest( const BOX2I& aRect, bool aContained, int aAccuracy = 0 ) const override;
  622. /**
  623. * Recombines the pad with other graphical shapes in the footprint
  624. *
  625. * @param aIsDryRun if true, the pad will not be recombined but the operation will still be logged
  626. * @param aMaxError the maximum error to allow for converting arcs to polygons
  627. * @return a list of shapes that were recombined
  628. */
  629. std::vector<PCB_SHAPE*> Recombine( bool aIsDryRun, int aMaxError );
  630. wxString GetClass() const override
  631. {
  632. return wxT( "PAD" );
  633. }
  634. /**
  635. * The bounding box is cached, so this will be efficient most of the time.
  636. */
  637. const BOX2I GetBoundingBox() const override;
  638. /**
  639. * Compare two pads and return 0 if they are equal.
  640. *
  641. * @return less than 0 if left less than right, 0 if equal, or greater than 0 if left
  642. * greater than right.
  643. */
  644. static int Compare( const PAD* aPadRef, const PAD* aPadCmp );
  645. void Move( const VECTOR2I& aMoveVector ) override
  646. {
  647. m_pos += aMoveVector;
  648. SetDirty();
  649. }
  650. void Rotate( const VECTOR2I& aRotCentre, const EDA_ANGLE& aAngle ) override;
  651. wxString GetItemDescription( UNITS_PROVIDER* aUnitsProvider, bool aFull ) const override;
  652. BITMAPS GetMenuImage() const override;
  653. /**
  654. * @return the GUI-appropriate name of the shape.
  655. */
  656. wxString ShowPadShape() const;
  657. /**
  658. * @return the GUI-appropriate description of the pad type (attribute) : Std, SMD ...
  659. */
  660. wxString ShowPadAttr() const;
  661. EDA_ITEM* Clone() const override;
  662. /**
  663. * Same as Clone, but returns a PAD item.
  664. *
  665. * Useful mainly for python scripts, because Clone returns an EDA_ITEM.
  666. */
  667. PAD* ClonePad() const
  668. {
  669. return (PAD*) Clone();
  670. }
  671. /**
  672. * Rebuild the effective shape cache (and bounding box and radius) for the pad and clears
  673. * the dirty bit.
  674. */
  675. void BuildEffectiveShapes( PCB_LAYER_ID aLayer ) const;
  676. void BuildEffectivePolygon( ERROR_LOC aErrorLoc = ERROR_INSIDE ) const;
  677. virtual void ViewGetLayers( int aLayers[], int& aCount ) const override;
  678. double ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const override;
  679. virtual const BOX2I ViewBBox() const override;
  680. void ClearZoneLayerOverrides()
  681. {
  682. m_zoneLayerOverrides.fill( ZLO_NONE );
  683. }
  684. const ZONE_LAYER_OVERRIDE& GetZoneLayerOverride( PCB_LAYER_ID aLayer ) const
  685. {
  686. return m_zoneLayerOverrides.at( aLayer );
  687. }
  688. void SetZoneLayerOverride( PCB_LAYER_ID aLayer, ZONE_LAYER_OVERRIDE aOverride )
  689. {
  690. std::unique_lock<std::mutex> cacheLock( m_zoneLayerOverridesMutex );
  691. m_zoneLayerOverrides.at( aLayer ) = aOverride;
  692. }
  693. void CheckPad( UNITS_PROVIDER* aUnitsProvider,
  694. const std::function<void( int aErrorCode,
  695. const wxString& aMsg )>& aErrorHandler ) const;
  696. double Similarity( const BOARD_ITEM& aOther ) const override;
  697. bool operator==( const PAD& aOther ) const;
  698. bool operator==( const BOARD_ITEM& aBoardItem ) const override;
  699. #if defined(DEBUG)
  700. virtual void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); }
  701. #endif
  702. protected:
  703. virtual void swapData( BOARD_ITEM* aImage ) override;
  704. private:
  705. void addPadPrimitivesToPolygon( SHAPE_POLY_SET* aMergedPolygon, int aError,
  706. ERROR_LOC aErrorLoc ) const;
  707. private:
  708. wxString m_number; // Pad name (pin number in schematic)
  709. wxString m_pinFunction; // Pin name in schematic
  710. wxString m_pinType; // Pin electrical type in schematic
  711. VECTOR2I m_pos; // Pad Position on board
  712. PADSTACK m_padStack;
  713. // Must be set to true to force rebuild shapes to draw (after geometry change for instance)
  714. mutable bool m_shapesDirty;
  715. mutable std::mutex m_shapesBuildingLock;
  716. mutable BOX2I m_effectiveBoundingBox;
  717. mutable std::shared_ptr<SHAPE_COMPOUND> m_effectiveShape;
  718. mutable std::shared_ptr<SHAPE_SEGMENT> m_effectiveHoleShape;
  719. mutable bool m_polyDirty[2];
  720. mutable std::mutex m_polyBuildingLock;
  721. mutable std::shared_ptr<SHAPE_POLY_SET> m_effectivePolygon[2];
  722. mutable int m_effectiveBoundingRadius;
  723. int m_subRatsnest; // Variable used to handle subnet (block) number in
  724. // ratsnest computations
  725. PAD_ATTRIB m_attribute = PAD_ATTRIB::PTH;
  726. PAD_PROP m_property; // Property in fab files (BGA, FIDUCIAL, TESTPOINT, etc.)
  727. int m_lengthPadToDie; // Length net from pad to die, inside the package
  728. std::mutex m_zoneLayerOverridesMutex;
  729. std::array<ZONE_LAYER_OVERRIDE, MAX_CU_LAYERS> m_zoneLayerOverrides;
  730. };
  731. #endif // PAD_H