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.

1197 lines
44 KiB

5 years ago
7 months ago
7 months ago
11 years ago
7 months ago
* KIWAY Milestone A): Make major modules into DLL/DSOs. ! The initial testing of this commit should be done using a Debug build so that all the wxASSERT()s are enabled. Also, be sure and keep enabled the USE_KIWAY_DLLs option. The tree won't likely build without it. Turning it off is senseless anyways. If you want stable code, go back to a prior version, the one tagged with "stable". * Relocate all functionality out of the wxApp derivative into more finely targeted purposes: a) DLL/DSO specific b) PROJECT specific c) EXE or process specific d) configuration file specific data e) configuration file manipulations functions. All of this functionality was blended into an extremely large wxApp derivative and that was incompatible with the desire to support multiple concurrently loaded DLL/DSO's ("KIFACE")s and multiple concurrently open projects. An amazing amount of organization come from simply sorting each bit of functionality into the proper box. * Switch to wxConfigBase from wxConfig everywhere except instantiation. * Add classes KIWAY, KIFACE, KIFACE_I, SEARCH_STACK, PGM_BASE, PGM_KICAD, PGM_SINGLE_TOP, * Remove "Return" prefix on many function names. * Remove obvious comments from CMakeLists.txt files, and from else() and endif()s. * Fix building boost for use in a DSO on linux. * Remove some of the assumptions in the CMakeLists.txt files that windows had to be the host platform when building windows binaries. * Reduce the number of wxStrings being constructed at program load time via static construction. * Pass wxConfigBase* to all SaveSettings() and LoadSettings() functions so that these functions are useful even when the wxConfigBase comes from another source, as is the case in the KICAD_MANAGER_FRAME. * Move the setting of the KIPRJMOD environment variable into class PROJECT, so that it can be moved into a project variable soon, and out of FP_LIB_TABLE. * Add the KIWAY_PLAYER which is associated with a particular PROJECT, and all its child wxFrames and wxDialogs now have a Kiway() member function which returns a KIWAY& that that window tree branch is in support of. This is like wxWindows DNA in that child windows get this member with proper value at time of construction. * Anticipate some of the needs for milestones B) and C) and make code adjustments now in an effort to reduce work in those milestones. * No testing has been done for python scripting, since milestone C) has that being largely reworked and re-thought-out.
12 years ago
11 years ago
4 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) 2015 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. #ifndef FOOTPRINT_H
  25. #define FOOTPRINT_H
  26. #include <deque>
  27. #include <template_fieldnames.h>
  28. #include <board_item_container.h>
  29. #include <board_item.h>
  30. #include <collectors.h>
  31. #include <component_classes/component_class_manager.h>
  32. #include <embedded_files.h>
  33. #include <layer_ids.h> // ALL_LAYERS definition.
  34. #include <lset.h>
  35. #include <lib_id.h>
  36. #include <list>
  37. #include <zones.h>
  38. #include <convert_shape_list_to_polygon.h>
  39. #include <pcb_item_containers.h>
  40. #include <pcb_text.h>
  41. #include <pcb_field.h>
  42. #include <functional>
  43. #include <math/vector3.h>
  44. class LINE_READER;
  45. class EDA_3D_CANVAS;
  46. class PAD;
  47. class BOARD;
  48. class MSG_PANEL_ITEM;
  49. class SHAPE;
  50. class REPORTER;
  51. class COMPONENT_CLASS_CACHE_PROXY;
  52. class PCB_POINT;
  53. namespace KIGFX {
  54. class VIEW;
  55. }
  56. namespace KIFONT {
  57. class OUTLINE_FONT;
  58. }
  59. enum INCLUDE_NPTH_T
  60. {
  61. DO_NOT_INCLUDE_NPTH = false,
  62. INCLUDE_NPTH = true
  63. };
  64. /**
  65. * The set of attributes allowed within a FOOTPRINT, using FOOTPRINT::SetAttributes()
  66. * and FOOTPRINT::GetAttributes(). These are to be ORed together when calling
  67. * FOOTPRINT::SetAttributes()
  68. */
  69. enum FOOTPRINT_ATTR_T
  70. {
  71. FP_THROUGH_HOLE = 0x0001,
  72. FP_SMD = 0x0002,
  73. FP_EXCLUDE_FROM_POS_FILES = 0x0004,
  74. FP_EXCLUDE_FROM_BOM = 0x0008,
  75. FP_BOARD_ONLY = 0x0010, // Footprint has no corresponding symbol
  76. FP_JUST_ADDED = 0x0020, // Footprint just added by netlist update
  77. FP_DNP = 0x0040
  78. };
  79. enum class FOOTPRINT_STACKUP
  80. {
  81. /**
  82. * The 'normal' stackup handling, where there is a single inner layer
  83. * (In1) and rule areas using it expand to all inner layer on the host PCB.
  84. */
  85. EXPAND_INNER_LAYERS,
  86. /**
  87. * Stackup handling where the footprint can have any number of copper layers,
  88. * and objects on those layers go to the matching inner layer on the host PCB.
  89. */
  90. CUSTOM_LAYERS,
  91. };
  92. class FP_3DMODEL
  93. {
  94. public:
  95. FP_3DMODEL() :
  96. // Initialize with sensible values
  97. m_Scale { 1, 1, 1 },
  98. m_Rotation { 0, 0, 0 },
  99. m_Offset { 0, 0, 0 },
  100. m_Opacity( 1.0 ),
  101. m_Show( true )
  102. {
  103. }
  104. VECTOR3D m_Scale; ///< 3D model scaling factor (dimensionless)
  105. VECTOR3D m_Rotation; ///< 3D model rotation (degrees)
  106. VECTOR3D m_Offset; ///< 3D model offset (mm)
  107. double m_Opacity;
  108. wxString m_Filename; ///< The 3D shape filename in 3D library
  109. bool m_Show; ///< Include model in rendering
  110. bool operator==( const FP_3DMODEL& aOther ) const
  111. {
  112. return m_Scale == aOther.m_Scale
  113. && m_Rotation == aOther.m_Rotation
  114. && m_Offset == aOther.m_Offset
  115. && m_Opacity == aOther.m_Opacity
  116. && m_Filename == aOther.m_Filename
  117. && m_Show == aOther.m_Show;
  118. }
  119. };
  120. class FOOTPRINT : public BOARD_ITEM_CONTAINER, public EMBEDDED_FILES
  121. {
  122. public:
  123. FOOTPRINT( BOARD* parent );
  124. FOOTPRINT( const FOOTPRINT& aFootprint );
  125. // Move constructor and operator needed due to std containers inside the footprint
  126. FOOTPRINT( FOOTPRINT&& aFootprint );
  127. ~FOOTPRINT();
  128. FOOTPRINT& operator=( const FOOTPRINT& aOther );
  129. FOOTPRINT& operator=( FOOTPRINT&& aOther );
  130. void CopyFrom( const BOARD_ITEM* aOther ) override;
  131. void Serialize( google::protobuf::Any &aContainer ) const override;
  132. bool Deserialize( const google::protobuf::Any &aContainer ) override;
  133. static inline bool ClassOf( const EDA_ITEM* aItem )
  134. {
  135. return aItem && aItem->Type() == PCB_FOOTPRINT_T;
  136. }
  137. /// Resets the caches for this footprint, for example if it was modified via the API
  138. void InvalidateGeometryCaches();
  139. LSET GetPrivateLayers() const { return m_privateLayers; }
  140. void SetPrivateLayers( const LSET& aLayers ) { m_privateLayers = aLayers; }
  141. ///< @copydoc BOARD_ITEM_CONTAINER::Add()
  142. void Add( BOARD_ITEM* aItem, ADD_MODE aMode = ADD_MODE::INSERT,
  143. bool aSkipConnectivity = false ) override;
  144. ///< @copydoc BOARD_ITEM_CONTAINER::Remove()
  145. void Remove( BOARD_ITEM* aItem, REMOVE_MODE aMode = REMOVE_MODE::NORMAL ) override;
  146. /**
  147. * Clear (i.e. force the ORPHANED dummy net info) the net info which
  148. * depends on a given board for all pads of the footprint.
  149. *
  150. * This is needed when a footprint is copied between the fp editor and
  151. * the board editor for instance, because net info become fully broken
  152. */
  153. void ClearAllNets();
  154. /**
  155. * Old footprints do not always have a valid UUID (some can be set to null uuid)
  156. * However null UUIDs, having a special meaning in editor, create issues when
  157. * editing a footprint
  158. * So all null uuids a re replaced by a valid uuid
  159. * @return true if at least one uuid is changed, false if no change
  160. */
  161. bool FixUuids();
  162. /**
  163. * Return the bounding box containing pads when the footprint is on the front side,
  164. * orientation 0, position 0,0.
  165. *
  166. * Mainly used in Gerber place file to draw a footprint outline when the courtyard
  167. * is missing or broken.
  168. *
  169. * @return The rectangle containing the pads for the normalized footprint.
  170. */
  171. BOX2I GetFpPadsLocalBbox() const;
  172. /**
  173. * Return a bounding polygon for the shapes and pads in the footprint.
  174. *
  175. * This operation is slower but more accurate than calculating a bounding box.
  176. */
  177. SHAPE_POLY_SET GetBoundingHull() const;
  178. SHAPE_POLY_SET GetBoundingHull( PCB_LAYER_ID aLayer ) const;
  179. bool TextOnly() const;
  180. // Virtual function
  181. const BOX2I GetBoundingBox() const override;
  182. const BOX2I GetBoundingBox( bool aIncludeText ) const;
  183. /**
  184. * Return the bounding box of the footprint on a given set of layers
  185. */
  186. const BOX2I GetLayerBoundingBox( const LSET& aLayers ) const;
  187. VECTOR2I GetCenter() const override { return GetBoundingBox( false ).GetCenter(); }
  188. std::deque<PAD*>& Pads() { return m_pads; }
  189. const std::deque<PAD*>& Pads() const { return m_pads; }
  190. DRAWINGS& GraphicalItems() { return m_drawings; }
  191. const DRAWINGS& GraphicalItems() const { return m_drawings; }
  192. ZONES& Zones() { return m_zones; }
  193. const ZONES& Zones() const { return m_zones; }
  194. GROUPS& Groups() { return m_groups; }
  195. const GROUPS& Groups() const { return m_groups; }
  196. PCB_POINTS& Points() { return m_points; }
  197. const PCB_POINTS& Points() const { return m_points; }
  198. bool HasThroughHolePads() const;
  199. std::vector<FP_3DMODEL>& Models() { return m_3D_Drawings; }
  200. const std::vector<FP_3DMODEL>& Models() const { return m_3D_Drawings; }
  201. void SetPosition( const VECTOR2I& aPos ) override;
  202. VECTOR2I GetPosition() const override { return m_pos; }
  203. void SetOrientation( const EDA_ANGLE& aNewAngle );
  204. EDA_ANGLE GetOrientation() const { return m_orient; }
  205. /**
  206. * Used as Layer property setter -- performs a flip if necessary to set the footprint layer
  207. * @param aLayer is the target layer (F_Cu or B_Cu)
  208. */
  209. void SetLayerAndFlip( PCB_LAYER_ID aLayer );
  210. // to make property magic work
  211. PCB_LAYER_ID GetLayer() const override { return BOARD_ITEM::GetLayer(); }
  212. // For property system:
  213. void SetOrientationDegrees( double aOrientation )
  214. {
  215. SetOrientation( EDA_ANGLE( aOrientation, DEGREES_T ) );
  216. }
  217. double GetOrientationDegrees() const
  218. {
  219. return m_orient.AsDegrees();
  220. }
  221. const LIB_ID& GetFPID() const { return m_fpid; }
  222. void SetFPID( const LIB_ID& aFPID )
  223. {
  224. m_fpid = aFPID;
  225. }
  226. wxString GetFPIDAsString() const { return m_fpid.Format(); }
  227. void SetFPIDAsString( const wxString& aFPID ) { m_fpid.Parse( aFPID ); }
  228. wxString GetLibDescription() const { return m_libDescription; }
  229. void SetLibDescription( const wxString& aDesc ) { m_libDescription = aDesc; }
  230. wxString GetKeywords() const { return m_keywords; }
  231. void SetKeywords( const wxString& aKeywords ) { m_keywords = aKeywords; }
  232. const KIID_PATH& GetPath() const { return m_path; }
  233. void SetPath( const KIID_PATH& aPath ) { m_path = aPath; }
  234. wxString GetSheetname() const { return m_sheetname; }
  235. void SetSheetname( const wxString& aSheetname ) { m_sheetname = aSheetname; }
  236. wxString GetSheetfile() const { return m_sheetfile; }
  237. void SetSheetfile( const wxString& aSheetfile ) { m_sheetfile = aSheetfile; }
  238. wxString GetFilters() const { return m_filters; }
  239. void SetFilters( const wxString& aFilters ) { m_filters = aFilters; }
  240. std::optional<int> GetLocalClearance() const { return m_clearance; }
  241. void SetLocalClearance( std::optional<int> aClearance ) { m_clearance = aClearance; }
  242. std::optional<int> GetLocalSolderMaskMargin() const { return m_solderMaskMargin; }
  243. void SetLocalSolderMaskMargin( std::optional<int> aMargin ) { m_solderMaskMargin = aMargin; }
  244. std::optional<int> GetLocalSolderPasteMargin() const { return m_solderPasteMargin; }
  245. void SetLocalSolderPasteMargin( std::optional<int> aMargin ) { m_solderPasteMargin = aMargin; }
  246. std::optional<double> GetLocalSolderPasteMarginRatio() const { return m_solderPasteMarginRatio; }
  247. void SetLocalSolderPasteMarginRatio( std::optional<double> aRatio ) { m_solderPasteMarginRatio = aRatio; }
  248. void SetLocalZoneConnection( ZONE_CONNECTION aType ) { m_zoneConnection = aType; }
  249. ZONE_CONNECTION GetLocalZoneConnection() const { return m_zoneConnection; }
  250. /**
  251. * Set the stackup mode for this footprint.
  252. *
  253. * This determines if the footprint lists its own layers or uses a default stackup,
  254. * with "expansion" of inner layers to the PCB's inner layers.
  255. */
  256. void SetStackupMode( FOOTPRINT_STACKUP aMode );
  257. FOOTPRINT_STACKUP GetStackupMode() const { return m_stackupMode; }
  258. /**
  259. * If the footprint has a non-default stackup, set the layers that
  260. * should be used for the stackup.
  261. */
  262. void SetStackupLayers( LSET aLayers );
  263. const LSET& GetStackupLayers() const { return m_stackupLayers; }
  264. int GetAttributes() const { return m_attributes; }
  265. void SetAttributes( int aAttributes ) { m_attributes = aAttributes; }
  266. bool AllowMissingCourtyard() const { return m_allowMissingCourtyard; }
  267. void SetAllowMissingCourtyard( bool aAllow ) { m_allowMissingCourtyard = aAllow; }
  268. bool AllowSolderMaskBridges() const { return m_allowSolderMaskBridges; }
  269. void SetAllowSolderMaskBridges( bool aAllow ) { m_allowSolderMaskBridges = aAllow; }
  270. void SetFlag( int aFlag ) { m_arflag = aFlag; }
  271. void IncrementFlag() { m_arflag += 1; }
  272. int GetFlag() const { return m_arflag; }
  273. bool IsNetTie() const
  274. {
  275. for( const wxString& group : m_netTiePadGroups )
  276. {
  277. if( !group.IsEmpty() )
  278. return true;
  279. }
  280. return false;
  281. }
  282. std::optional<int> GetLocalClearance( wxString* aSource ) const
  283. {
  284. if( m_clearance.has_value() && aSource )
  285. *aSource = wxString::Format( _( "footprint %s" ), GetReference() );
  286. return m_clearance;
  287. }
  288. /**
  289. * Return any local clearance overrides set in the "classic" (ie: pre-rule) system.
  290. *
  291. * @param aSource [out] optionally reports the source as a user-readable string.
  292. * @return the clearance in internal units.
  293. */
  294. std::optional<int> GetClearanceOverrides( wxString* aSource ) const
  295. {
  296. return GetLocalClearance( aSource );
  297. }
  298. ZONE_CONNECTION GetZoneConnectionOverrides( wxString* aSource ) const
  299. {
  300. if( m_zoneConnection != ZONE_CONNECTION::INHERITED && aSource )
  301. *aSource = wxString::Format( _( "footprint %s" ), GetReference() );
  302. return m_zoneConnection;
  303. }
  304. /**
  305. * @return a list of pad groups, each of which is allowed to short nets within their group.
  306. * A pad group is a comma-separated list of pad numbers.
  307. */
  308. const std::vector<wxString>& GetNetTiePadGroups() const { return m_netTiePadGroups; }
  309. void ClearNetTiePadGroups()
  310. {
  311. m_netTiePadGroups.clear();
  312. }
  313. void AddNetTiePadGroup( const wxString& aGroup )
  314. {
  315. m_netTiePadGroups.emplace_back( aGroup );
  316. }
  317. /**
  318. * @return a map from pad numbers to net-tie group indices. If a pad is not a member of
  319. * a net-tie group its index will be -1.
  320. */
  321. std::map<wxString, int> MapPadNumbersToNetTieGroups() const;
  322. /**
  323. * @return a list of pads that appear in \a aPad's net-tie pad group.
  324. */
  325. std::vector<PAD*> GetNetTiePads( PAD* aPad ) const;
  326. /**
  327. * Returns the most likely attribute based on pads
  328. * Either FP_THROUGH_HOLE/FP_SMD/OTHER(0)
  329. * @return 0/FP_SMD/FP_THROUGH_HOLE
  330. */
  331. int GetLikelyAttribute() const;
  332. void Move( const VECTOR2I& aMoveVector ) override;
  333. void Rotate( const VECTOR2I& aRotCentre, const EDA_ANGLE& aAngle ) override;
  334. void Flip( const VECTOR2I& aCentre, FLIP_DIRECTION aFlipDirection ) override;
  335. /**
  336. * Move the reference point of the footprint.
  337. *
  338. * It looks like a move footprint:
  339. * the footprints elements (pads, outlines, edges .. ) are moved
  340. * However:
  341. * - the footprint position is not modified.
  342. * - the relative (local) coordinates of these items are modified
  343. * (a move footprint does not change these local coordinates,
  344. * but changes the footprint position)
  345. */
  346. void MoveAnchorPosition( const VECTOR2I& aMoveVector );
  347. /**
  348. * @return true if the footprint is flipped, i.e. on the back side of the board
  349. */
  350. bool IsFlipped() const { return GetLayer() == B_Cu; }
  351. /**
  352. * Use instead of IsFlipped() when you also need to account for unsided footprints (those
  353. * purely on user-layers, etc.).
  354. */
  355. PCB_LAYER_ID GetSide() const;
  356. /**
  357. * @copydoc BOARD_ITEM::IsOnLayer
  358. */
  359. bool IsOnLayer( PCB_LAYER_ID aLayer ) const override;
  360. // m_footprintStatus bits:
  361. #define FP_is_LOCKED 0x01 ///< footprint LOCKED: no autoplace allowed
  362. #define FP_is_PLACED 0x02 ///< In autoplace: footprint automatically placed
  363. #define FP_to_PLACE 0x04 ///< In autoplace: footprint waiting for autoplace
  364. #define FP_PADS_are_LOCKED 0x08
  365. bool IsLocked() const override
  366. {
  367. return ( m_fpStatus & FP_is_LOCKED ) != 0;
  368. }
  369. /**
  370. * Set the #MODULE_is_LOCKED bit in the m_ModuleStatus.
  371. *
  372. * @param isLocked true means turn on locked status, else unlock
  373. */
  374. void SetLocked( bool isLocked ) override
  375. {
  376. if( isLocked )
  377. m_fpStatus |= FP_is_LOCKED;
  378. else
  379. m_fpStatus &= ~FP_is_LOCKED;
  380. }
  381. /**
  382. * @return true if the footprint is flagged with conflicting with some item
  383. */
  384. bool IsConflicting() const;
  385. bool IsPlaced() const { return m_fpStatus & FP_is_PLACED; }
  386. void SetIsPlaced( bool isPlaced )
  387. {
  388. if( isPlaced )
  389. m_fpStatus |= FP_is_PLACED;
  390. else
  391. m_fpStatus &= ~FP_is_PLACED;
  392. }
  393. bool NeedsPlaced() const { return m_fpStatus & FP_to_PLACE; }
  394. void SetNeedsPlaced( bool needsPlaced )
  395. {
  396. if( needsPlaced )
  397. m_fpStatus |= FP_to_PLACE;
  398. else
  399. m_fpStatus &= ~FP_to_PLACE;
  400. }
  401. bool LegacyPadsLocked() const { return m_fpStatus & FP_PADS_are_LOCKED; }
  402. /**
  403. * Test if footprint attributes for type (SMD/Through hole/Other) match the expected
  404. * type based on the pads in the footprint.
  405. * Footprints with plated through-hole pads should usually be marked through hole even if they
  406. * also have SMD because they might not be auto-placed. Exceptions to this might be shielded
  407. * connectors. Otherwise, footprints with SMD pads should be marked SMD.
  408. * Footprints with no connecting pads should be marked "Other"
  409. *
  410. * @param aErrorHandler callback to handle the error messages generated
  411. */
  412. void CheckFootprintAttributes( const std::function<void( const wxString& )>& aErrorHandler );
  413. /**
  414. * Run non-board-specific DRC checks on footprint's pads. These are the checks supported by
  415. * both the PCB DRC and the Footprint Editor Footprint Checker.
  416. *
  417. * @param aErrorHandler callback to handle the error messages generated
  418. */
  419. void CheckPads( UNITS_PROVIDER* aUnitsProvider,
  420. const std::function<void( const PAD*, int, const wxString& )>& aErrorHandler );
  421. /**
  422. * Check for overlapping, different-numbered, non-net-tie pads.
  423. *
  424. * @param aErrorHandler callback to handle the error messages generated
  425. */
  426. void CheckShortingPads( const std::function<void( const PAD*, const PAD*, int aErrorCode,
  427. const VECTOR2I& )>& aErrorHandler );
  428. /**
  429. * Check for un-allowed shorting of pads in net-tie footprints. If two pads are shorted,
  430. * they must both appear in one of the allowed-shorting lists.
  431. *
  432. * @param aErrorHandler callback to handle the error messages generated
  433. */
  434. void CheckNetTies( const std::function<void( const BOARD_ITEM* aItem,
  435. const BOARD_ITEM* bItem,
  436. const BOARD_ITEM* cItem,
  437. const VECTOR2I& )>& aErrorHandler );
  438. /**
  439. * Sanity check net-tie pad groups. Pads cannot be listed more than once, and pad numbers
  440. * must correspond to a pad.
  441. *
  442. * @param aErrorHandler callback to handle the error messages generated
  443. */
  444. void CheckNetTiePadGroups( const std::function<void( const wxString& )>& aErrorHandler );
  445. void CheckClippedSilk( const std::function<void( BOARD_ITEM* aItemA,
  446. BOARD_ITEM* aItemB,
  447. const VECTOR2I& aPt )>& aErrorHandler );
  448. /**
  449. * Cache the pads that are allowed to connect to each other in the footprint.
  450. */
  451. void BuildNetTieCache();
  452. /**
  453. * Get the set of net codes that are allowed to connect to a footprint item
  454. */
  455. const std::set<int>& GetNetTieCache( const BOARD_ITEM* aItem ) const
  456. {
  457. static const std::set<int> emptySet;
  458. auto it = m_netTieCache.find( aItem );
  459. if( it == m_netTieCache.end() )
  460. return emptySet;
  461. return it->second;
  462. }
  463. /**
  464. * Generate pads shapes on layer \a aLayer as polygons and adds these polygons to
  465. * \a aBuffer.
  466. *
  467. * Useful to generate a polygonal representation of a footprint in 3D view and plot functions,
  468. * when a full polygonal approach is needed.
  469. *
  470. * @param aLayer is the layer to consider, or #UNDEFINED_LAYER to consider all layers.
  471. * @param aBuffer i the buffer to store polygons.
  472. * @param aClearance is an additional size to add to pad shapes.
  473. * @param aMaxError is the maximum deviation from true for arcs.
  474. */
  475. void TransformPadsToPolySet( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aLayer, int aClearance,
  476. int aMaxError, ERROR_LOC aErrorLoc ) const;
  477. /**
  478. * Generate shapes of graphic items (outlines) on layer \a aLayer as polygons and adds these
  479. * polygons to \a aBuffer.
  480. *
  481. * Useful to generate a polygonal representation of a footprint in 3D view and plot functions,
  482. * when a full polygonal approach is needed.
  483. *
  484. * @param aLayer is the layer to consider, or #UNDEFINED_LAYER to consider all.
  485. * @param aBuffer is the buffer to store polygons.
  486. * @param aClearance is a value to inflate shapes.
  487. * @param aError is the maximum error between true arc and polygon approximation.
  488. * @param aIncludeText set to true to transform text shapes.
  489. * @param aIncludeShapes set to true to transform footprint shapes.
  490. */
  491. void TransformFPShapesToPolySet( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aLayer, int aClearance,
  492. int aError, ERROR_LOC aErrorLoc,
  493. bool aIncludeText = true,
  494. bool aIncludeShapes = true,
  495. bool aIncludePrivateItems = false ) const;
  496. /**
  497. * This function is the same as TransformFPShapesToPolySet but only generates text.
  498. */
  499. void TransformFPTextToPolySet( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aLayer, int aClearance,
  500. int aError, ERROR_LOC aErrorLoc ) const
  501. {
  502. TransformFPShapesToPolySet( aBuffer, aLayer, aClearance, aError, aErrorLoc, true, false );
  503. }
  504. /**
  505. * Return the list of system text vars for this footprint.
  506. */
  507. void GetContextualTextVars( wxArrayString* aVars ) const;
  508. /**
  509. * Resolve any references to system tokens supported by the component.
  510. *
  511. * @param aDepth a counter to limit recursion and circular references.
  512. */
  513. bool ResolveTextVar( wxString* token, int aDepth = 0 ) const;
  514. /// @copydoc EDA_ITEM::GetMsgPanelInfo
  515. void GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList ) override;
  516. bool HitTest( const VECTOR2I& aPosition, int aAccuracy = 0 ) const override;
  517. bool Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) const override;
  518. /**
  519. * Test if a point is inside the bounding polygon of the footprint.
  520. *
  521. * The other hit test methods are just checking the bounding box, which can be quite
  522. * inaccurate for rotated or oddly-shaped footprints.
  523. *
  524. * @param aPosition is the point to test
  525. * @return true if aPosition is inside the bounding polygon
  526. */
  527. bool HitTestAccurate( const VECTOR2I& aPosition, int aAccuracy = 0 ) const;
  528. bool HitTest( const BOX2I& aRect, bool aContained, int aAccuracy = 0 ) const override;
  529. bool HitTest( const SHAPE_LINE_CHAIN& aPoly, bool aContained ) const override;
  530. /**
  531. * Test if the point hits one or more of the footprint elements on a given layer.
  532. *
  533. * @param aPosition is the point to test
  534. * @param aAccuracy is the hit test accuracy
  535. * @param aLayer is the layer to test
  536. * @return true if aPosition hits a footprint element on aLayer
  537. */
  538. bool HitTestOnLayer( const VECTOR2I& aPosition, PCB_LAYER_ID aLayer, int aAccuracy = 0 ) const;
  539. bool HitTestOnLayer( const BOX2I& aRect, bool aContained, PCB_LAYER_ID aLayer, int aAccuracy = 0 ) const;
  540. /**
  541. * @return reference designator text.
  542. */
  543. const wxString& GetReference() const { return Reference().GetText(); }
  544. /**
  545. * @param aReference A reference to a wxString object containing the reference designator
  546. * text.
  547. */
  548. void SetReference( const wxString& aReference ) { Reference().SetText( aReference ); }
  549. // Property system doesn't like const references
  550. wxString GetReferenceAsString() const
  551. {
  552. return GetReference();
  553. }
  554. /**
  555. * Bump the current reference by \a aDelta.
  556. */
  557. void IncrementReference( int aDelta );
  558. /**
  559. * @return the value text.
  560. */
  561. const wxString& GetValue() const { return Value().GetText(); }
  562. /**
  563. * @param aValue A reference to a wxString object containing the value text.
  564. */
  565. void SetValue( const wxString& aValue ) { Value().SetText( aValue ); }
  566. // Property system doesn't like const references
  567. wxString GetValueAsString() const
  568. {
  569. return GetValue();
  570. }
  571. /// read/write accessors:
  572. PCB_FIELD& Value() { return *GetField( FIELD_T::VALUE ); }
  573. PCB_FIELD& Reference() { return *GetField( FIELD_T::REFERENCE ); }
  574. /// The const versions to keep the compiler happy.
  575. const PCB_FIELD& Value() const { return *GetField( FIELD_T::VALUE ); }
  576. const PCB_FIELD& Reference() const { return *GetField( FIELD_T::REFERENCE ); }
  577. //-----<Fields>-----------------------------------------------------------
  578. /**
  579. * Return a mandatory field in this footprint. The const version will return nullptr if
  580. * the field doesn't exist; the non-const version will create the field and return it.
  581. */
  582. PCB_FIELD* GetField( FIELD_T aFieldType );
  583. const PCB_FIELD* GetField( FIELD_T aFieldNdx ) const;
  584. /**
  585. * Return a field in this symbol.
  586. *
  587. * @param aFieldName is the name of the field
  588. *
  589. * @return is the field with \a aFieldName or NULL if the field does not exist.
  590. */
  591. PCB_FIELD* GetField( const wxString& aFieldName ) const;
  592. bool HasField( const wxString& aFieldName ) const;
  593. /**
  594. * Populate a std::vector with PCB_TEXTs.
  595. *
  596. * @param aVector is the vector to populate.
  597. * @param aVisibleOnly is used to add only the fields that are visible and contain text.
  598. */
  599. void GetFields( std::vector<PCB_FIELD*>& aVector, bool aVisibleOnly ) const;
  600. /**
  601. * Return a reference to the deque holding the footprint's fields
  602. */
  603. const std::deque<PCB_FIELD*>& GetFields() const { return m_fields; }
  604. std::deque<PCB_FIELD*>& GetFields() { return m_fields; }
  605. /**
  606. * Return the next ordinal for a user field for this footprint
  607. */
  608. int GetNextFieldOrdinal() const;
  609. /**
  610. * @brief Apply default board settings to the footprint field text properties.
  611. *
  612. * This is needed because the board settings are not available when the footprint is
  613. * being created in the footprint library cache, and we want these fields to have
  614. * the correct default text properties.
  615. */
  616. void ApplyDefaultSettings( const BOARD& board, bool aStyleFields, bool aStyleText,
  617. bool aStyleShapes );
  618. struct FP_UNIT_INFO
  619. {
  620. wxString m_unitName; // e.g. A
  621. std::vector<wxString> m_pins; // pin numbers in this unit
  622. };
  623. void SetUnitInfo( const std::vector<FP_UNIT_INFO>& aUnits ) { m_unitInfo = aUnits; }
  624. const std::vector<FP_UNIT_INFO>& GetUnitInfo() const { return m_unitInfo; }
  625. bool IsBoardOnly() const { return m_attributes & FP_BOARD_ONLY; }
  626. void SetBoardOnly( bool aIsBoardOnly = true )
  627. {
  628. if( aIsBoardOnly )
  629. m_attributes |= FP_BOARD_ONLY;
  630. else
  631. m_attributes &= ~FP_BOARD_ONLY;
  632. }
  633. bool IsExcludedFromPosFiles() const { return m_attributes & FP_EXCLUDE_FROM_POS_FILES; }
  634. void SetExcludedFromPosFiles( bool aExclude = true )
  635. {
  636. if( aExclude )
  637. m_attributes |= FP_EXCLUDE_FROM_POS_FILES;
  638. else
  639. m_attributes &= ~FP_EXCLUDE_FROM_POS_FILES;
  640. }
  641. bool IsExcludedFromBOM() const { return m_attributes & FP_EXCLUDE_FROM_BOM; }
  642. void SetExcludedFromBOM( bool aExclude = true )
  643. {
  644. if( aExclude )
  645. m_attributes |= FP_EXCLUDE_FROM_BOM;
  646. else
  647. m_attributes &= ~FP_EXCLUDE_FROM_BOM;
  648. }
  649. bool IsDNP() const { return m_attributes & FP_DNP; }
  650. void SetDNP( bool aDNP = true )
  651. {
  652. if( aDNP )
  653. m_attributes |= FP_DNP;
  654. else
  655. m_attributes &= ~FP_DNP;
  656. }
  657. void SetFileFormatVersionAtLoad( int aVersion ) { m_fileFormatVersionAtLoad = aVersion; }
  658. int GetFileFormatVersionAtLoad() const { return m_fileFormatVersionAtLoad; }
  659. /**
  660. * Return a #PAD with a matching number.
  661. *
  662. * @note Numbers may not be unique depending on how the footprint was created.
  663. *
  664. * @param aPadNumber the pad number to find.
  665. * @param aSearchAfterMe = not nullptr to find a pad living after aAfterMe
  666. * @return the first matching numbered #PAD is returned or NULL if not found.
  667. */
  668. PAD* FindPadByNumber( const wxString& aPadNumber, PAD* aSearchAfterMe = nullptr ) const;
  669. /**
  670. * Get a pad at \a aPosition on \a aLayerMask in the footprint.
  671. *
  672. * @param aPosition A VECTOR2I object containing the position to hit test.
  673. * @param aLayerMask A layer or layers to mask the hit test.
  674. * @return A pointer to a #PAD object if found otherwise NULL.
  675. */
  676. PAD* GetPad( const VECTOR2I& aPosition, const LSET& aLayerMask = LSET::AllLayersMask() );
  677. std::vector<const PAD*> GetPads( const wxString& aPadNumber,
  678. const PAD* aIgnore = nullptr ) const;
  679. /**
  680. * Return the number of pads.
  681. *
  682. * @param aIncludeNPTH includes non-plated through holes when true. Does not include
  683. * non-plated through holes when false.
  684. * @return the number of pads according to \a aIncludeNPTH.
  685. */
  686. unsigned GetPadCount( INCLUDE_NPTH_T aIncludeNPTH = INCLUDE_NPTH_T(INCLUDE_NPTH) ) const;
  687. /**
  688. * Return the number of unique non-blank pads.
  689. *
  690. * A complex pad can be built with many pads having the same pad name to create a complex
  691. * shape or fragmented solder paste areas.
  692. *
  693. * @param aIncludeNPTH includes non-plated through holes when true. Does not include
  694. * non-plated through holes when false.
  695. * @return the number of unique pads according to \a aIncludeNPTH.
  696. */
  697. unsigned GetUniquePadCount( INCLUDE_NPTH_T aIncludeNPTH = INCLUDE_NPTH_T(INCLUDE_NPTH) ) const;
  698. /**
  699. * Return the names of the unique, non-blank pads.
  700. */
  701. std::set<wxString>
  702. GetUniquePadNumbers( INCLUDE_NPTH_T aIncludeNPTH = INCLUDE_NPTH_T(INCLUDE_NPTH) ) const;
  703. /**
  704. * Return the next available pad number in the footprint.
  705. *
  706. * @param aFillSequenceGaps true if the numbering should "fill in" gaps in the sequence,
  707. * else return the highest value + 1
  708. * @return the next available pad number
  709. */
  710. wxString GetNextPadNumber( const wxString& aLastPadName ) const;
  711. bool GetDuplicatePadNumbersAreJumpers() const { return m_duplicatePadNumbersAreJumpers; }
  712. void SetDuplicatePadNumbersAreJumpers( bool aEnabled ) { m_duplicatePadNumbersAreJumpers = aEnabled; }
  713. /**
  714. * Each jumper pad group is a set of pad numbers that should be treated as internally connected.
  715. * @return The list of jumper pad groups in this footprint
  716. */
  717. std::vector<std::set<wxString>>& JumperPadGroups() { return m_jumperPadGroups; }
  718. const std::vector<std::set<wxString>>& JumperPadGroups() const { return m_jumperPadGroups; }
  719. /// Retrieves the jumper group containing the specified pad number, if one exists
  720. std::optional<const std::set<wxString>> GetJumperPadGroup( const wxString& aPadNumber ) const;
  721. /**
  722. * Position Reference and Value fields at the top and bottom of footprint's bounding box.
  723. */
  724. void AutoPositionFields();
  725. /**
  726. * Get the type of footprint
  727. * @return "SMD"/"Through hole"/"Other" based on attributes
  728. */
  729. wxString GetTypeName() const;
  730. double GetArea( int aPadding = 0 ) const;
  731. KIID GetLink() const { return m_link; }
  732. void SetLink( const KIID& aLink ) { m_link = aLink; }
  733. BOARD_ITEM* Duplicate( bool addToParentGroup, BOARD_COMMIT* aCommit = nullptr ) const override;
  734. /**
  735. * Duplicate a given item within the footprint, optionally adding it to the board.
  736. *
  737. * @return the new item, or NULL if the item could not be duplicated.
  738. */
  739. BOARD_ITEM* DuplicateItem( bool addToParentGroup, BOARD_COMMIT* aCommit, const BOARD_ITEM* aItem,
  740. bool addToFootprint = false );
  741. /**
  742. * Add \a a3DModel definition to the end of the 3D model list.
  743. *
  744. * @param a3DModel A pointer to a #FP_3DMODEL to add to the list.
  745. */
  746. void Add3DModel( FP_3DMODEL* a3DModel );
  747. INSPECT_RESULT Visit( INSPECTOR inspector, void* testData,
  748. const std::vector<KICAD_T>& aScanTypes ) override;
  749. wxString GetClass() const override
  750. {
  751. return wxT( "FOOTPRINT" );
  752. }
  753. wxString GetItemDescription( UNITS_PROVIDER* aUnitsProvider, bool aFull ) const override;
  754. BITMAPS GetMenuImage() const override;
  755. EDA_ITEM* Clone() const override;
  756. ///< @copydoc BOARD_ITEM::RunOnChildren
  757. void RunOnChildren( const std::function<void( BOARD_ITEM* )>& aFunction, RECURSE_MODE aMode ) const override;
  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. /**
  762. * Test for validity of a name of a footprint to be used in a footprint library
  763. * ( no spaces, dir separators ... ).
  764. *
  765. * @param aName is the name in library to validate.
  766. * @return true if the given name is valid
  767. */
  768. static bool IsLibNameValid( const wxString& aName );
  769. /**
  770. * Test for validity of the name in a library of the footprint ( no spaces, dir
  771. * separators ... ).
  772. *
  773. * @param aUserReadable set to false to get the list of invalid characters or true to get
  774. * a readable form (i.e ' ' = 'space' '\\t'= 'tab').
  775. *
  776. * @return the list of invalid chars in the library name.
  777. */
  778. static const wxChar* StringLibNameInvalidChars( bool aUserReadable );
  779. /**
  780. * Return true if a board footprint differs from the library version.
  781. */
  782. bool FootprintNeedsUpdate( const FOOTPRINT* aLibFP, int aCompareFlags = 0,
  783. REPORTER* aReporter = nullptr );
  784. /**
  785. * Take ownership of caller's heap allocated aInitialComments block.
  786. *
  787. * The comments are single line strings already containing the s-expression comments with
  788. * optional leading whitespace and then a '#' character followed by optional single line
  789. * text (text with no line endings, not even one). This block of single line comments
  790. * will be output upfront of any generated s-expression text in the PCBIO::Format() function.
  791. *
  792. * @note A block of single line comments constitutes a multiline block of single line
  793. * comments. That is, the block is made of consecutive single line comments.
  794. *
  795. * @param aInitialComments is a heap allocated wxArrayString or NULL, which the caller
  796. * gives up ownership of over to this FOOTPRINT.
  797. */
  798. void SetInitialComments( wxArrayString* aInitialComments )
  799. {
  800. delete m_initial_comments;
  801. m_initial_comments = aInitialComments;
  802. }
  803. /**
  804. * Calculate the ratio of total area of the footprint pads and graphical items to the
  805. * area of the footprint. Used by selection tool heuristics.
  806. *
  807. * @return the ratio.
  808. */
  809. double CoverageRatio( const GENERAL_COLLECTOR& aCollector ) const;
  810. static double GetCoverageArea( const BOARD_ITEM* aItem, const GENERAL_COLLECTOR& aCollector );
  811. /// Return the initial comments block or NULL if none, without transfer of ownership.
  812. const wxArrayString* GetInitialComments() const { return m_initial_comments; }
  813. /**
  814. * Used in DRC to test the courtyard area (a complex polygon).
  815. *
  816. * @return the courtyard polygon.
  817. */
  818. const SHAPE_POLY_SET& GetCourtyard( PCB_LAYER_ID aLayer ) const;
  819. /**
  820. * Return the cached courtyard area. No checks are performed.
  821. *
  822. * @return the cached courtyard polygon.
  823. */
  824. const SHAPE_POLY_SET& GetCachedCourtyard( PCB_LAYER_ID aLayer ) const;
  825. /**
  826. * Build complex polygons of the courtyard areas from graphic items on the courtyard layers.
  827. *
  828. * @note Set the #MALFORMED_F_COURTYARD and #MALFORMED_B_COURTYARD status flags if the given
  829. * courtyard layer does not contain a (single) closed shape.
  830. */
  831. void BuildCourtyardCaches( OUTLINE_ERROR_HANDLER* aErrorHandler = nullptr );
  832. // @copydoc BOARD_ITEM::GetEffectiveShape
  833. std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER,
  834. FLASHING aFlash = FLASHING::DEFAULT ) const override;
  835. EMBEDDED_FILES* GetEmbeddedFiles() override
  836. {
  837. return static_cast<EMBEDDED_FILES*>( this );
  838. }
  839. const EMBEDDED_FILES* GetEmbeddedFiles() const
  840. {
  841. return static_cast<const EMBEDDED_FILES*>( this );
  842. }
  843. /**
  844. * Get a list of outline fonts referenced in the footprint
  845. */
  846. std::set<KIFONT::OUTLINE_FONT*> GetFonts() const override;
  847. void EmbedFonts() override;
  848. double Similarity( const BOARD_ITEM& aOther ) const override;
  849. /// Sets the component class object pointer for this footprint
  850. void SetStaticComponentClass( const COMPONENT_CLASS* aClass ) const;
  851. /// Returns the component class for this footprint
  852. const COMPONENT_CLASS* GetStaticComponentClass() const;
  853. /// Returns the component class for this footprint
  854. const COMPONENT_CLASS* GetComponentClass() const;
  855. /// Used for display in the properties panel
  856. wxString GetComponentClassAsString() const;
  857. /// Forces immediate recalculation of the component class for this footprint
  858. void RecomputeComponentClass() const;
  859. /// Forces deferred (on next access) recalculation of the component class for this footprint
  860. void InvalidateComponentClassCache() const;
  861. /**
  862. * @brief Sets the transient component class names
  863. *
  864. * This is used during paste operations as we can't resolve the component classes immediately
  865. * until we have the true board context once the pasted items have been placed
  866. */
  867. void SetTransientComponentClassNames( const std::unordered_set<wxString>& classNames )
  868. {
  869. m_transientComponentClassNames = classNames;
  870. }
  871. /// Gets the transient component class names
  872. const std::unordered_set<wxString>& GetTransientComponentClassNames()
  873. {
  874. return m_transientComponentClassNames;
  875. }
  876. /// Remove the transient component class names
  877. void ClearTransientComponentClassNames() { m_transientComponentClassNames.clear(); };
  878. /// Resolves a set of component class names to this footprint's actual component class
  879. void ResolveComponentClassNames( BOARD* aBoard,
  880. const std::unordered_set<wxString>& aComponentClassNames );
  881. bool operator==( const BOARD_ITEM& aOther ) const override;
  882. bool operator==( const FOOTPRINT& aOther ) const;
  883. #if defined(DEBUG)
  884. virtual void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); }
  885. #endif
  886. struct cmp_drawings
  887. {
  888. bool operator()( const BOARD_ITEM* itemA, const BOARD_ITEM* itemB ) const;
  889. };
  890. struct cmp_pads
  891. {
  892. bool operator()( const PAD* aFirst, const PAD* aSecond ) const;
  893. };
  894. // TODO(JE) padstacks -- this code isn't used anywhere though
  895. #if 0
  896. struct cmp_padstack
  897. {
  898. bool operator()( const PAD* aFirst, const PAD* aSecond ) const;
  899. };
  900. #endif
  901. struct cmp_zones
  902. {
  903. bool operator()( const ZONE* aFirst, const ZONE* aSecond ) const;
  904. };
  905. protected:
  906. virtual void swapData( BOARD_ITEM* aImage ) override;
  907. void addMandatoryFields();
  908. private:
  909. std::deque<PCB_FIELD*> m_fields; // Fields, mapped by name, owned by pointer
  910. std::deque<BOARD_ITEM*> m_drawings; // Drawings in the footprint, owned by pointer
  911. std::deque<PAD*> m_pads; // Pads, owned by pointer
  912. std::vector<ZONE*> m_zones; // Rule area zones, owned by pointer
  913. std::deque<PCB_GROUP*> m_groups; // Groups, owned by pointer
  914. std::deque<PCB_POINT*> m_points; // Points, owned by pointer
  915. EDA_ANGLE m_orient; // Orientation
  916. VECTOR2I m_pos; // Position of footprint on the board in internal units.
  917. LIB_ID m_fpid; // The #LIB_ID of the FOOTPRINT.
  918. int m_attributes; // Flag bits (see FOOTPRINT_ATTR_T)
  919. int m_fpStatus; // For autoplace: flags (LOCKED, FIELDS_AUTOPLACED)
  920. int m_fileFormatVersionAtLoad;
  921. // Bounding box caching strategy:
  922. // While we attempt to notice the low-hanging fruit operations and update the bounding boxes
  923. // accordingly, we rely mostly on a "if anything changed then the caches are stale" approach.
  924. // We implement this by having PCB_BASE_FRAME's OnModify() method increment an operation
  925. // counter, and storing that as a timestamp for the various caches.
  926. // This means caches will get regenerated often -- but still far less often than if we had no
  927. // caches at all. The principal opitmization would be to change to dirty flag and make sure
  928. // that any edit that could affect the bounding boxes (including edits to the footprint
  929. // children) marked the bounding boxes dirty. It would definitely be faster -- but also more
  930. // fragile.
  931. mutable BOX2I m_cachedBoundingBox;
  932. mutable int m_boundingBoxCacheTimeStamp;
  933. mutable BOX2I m_cachedTextExcludedBBox;
  934. mutable int m_textExcludedBBoxCacheTimeStamp;
  935. mutable SHAPE_POLY_SET m_cachedHull;
  936. mutable int m_hullCacheTimeStamp;
  937. // A list of pad groups, each of which is allowed to short nets within their group.
  938. // A pad group is a comma-separated list of pad numbers.
  939. std::vector<wxString> m_netTiePadGroups;
  940. // A list of 1:N footprint item to allowed net numbers
  941. std::map<const BOARD_ITEM*, std::set<int>> m_netTieCache;
  942. /// A list of jumper pad groups, each of which is a set of pad numbers that should be jumpered
  943. /// together (treated as internally connected for the purposes of connectivity)
  944. std::vector<std::set<wxString>> m_jumperPadGroups;
  945. /// Flag that this footprint should automatically treat sets of two or more pads with the same
  946. /// number as jumpered pin groups
  947. bool m_duplicatePadNumbersAreJumpers;
  948. bool m_allowMissingCourtyard;
  949. bool m_allowSolderMaskBridges;
  950. // Optional overrides
  951. ZONE_CONNECTION m_zoneConnection;
  952. std::optional<int> m_clearance;
  953. std::optional<int> m_solderMaskMargin; // Solder mask margin
  954. std::optional<int> m_solderPasteMargin; // Solder paste margin absolute value
  955. std::optional<double> m_solderPasteMarginRatio; // Solder mask margin ratio of pad size
  956. // The final margin is the sum of these 2 values
  957. LSET m_stackupLayers; // Layers in the stackup
  958. FOOTPRINT_STACKUP m_stackupMode; // Stackup mode for this footprint
  959. LSET m_privateLayers; // Layers visible only in the footprint editor
  960. wxString m_libDescription; // File name and path for documentation file.
  961. wxString m_keywords; // Search keywords to find footprint in library.
  962. KIID_PATH m_path; // Path to associated symbol ([sheetUUID, .., symbolUUID]).
  963. wxString m_sheetname; // Name of the sheet containing the symbol for this footprint
  964. wxString m_sheetfile; // File of the sheet containing the symbol for this footprint
  965. wxString m_filters; // Footprint filters from symbol
  966. timestamp_t m_lastEditTime;
  967. int m_arflag; // Use to trace ratsnest and auto routing.
  968. KIID m_link; // Temporary logical link used during editing
  969. std::vector<FP_3DMODEL> m_3D_Drawings; // 3D models.
  970. wxArrayString* m_initial_comments; // s-expression comments in the footprint,
  971. // lazily allocated only if needed for speed
  972. SHAPE_POLY_SET m_courtyard_cache_front; // Note that a footprint can have both front and back
  973. SHAPE_POLY_SET m_courtyard_cache_back; // courtyards populated.
  974. mutable HASH_128 m_courtyard_cache_front_hash;
  975. mutable HASH_128 m_courtyard_cache_back_hash;
  976. mutable std::mutex m_courtyard_cache_mutex;
  977. std::unordered_set<wxString> m_transientComponentClassNames;
  978. std::unique_ptr<COMPONENT_CLASS_CACHE_PROXY> m_componentClassCacheProxy;
  979. // Optional unit mapping information for multi-unit symbols
  980. std::vector<FP_UNIT_INFO> m_unitInfo;
  981. };
  982. #endif // FOOTPRINT_H