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.

472 lines
18 KiB

18 years ago
18 years ago
14 years ago
4 years ago
14 years ago
14 years ago
4 years ago
14 years ago
18 years ago
14 years ago
14 years ago
14 years ago
14 years ago
18 years ago
4 years ago
  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2024 Jon Evans <jon@craftyjon.com>
  5. * Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors.
  6. *
  7. * This program is free software: you can redistribute it and/or modify it
  8. * under the terms of the GNU General Public License as published by the
  9. * Free Software Foundation, either version 3 of the License, or (at your
  10. * option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful, but
  13. * WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License along
  18. * with this program. If not, see <http://www.gnu.org/licenses/>.
  19. */
  20. #ifndef KICAD_PADSTACK_H
  21. #define KICAD_PADSTACK_H
  22. #include <memory>
  23. #include <optional>
  24. #include <wx/string.h>
  25. #include <api/serializable.h>
  26. #include <geometry/eda_angle.h>
  27. #include <layer_ids.h>
  28. #include <lset.h>
  29. #include <math/vector2d.h>
  30. #include <properties/property.h>
  31. #include <zones.h>
  32. class BOARD_ITEM;
  33. class PCB_SHAPE;
  34. /**
  35. * The set of pad shapes, used with PAD::{Set,Get}Shape()
  36. *
  37. * --> DO NOT REORDER, PCB_IO_KICAD_LEGACY is dependent on the integer values <--
  38. */
  39. enum class PAD_SHAPE : int
  40. {
  41. CIRCLE,
  42. RECTANGLE, // do not use just RECT: it collides in a header on MSYS2
  43. OVAL,
  44. TRAPEZOID,
  45. ROUNDRECT,
  46. // Rectangle with a chamfered corner ( and with rounded other corners).
  47. CHAMFERED_RECT,
  48. CUSTOM // A shape defined by user, using a set of basic shapes
  49. // (thick segments, circles, arcs, polygons).
  50. };
  51. /**
  52. * The set of pad drill shapes, used with PAD::{Set,Get}DrillShape()
  53. */
  54. enum class PAD_DRILL_SHAPE
  55. {
  56. UNDEFINED,
  57. CIRCLE,
  58. OBLONG,
  59. };
  60. /**
  61. * The set of pad shapes, used with PAD::{Set,Get}Attribute().
  62. *
  63. * The double name is for convenience of Python devs
  64. */
  65. enum class PAD_ATTRIB
  66. {
  67. PTH, ///< Plated through hole pad
  68. SMD, ///< Smd pad, appears on the solder paste layer (default)
  69. CONN, ///< Like smd, does not appear on the solder paste layer (default)
  70. ///< Note: also has a special attribute in Gerber X files
  71. ///< Used for edgecard connectors for instance
  72. NPTH, ///< like PAD_PTH, but not plated
  73. ///< mechanical use only, no connection allowed
  74. };
  75. /**
  76. * The set of pad properties used in Gerber files (Draw files, and P&P files)
  77. * to define some properties in fabrication or test files. Also used by
  78. * DRC to check some properties.
  79. */
  80. enum class PAD_PROP
  81. {
  82. NONE, ///< no special fabrication property
  83. BGA, ///< Smd pad, used in BGA footprints
  84. FIDUCIAL_GLBL, ///< a fiducial (usually a smd) for the full board
  85. FIDUCIAL_LOCAL, ///< a fiducial (usually a smd) local to the parent footprint
  86. TESTPOINT, ///< a test point pad
  87. HEATSINK, ///< a pad used as heat sink, usually in SMD footprints
  88. CASTELLATED, ///< a pad with a castellated through hole
  89. MECHANICAL, ///< a pad used for mechanical support
  90. };
  91. /**
  92. * A PADSTACK defines the characteristics of a single or multi-layer pad, in the IPC sense of
  93. * the word. This means that a PCB_PAD has a padstack, but also a PCB_VIA. The padstack for
  94. * a pad defines its geometry on copper, soldermask, and paste layers, as well as any drilling
  95. * or milling associated with the pad (round or slot hole, back-drilling, etc). Padstacks also
  96. * define thermal relief settings for all copper layers, clearance overrides for all copper
  97. * layers, and potentially other properties in the future. In other words, the padstack defines
  98. * most of the geometric features of a pad on all layers. It does not define electrical properties
  99. * or other metadata.
  100. *
  101. * For padstacks that do not vary between layers, F_Cu is used as the copper layer to store all
  102. * padstack properties.
  103. */
  104. class PADSTACK : public SERIALIZABLE
  105. {
  106. public:
  107. ///! Padstack type, mostly for IPC-7351 naming and attributes
  108. ///! Note that TYPE::MOUNTING is probably not currently supported by KiCad
  109. enum class TYPE
  110. {
  111. NORMAL, ///< Padstack for a footprint pad
  112. VIA, ///< Padstack for a via
  113. MOUNTING ///< A mounting hole (plated or unplated, not associated with a footprint)
  114. };
  115. ///! Copper geometry mode: controls how many unique copper layer shapes this padstack has
  116. enum class MODE
  117. {
  118. NORMAL, ///< Shape is the same on all layers
  119. FRONT_INNER_BACK, ///< Up to three shapes can be defined (F_Cu, inner copper layers, B_Cu)
  120. CUSTOM ///< Shapes can be defined on arbitrary layers
  121. };
  122. ///! Temporary layer identifier to identify code that is not padstack-aware
  123. static constexpr PCB_LAYER_ID ALL_LAYERS = F_Cu;
  124. ///! The layer identifier to use for "inner layers" on top/inner/bottom padstacks
  125. static constexpr PCB_LAYER_ID INNER_LAYERS = In1_Cu;
  126. ///! Whether or not to remove the copper shape for unconnected layers
  127. enum class UNCONNECTED_LAYER_MODE
  128. {
  129. KEEP_ALL,
  130. REMOVE_ALL,
  131. REMOVE_EXCEPT_START_AND_END
  132. };
  133. enum class CUSTOM_SHAPE_ZONE_MODE
  134. {
  135. OUTLINE,
  136. CONVEXHULL
  137. };
  138. ///! The set of properties that define a pad's shape on a given layer
  139. struct SHAPE_PROPS
  140. {
  141. PAD_SHAPE shape; ///< Shape of the pad
  142. PAD_SHAPE anchor_shape; ///< Shape of the anchor when shape == PAD_SHAPE::CUSTOM
  143. VECTOR2I size; ///< Size of the shape, or of the anchor pad for custom shape pads
  144. /*
  145. * Most of the time the hole is the center of the shape (m_Offset = 0). But some designers
  146. * use oblong/rect pads with a hole moved to one of the oblong/rect pad shape ends.
  147. * In all cases the hole is at the pad position. This offset is from the hole to the center
  148. * of the pad shape (ie: the copper area around the hole).
  149. * ShapePos() returns the board shape position according to the offset and the pad rotation.
  150. */
  151. VECTOR2I offset; ///< Offset of the shape center from the pad center
  152. double round_rect_corner_radius;
  153. double round_rect_radius_ratio;
  154. double chamfered_rect_ratio; ///< Size of chamfer: ratio of smallest of X,Y size
  155. int chamfered_rect_positions; ///< @see RECT_CHAMFER_POSITIONS
  156. /**
  157. * Delta for PAD_SHAPE::TRAPEZOID; half the delta squeezes one end and half expands the
  158. * other. It is only valid to have a single axis be non-zero.
  159. */
  160. VECTOR2I trapezoid_delta_size;
  161. SHAPE_PROPS();
  162. bool operator==( const SHAPE_PROPS& aOther ) const;
  163. };
  164. /**
  165. * The features of a padstack that can vary between copper layers
  166. * All parameters are optional; leaving them un-set means "use parent/rule defaults"
  167. * Pad clearances, margins, etc. exist in a hierarchy. If a given level is specified then
  168. * the remaining levels are NOT consulted.
  169. *
  170. * LEVEL 1: (highest priority) local overrides (pad, footprint, etc.)
  171. * LEVEL 2: Rules
  172. * LEVEL 3: Accumulated local settings, netclass settings, & board design settings
  173. *
  174. * These are the LEVEL 1 settings (overrides) for a pad.
  175. */
  176. struct COPPER_LAYER_PROPS
  177. {
  178. SHAPE_PROPS shape;
  179. std::optional<ZONE_CONNECTION> zone_connection;
  180. std::optional<int> thermal_spoke_width;
  181. std::optional<EDA_ANGLE> thermal_spoke_angle;
  182. std::optional<int> thermal_gap;
  183. std::optional<int> clearance;
  184. /*
  185. * Editing definitions of primitives for custom pad shapes. In local coordinates relative
  186. * to m_Pos (NOT shapePos) at orient 0.
  187. */
  188. std::vector<std::shared_ptr<PCB_SHAPE>> custom_shapes;
  189. bool operator==( const COPPER_LAYER_PROPS& aOther ) const;
  190. };
  191. ///! The features of a padstack that can vary on outer layers.
  192. ///! All parameters are optional; leaving them un-set means "use parent/rule defaults"
  193. struct MASK_LAYER_PROPS
  194. {
  195. std::optional<int> solder_mask_margin;
  196. std::optional<int> solder_paste_margin;
  197. std::optional<double> solder_paste_margin_ratio;
  198. std::optional<bool> has_solder_mask; ///< True if this outer layer has mask (is not tented)
  199. std::optional<bool> has_solder_paste; ///< True if this outer layer has solder paste
  200. bool operator==( const MASK_LAYER_PROPS& aOther ) const;
  201. };
  202. ///! The properties of a padstack drill. Drill position is always the pad position (origin).
  203. struct DRILL_PROPS
  204. {
  205. VECTOR2I size; ///< Drill diameter (x == y) or slot dimensions (x != y)
  206. PAD_DRILL_SHAPE shape;
  207. PCB_LAYER_ID start;
  208. PCB_LAYER_ID end;
  209. bool operator==( const DRILL_PROPS& aOther ) const;
  210. };
  211. public:
  212. PADSTACK( BOARD_ITEM* aParent );
  213. virtual ~PADSTACK() = default;
  214. PADSTACK( const PADSTACK& aOther );
  215. PADSTACK& operator=( const PADSTACK &aOther );
  216. bool operator==( const PADSTACK& aOther ) const;
  217. bool operator!=( const PADSTACK& aOther ) const { return !operator==( aOther ); }
  218. void Serialize( google::protobuf::Any &aContainer ) const override;
  219. bool Deserialize( const google::protobuf::Any &aContainer ) override;
  220. /**
  221. * Compare two padstacks and return 0 if they are equal.
  222. *
  223. * @return less than 0 if left less than right, 0 if equal, or greater than 0 if left
  224. * greater than right.
  225. */
  226. static int Compare( const PADSTACK* aPadstackRef, const PADSTACK* aPadstackCmp );
  227. /**
  228. * Return a measure of how likely the other object is to represent the same
  229. * object. The scale runs from 0.0 (definitely different objects) to 1.0 (same)
  230. */
  231. double Similarity( const PADSTACK& aOther ) const;
  232. const LSET& LayerSet() const { return m_layerSet; }
  233. LSET& LayerSet() { return m_layerSet; }
  234. void SetLayerSet( const LSET& aSet ) { m_layerSet = aSet; }
  235. PCB_LAYER_ID StartLayer() const;
  236. PCB_LAYER_ID EndLayer() const;
  237. MODE Mode() const { return m_mode; }
  238. void SetMode( MODE aMode );
  239. ///! Returns the name of this padstack in IPC-7351 format
  240. wxString Name() const;
  241. EDA_ANGLE GetOrientation() const { return m_orientation; }
  242. void SetOrientation( EDA_ANGLE aAngle )
  243. {
  244. m_orientation = aAngle;
  245. m_orientation.Normalize();
  246. }
  247. DRILL_PROPS& Drill() { return m_drill; }
  248. const DRILL_PROPS& Drill() const { return m_drill; }
  249. DRILL_PROPS& SecondaryDrill() { return m_secondaryDrill; }
  250. const DRILL_PROPS& SecondaryDrill() const { return m_secondaryDrill; }
  251. UNCONNECTED_LAYER_MODE UnconnectedLayerMode() const { return m_unconnectedLayerMode; }
  252. void SetUnconnectedLayerMode( UNCONNECTED_LAYER_MODE aMode ) { m_unconnectedLayerMode = aMode; }
  253. COPPER_LAYER_PROPS& CopperLayer( PCB_LAYER_ID aLayer );
  254. const COPPER_LAYER_PROPS& CopperLayer( PCB_LAYER_ID aLayer ) const;
  255. MASK_LAYER_PROPS& FrontOuterLayers() { return m_frontMaskProps; }
  256. const MASK_LAYER_PROPS& FrontOuterLayers() const { return m_frontMaskProps; }
  257. MASK_LAYER_PROPS& BackOuterLayers() { return m_backMaskProps; }
  258. const MASK_LAYER_PROPS& BackOuterLayers() const { return m_backMaskProps; }
  259. /**
  260. * Checks if this padstack is tented (covered in soldermask) on the given side
  261. * @param aSide is a front or back layer (any will do)
  262. * @return true or false if this padstack contains a tenting override on the given layer, or
  263. * std::nullopt if there is no override (meaning design rules should be used)
  264. */
  265. std::optional<bool> IsTented( PCB_LAYER_ID aSide ) const;
  266. CUSTOM_SHAPE_ZONE_MODE CustomShapeInZoneMode() const { return m_customShapeInZoneMode; }
  267. void SetCustomShapeInZoneMode( CUSTOM_SHAPE_ZONE_MODE aM ) { m_customShapeInZoneMode = aM; }
  268. /**
  269. * Runs the given callable for each active unique copper layer in this padstack, meaning
  270. * F_Cu for MODE::NORMAL; F_Cu, PADSTACK::INNER_LAYERS, and B_Cu for top/inner/bottom,
  271. * and an arbitrary set of layers for full-custom padstacks.
  272. * @param aMethod will be called once for each independent copper layer in the padstack
  273. */
  274. void ForEachUniqueLayer( const std::function<void( PCB_LAYER_ID )>& aMethod ) const;
  275. /**
  276. * Determines which geometry layer should be used for the given input layer.
  277. * For example, for MODE::NORMAL, this will always be F_Cu, and for MODE::FRONT_INNER_BACK,
  278. * this will be one of F_Cu, PADSTACK::INNER_LAYERS, and B_Cu depending on the input
  279. * layer.
  280. *
  281. * @param aLayer is a valid board layer
  282. * @return the layer that the padstack's geometry is stored on for the given input layer
  283. */
  284. PCB_LAYER_ID EffectiveLayerFor( PCB_LAYER_ID aLayer ) const;
  285. // The following section has convenience getters for the padstack properties on a given layer.
  286. PAD_SHAPE Shape( PCB_LAYER_ID aLayer ) const;
  287. void SetShape( PAD_SHAPE aShape, PCB_LAYER_ID aLayer );
  288. // Setter rather than direct access to enforce only positive sizes
  289. void SetSize( const VECTOR2I& aSize, PCB_LAYER_ID aLayer );
  290. const VECTOR2I& Size( PCB_LAYER_ID aLayer ) const;
  291. PAD_DRILL_SHAPE DrillShape() const;
  292. void SetDrillShape( PAD_DRILL_SHAPE aShape );
  293. VECTOR2I& Offset( PCB_LAYER_ID aLayer );
  294. const VECTOR2I& Offset( PCB_LAYER_ID aLayer ) const;
  295. PAD_SHAPE AnchorShape( PCB_LAYER_ID aLayer ) const;
  296. void SetAnchorShape( PAD_SHAPE aShape, PCB_LAYER_ID aLayer );
  297. VECTOR2I& TrapezoidDeltaSize( PCB_LAYER_ID aLayer );
  298. const VECTOR2I& TrapezoidDeltaSize( PCB_LAYER_ID aLayer ) const;
  299. double RoundRectRadiusRatio( PCB_LAYER_ID aLayer ) const;
  300. void SetRoundRectRadiusRatio( double aRatio, PCB_LAYER_ID aLayer );
  301. int RoundRectRadius( PCB_LAYER_ID aLayer ) const;
  302. void SetRoundRectRadius( double aRadius, PCB_LAYER_ID aLayer );
  303. double ChamferRatio( PCB_LAYER_ID aLayer ) const;
  304. void SetChamferRatio( double aRatio, PCB_LAYER_ID aLayer );
  305. int& ChamferPositions( PCB_LAYER_ID aLayer );
  306. const int& ChamferPositions( PCB_LAYER_ID aLayer ) const;
  307. void SetChamferPositions( int aPositions, PCB_LAYER_ID aLayer );
  308. std::optional<int>& Clearance( PCB_LAYER_ID aLayer = F_Cu );
  309. const std::optional<int>& Clearance( PCB_LAYER_ID aLayer = F_Cu ) const;
  310. std::optional<int>& SolderMaskMargin( PCB_LAYER_ID aLayer = F_Cu );
  311. const std::optional<int>& SolderMaskMargin( PCB_LAYER_ID aLayer = F_Cu ) const;
  312. std::optional<int>& SolderPasteMargin( PCB_LAYER_ID aLayer = F_Cu );
  313. const std::optional<int>& SolderPasteMargin( PCB_LAYER_ID aLayer = F_Cu ) const;
  314. std::optional<double>& SolderPasteMarginRatio( PCB_LAYER_ID aLayer = F_Cu );
  315. const std::optional<double>& SolderPasteMarginRatio( PCB_LAYER_ID aLayer = F_Cu ) const;
  316. std::optional<ZONE_CONNECTION>& ZoneConnection( PCB_LAYER_ID aLayer = F_Cu );
  317. const std::optional<ZONE_CONNECTION>& ZoneConnection( PCB_LAYER_ID aLayer = F_Cu ) const;
  318. std::optional<int>& ThermalSpokeWidth( PCB_LAYER_ID aLayer = F_Cu );
  319. const std::optional<int>& ThermalSpokeWidth( PCB_LAYER_ID aLayer = F_Cu ) const;
  320. std::optional<int>& ThermalGap( PCB_LAYER_ID aLayer = F_Cu );
  321. const std::optional<int>& ThermalGap( PCB_LAYER_ID aLayer = F_Cu ) const;
  322. EDA_ANGLE DefaultThermalSpokeAngleForShape( PCB_LAYER_ID aLayer = F_Cu ) const;
  323. EDA_ANGLE ThermalSpokeAngle( PCB_LAYER_ID aLayer = F_Cu ) const;
  324. void SetThermalSpokeAngle( EDA_ANGLE aAngle, PCB_LAYER_ID aLayer = F_Cu );
  325. std::vector<std::shared_ptr<PCB_SHAPE>>& Primitives( PCB_LAYER_ID aLayer );
  326. const std::vector<std::shared_ptr<PCB_SHAPE>>& Primitives( PCB_LAYER_ID aLayer ) const;
  327. /**
  328. * Adds a custom shape primitive to the padstack.
  329. * @param aShape is a shape to add as a custom primitive. Ownership is passed to this PADSTACK.
  330. * @param aLayer is the padstack layer to add to.
  331. */
  332. void AddPrimitive( PCB_SHAPE* aShape, PCB_LAYER_ID aLayer );
  333. /**
  334. * Appends a copy of each shape in the given list to this padstack's custom shape list
  335. * @param aPrimitivesList is a list of shapes to add copies of to this PADSTACK
  336. * @param aLayer is the padstack layer to add to.
  337. */
  338. void AppendPrimitives( const std::vector<std::shared_ptr<PCB_SHAPE>>& aPrimitivesList,
  339. PCB_LAYER_ID aLayer );
  340. /**
  341. * Clears the existing primitive list (freeing the owned shapes) and adds copies of the given
  342. * shapes to the padstack for the given layer.
  343. * @param aPrimitivesList is a list of shapes to add copies of to this PADSTACK
  344. * @param aLayer is the padstack layer to add to.
  345. */
  346. void ReplacePrimitives( const std::vector<std::shared_ptr<PCB_SHAPE>>& aPrimitivesList,
  347. PCB_LAYER_ID aLayer );
  348. void ClearPrimitives( PCB_LAYER_ID aLayer );
  349. private:
  350. ///! The BOARD_ITEM this PADSTACK belongs to; will be used as the parent for owned shapes
  351. BOARD_ITEM* m_parent;
  352. ///! The copper layer variation mode this padstack is in
  353. MODE m_mode;
  354. ///! The board layers that this padstack is active on
  355. LSET m_layerSet;
  356. ///! An override for the IPC-7351 padstack name
  357. wxString m_customName;
  358. ///! The rotation of the pad relative to an outer reference frame
  359. EDA_ANGLE m_orientation;
  360. ///! The properties applied to copper layers if they aren't overridden
  361. //COPPER_LAYER_PROPS m_defaultCopperProps;
  362. std::unordered_map<PCB_LAYER_ID, COPPER_LAYER_PROPS> m_copperProps;
  363. ///! The overrides applied to front outer technical layers
  364. MASK_LAYER_PROPS m_frontMaskProps;
  365. ///! The overrides applied to back outer technical layers
  366. MASK_LAYER_PROPS m_backMaskProps;
  367. UNCONNECTED_LAYER_MODE m_unconnectedLayerMode;
  368. /**
  369. * How to build the custom shape in zone, to create the clearance area:
  370. * CUSTOM_SHAPE_ZONE_MODE::OUTLINE = use pad shape
  371. * CUSTOM_SHAPE_ZONE_MODE::CONVEXHULL = use the convex hull of the pad shape
  372. */
  373. CUSTOM_SHAPE_ZONE_MODE m_customShapeInZoneMode;
  374. ///! The primary drill parameters, which also define the start and end layers for through-hole
  375. ///! vias and pads (F_Cu to B_Cu for normal holes; a subset of layers for blind/buried vias)
  376. DRILL_PROPS m_drill;
  377. ///! Secondary drill, used to define back-drilling
  378. DRILL_PROPS m_secondaryDrill;
  379. };
  380. #ifndef SWIG
  381. DECLARE_ENUM_TO_WXANY( PADSTACK::UNCONNECTED_LAYER_MODE );
  382. #endif
  383. #endif //KICAD_PADSTACK_H