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.

970 lines
34 KiB

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