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.

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