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.

792 lines
30 KiB

5 years ago
4 years ago
11 years ago
5 years 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 (C) 1992-2022 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 <board_item_container.h>
  28. #include <board_item.h>
  29. #include <collectors.h>
  30. #include <convert_to_biu.h>
  31. #include <layer_ids.h> // ALL_LAYERS definition.
  32. #include <lib_id.h>
  33. #include <list>
  34. #include <zones.h>
  35. #include <convert_shape_list_to_polygon.h>
  36. #include <pcb_item_containers.h>
  37. #include <fp_text.h>
  38. #include <functional>
  39. class LINE_READER;
  40. class EDA_3D_CANVAS;
  41. class PAD;
  42. class BOARD;
  43. class MSG_PANEL_ITEM;
  44. class SHAPE;
  45. namespace KIGFX {
  46. class VIEW;
  47. }
  48. enum INCLUDE_NPTH_T
  49. {
  50. DO_NOT_INCLUDE_NPTH = false,
  51. INCLUDE_NPTH = true
  52. };
  53. /**
  54. * The set of attributes allowed within a FOOTPRINT, using FOOTPRINT::SetAttributes()
  55. * and FOOTPRINT::GetAttributes(). These are to be ORed together when calling
  56. * FOOTPRINT::SetAttributes()
  57. */
  58. enum FOOTPRINT_ATTR_T
  59. {
  60. FP_THROUGH_HOLE = 0x0001,
  61. FP_SMD = 0x0002,
  62. FP_EXCLUDE_FROM_POS_FILES = 0x0004,
  63. FP_EXCLUDE_FROM_BOM = 0x0008,
  64. FP_BOARD_ONLY = 0x0010, // Footprint has no corresponding symbol
  65. FP_JUST_ADDED = 0x0020, // Footprint just added by netlist update
  66. FP_ALLOW_SOLDERMASK_BRIDGES = 0x0040,
  67. FP_ALLOW_MISSING_COURTYARD = 0x0080
  68. };
  69. class FP_3DMODEL
  70. {
  71. public:
  72. FP_3DMODEL() :
  73. // Initialize with sensible values
  74. m_Scale { 1, 1, 1 },
  75. m_Rotation { 0, 0, 0 },
  76. m_Offset { 0, 0, 0 },
  77. m_Opacity( 1.0 ),
  78. m_Show( true )
  79. {
  80. }
  81. struct VECTOR3D
  82. {
  83. double x, y, z;
  84. };
  85. VECTOR3D m_Scale; ///< 3D model scaling factor (dimensionless)
  86. VECTOR3D m_Rotation; ///< 3D model rotation (degrees)
  87. VECTOR3D m_Offset; ///< 3D model offset (mm)
  88. double m_Opacity;
  89. wxString m_Filename; ///< The 3D shape filename in 3D library
  90. bool m_Show; ///< Include model in rendering
  91. };
  92. class FOOTPRINT : public BOARD_ITEM_CONTAINER
  93. {
  94. public:
  95. FOOTPRINT( BOARD* parent );
  96. FOOTPRINT( const FOOTPRINT& aFootprint );
  97. // Move constructor and operator needed due to std containers inside the footprint
  98. FOOTPRINT( FOOTPRINT&& aFootprint );
  99. ~FOOTPRINT();
  100. FOOTPRINT& operator=( const FOOTPRINT& aOther );
  101. FOOTPRINT& operator=( FOOTPRINT&& aOther );
  102. static inline bool ClassOf( const EDA_ITEM* aItem )
  103. {
  104. return aItem && aItem->Type() == PCB_FOOTPRINT_T;
  105. }
  106. LSET GetPrivateLayers() const { return m_privateLayers; }
  107. void SetPrivateLayers( LSET aLayers ) { m_privateLayers = aLayers; }
  108. ///< @copydoc BOARD_ITEM_CONTAINER::Add()
  109. void Add( BOARD_ITEM* aItem, ADD_MODE aMode = ADD_MODE::INSERT,
  110. bool aSkipConnectivity = false ) override;
  111. ///< @copydoc BOARD_ITEM_CONTAINER::Remove()
  112. void Remove( BOARD_ITEM* aItem, REMOVE_MODE aMode = REMOVE_MODE::NORMAL ) override;
  113. /**
  114. * Clear (i.e. force the ORPHANED dummy net info) the net info which
  115. * depends on a given board for all pads of the footprint.
  116. *
  117. * This is needed when a footprint is copied between the fp editor and
  118. * the board editor for instance, because net info become fully broken
  119. */
  120. void ClearAllNets();
  121. /**
  122. * Old footprints do not alway have a valid UUID (some can be set to null uuid)
  123. * However null UUIDs, having a special meaning in editor, create issues when
  124. * editing a footprint
  125. * So all null uuids a re replaced by a valid uuid
  126. * @return true if at least one uuid is changed, false if no change
  127. */
  128. bool FixUuids();
  129. /**
  130. * Return the bounding box containing pads when the footprint is on the front side,
  131. * orientation 0, position 0,0.
  132. *
  133. * Mainly used in Gerber place file to draw a footprint outline when the courtyard
  134. * is missing or broken.
  135. *
  136. * @return The rectangle containing the pads for the normalized footprint.
  137. */
  138. EDA_RECT GetFpPadsLocalBbox() const;
  139. /**
  140. * Return a bounding polygon for the shapes and pads in the footprint.
  141. *
  142. * This operation is slower but more accurate than calculating a bounding box.
  143. */
  144. SHAPE_POLY_SET GetBoundingHull() const;
  145. // Virtual function
  146. const EDA_RECT GetBoundingBox() const override;
  147. const EDA_RECT GetBoundingBox( bool aIncludeText, bool aIncludeInvisibleText ) const;
  148. PADS& Pads() { return m_pads; }
  149. const PADS& Pads() const { return m_pads; }
  150. DRAWINGS& GraphicalItems() { return m_drawings; }
  151. const DRAWINGS& GraphicalItems() const { return m_drawings; }
  152. FP_ZONES& Zones() { return m_fp_zones; }
  153. const FP_ZONES& Zones() const { return m_fp_zones; }
  154. FP_GROUPS& Groups() { return m_fp_groups; }
  155. const FP_GROUPS& Groups() const { return m_fp_groups; }
  156. bool HasThroughHolePads() const;
  157. std::vector<FP_3DMODEL>& Models() { return m_3D_Drawings; }
  158. const std::vector<FP_3DMODEL>& Models() const { return m_3D_Drawings; }
  159. void SetPosition( const VECTOR2I& aPos ) override;
  160. VECTOR2I GetPosition() const override { return m_pos; }
  161. void SetOrientation( const EDA_ANGLE& aNewAngle );
  162. EDA_ANGLE GetOrientation() const { return m_orient; }
  163. // For property system:
  164. void SetOrientationDegrees( double aOrientation )
  165. {
  166. SetOrientation( EDA_ANGLE( aOrientation, DEGREES_T ) );
  167. }
  168. double GetOrientationDegrees() const
  169. {
  170. return m_orient.AsDegrees();
  171. }
  172. const LIB_ID& GetFPID() const { return m_fpid; }
  173. void SetFPID( const LIB_ID& aFPID ) { m_fpid = aFPID; }
  174. const wxString& GetDescription() const { return m_doc; }
  175. void SetDescription( const wxString& aDoc ) { m_doc = aDoc; }
  176. const wxString& GetKeywords() const { return m_keywords; }
  177. void SetKeywords( const wxString& aKeywords ) { m_keywords = aKeywords; }
  178. const KIID_PATH& GetPath() const { return m_path; }
  179. void SetPath( const KIID_PATH& aPath ) { m_path = aPath; }
  180. int GetLocalSolderMaskMargin() const { return m_localSolderMaskMargin; }
  181. void SetLocalSolderMaskMargin( int aMargin ) { m_localSolderMaskMargin = aMargin; }
  182. int GetLocalClearance() const { return m_localClearance; }
  183. void SetLocalClearance( int aClearance ) { m_localClearance = aClearance; }
  184. int GetLocalClearance( wxString* aSource ) const
  185. {
  186. if( aSource )
  187. *aSource = wxString::Format( _( "footprint %s" ), GetReference() );
  188. return m_localClearance;
  189. }
  190. int GetLocalSolderPasteMargin() const { return m_localSolderPasteMargin; }
  191. void SetLocalSolderPasteMargin( int aMargin ) { m_localSolderPasteMargin = aMargin; }
  192. double GetLocalSolderPasteMarginRatio() const { return m_localSolderPasteMarginRatio; }
  193. void SetLocalSolderPasteMarginRatio( double aRatio ) { m_localSolderPasteMarginRatio = aRatio; }
  194. void SetZoneConnection( ZONE_CONNECTION aType ) { m_zoneConnection = aType; }
  195. ZONE_CONNECTION GetZoneConnection() const { return m_zoneConnection; }
  196. int GetAttributes() const { return m_attributes; }
  197. void SetAttributes( int aAttributes ) { m_attributes = aAttributes; }
  198. void SetFlag( int aFlag ) { m_arflag = aFlag; }
  199. void IncrementFlag() { m_arflag += 1; }
  200. int GetFlag() const { return m_arflag; }
  201. // A bit of a hack until net ties are supported as first class citizens
  202. bool IsNetTie() const
  203. {
  204. return GetKeywords().StartsWith( wxT( "net tie" ) );
  205. }
  206. /**
  207. * Returns the most likely attribute based on pads
  208. * Either FP_THROUGH_HOLE/FP_SMD/OTHER(0)
  209. * @return 0/FP_SMD/FP_THROUGH_HOLE
  210. */
  211. int GetLikelyAttribute() const;
  212. void Move( const VECTOR2I& aMoveVector ) override;
  213. void Rotate( const VECTOR2I& aRotCentre, const EDA_ANGLE& aAngle ) override;
  214. void Flip( const VECTOR2I& aCentre, bool aFlipLeftRight ) override;
  215. /**
  216. * Move the reference point of the footprint.
  217. *
  218. * It looks like a move footprint:
  219. * the footprints elements (pads, outlines, edges .. ) are moved
  220. * However:
  221. * - the footprint position is not modified.
  222. * - the relative (local) coordinates of these items are modified
  223. * (a move footprint does not change these local coordinates,
  224. * but changes the footprint position)
  225. */
  226. void MoveAnchorPosition( const VECTOR2I& aMoveVector );
  227. /**
  228. * @return true if the footprint is flipped, i.e. on the back side of the board
  229. */
  230. bool IsFlipped() const { return GetLayer() == B_Cu; }
  231. /**
  232. * A special IsOnLayer for footprints: return true if the footprint contains only items on the
  233. * given layer, even if that layer is not one of the valid footprint layers F_Cu and B_Cu.
  234. * This allows selection of "graphic" footprints that contain only silkscreen, for example.
  235. */
  236. bool IsOnLayer( PCB_LAYER_ID aLayer ) const override;
  237. // m_footprintStatus bits:
  238. #define FP_is_LOCKED 0x01 ///< footprint LOCKED: no autoplace allowed
  239. #define FP_is_PLACED 0x02 ///< In autoplace: footprint automatically placed
  240. #define FP_to_PLACE 0x04 ///< In autoplace: footprint waiting for autoplace
  241. #define FP_PADS_are_LOCKED 0x08
  242. bool IsLocked() const override
  243. {
  244. return ( m_fpStatus & FP_is_LOCKED ) != 0;
  245. }
  246. /**
  247. * Set the #MODULE_is_LOCKED bit in the m_ModuleStatus.
  248. *
  249. * @param isLocked true means turn on locked status, else unlock
  250. */
  251. void SetLocked( bool isLocked ) override
  252. {
  253. if( isLocked )
  254. m_fpStatus |= FP_is_LOCKED;
  255. else
  256. m_fpStatus &= ~FP_is_LOCKED;
  257. }
  258. /**
  259. * @return true if the footprint is flagged with conflicting with some item
  260. */
  261. bool IsConflicting() const;
  262. bool IsPlaced() const { return m_fpStatus & FP_is_PLACED; }
  263. void SetIsPlaced( bool isPlaced )
  264. {
  265. if( isPlaced )
  266. m_fpStatus |= FP_is_PLACED;
  267. else
  268. m_fpStatus &= ~FP_is_PLACED;
  269. }
  270. bool NeedsPlaced() const { return m_fpStatus & FP_to_PLACE; }
  271. void SetNeedsPlaced( bool needsPlaced )
  272. {
  273. if( needsPlaced )
  274. m_fpStatus |= FP_to_PLACE;
  275. else
  276. m_fpStatus &= ~FP_to_PLACE;
  277. }
  278. bool LegacyPadsLocked() const { return m_fpStatus & FP_PADS_are_LOCKED; }
  279. /**
  280. * Test if footprint attributes for type (SMD/Through hole/Other) match the expected
  281. * type based on the pads in the footprint.
  282. * Footprints with plated through-hole pads should usually be marked through hole even if they
  283. * also have SMD because they might not be auto-placed. Exceptions to this might be shielded
  284. * connectors. Otherwise, footprints with SMD pads should be marked SMD.
  285. * Footprints with no connecting pads should be marked "Other"
  286. *
  287. * @param aErrorHandler callback to handle the error messages generated
  288. */
  289. void CheckFootprintAttributes( const std::function<void( const wxString& )>& aErrorHandler );
  290. /**
  291. * Run non-board-specific DRC checks on footprint's pads. These are the checks supported by
  292. * both the PCB DRC and the Footprint Editor Footprint Checker.
  293. *
  294. * @param aErrorHandler callback to handle the error messages generated
  295. */
  296. void CheckPads( const std::function<void( const PAD*, int, const wxString& )>& aErrorHandler );
  297. /**
  298. * Check for overlapping, different-numbered pads.
  299. *
  300. * @param aErrorHandler callback to handle the error messages generated
  301. */
  302. void CheckOverlappingPads( const std::function<void( const PAD*, const PAD*,
  303. const VECTOR2I& )>& aErrorHandler );
  304. /**
  305. * Generate pads shapes on layer \a aLayer as polygons and adds these polygons to
  306. * \a aCornerBuffer.
  307. *
  308. * Useful to generate a polygonal representation of a footprint in 3D view and plot functions,
  309. * when a full polygonal approach is needed.
  310. *
  311. * @param aLayer is the layer to consider, or #UNDEFINED_LAYER to consider all layers.
  312. * @param aCornerBuffer i the buffer to store polygons.
  313. * @param aClearance is an additional size to add to pad shapes.
  314. * @param aMaxError is the maximum deviation from true for arcs.
  315. * @param aSkipNPTHPadsWihNoCopper if true, do not add a NPTH pad shape, if the shape has
  316. * same size and position as the hole. Usually, these pads are not drawn on copper
  317. * layers, because there is actually no copper
  318. * Due to diff between layers and holes, these pads must be skipped to be sure
  319. * there is no copper left on the board (for instance when creating Gerber Files or
  320. * 3D shapes). Defaults to false.
  321. * @param aSkipPlatedPads is used on 3D-Viewer to extract plated and non-plated pads.
  322. * @param aSkipNonPlatedPads is used on 3D-Viewer to extract plated and plated pads.
  323. */
  324. void TransformPadsWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
  325. PCB_LAYER_ID aLayer, int aClearance,
  326. int aMaxError, ERROR_LOC aErrorLoc,
  327. bool aSkipNPTHPadsWihNoCopper = false,
  328. bool aSkipPlatedPads = false,
  329. bool aSkipNonPlatedPads = false ) const;
  330. /**
  331. * Generate shapes of graphic items (outlines) on layer \a aLayer as polygons and adds these
  332. * polygons to \a aCornerBuffer.
  333. *
  334. * Useful to generate a polygonal representation of a footprint in 3D view and plot functions,
  335. * when a full polygonal approach is needed.
  336. *
  337. * @param aLayer is the layer to consider, or #UNDEFINED_LAYER to consider all.
  338. * @param aCornerBuffer is the buffer to store polygons.
  339. * @param aClearance is a value to inflate shapes.
  340. * @param aError is the maximum error between true arc and polygon approximation.
  341. * @param aIncludeText set to true to transform text shapes.
  342. * @param aIncludeShapes set to true to transform footprint shapes.
  343. */
  344. void TransformFPShapesWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
  345. PCB_LAYER_ID aLayer, int aClearance,
  346. int aError, ERROR_LOC aErrorLoc,
  347. bool aIncludeText = true,
  348. bool aIncludeShapes = true ) const;
  349. /**
  350. * This function is the same as TransformGraphicShapesWithClearanceToPolygonSet
  351. * but only generate text.
  352. */
  353. void TransformFPTextWithClearanceToPolygonSet( SHAPE_POLY_SET& aCornerBuffer,
  354. PCB_LAYER_ID aLayer, int aClearance,
  355. int aError, ERROR_LOC aErrorLoc ) const
  356. {
  357. TransformFPShapesWithClearanceToPolygon( aCornerBuffer, aLayer, aClearance, aError,
  358. aErrorLoc, true, false );
  359. }
  360. /**
  361. * Return the list of system text vars for this footprint.
  362. */
  363. void GetContextualTextVars( wxArrayString* aVars ) const;
  364. /**
  365. * Resolve any references to system tokens supported by the component.
  366. *
  367. * @param aDepth a counter to limit recursion and circular references.
  368. */
  369. bool ResolveTextVar( wxString* token, int aDepth = 0 ) const;
  370. ///< @copydoc EDA_ITEM::GetMsgPanelInfo
  371. void GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList ) override;
  372. bool HitTest( const VECTOR2I& aPosition, int aAccuracy = 0 ) const override;
  373. /**
  374. * Test if a point is inside the bounding polygon of the footprint.
  375. *
  376. * The other hit test methods are just checking the bounding box, which can be quite
  377. * inaccurate for rotated or oddly-shaped footprints.
  378. *
  379. * @param aPosition is the point to test
  380. * @return true if aPosition is inside the bounding polygon
  381. */
  382. bool HitTestAccurate( const VECTOR2I& aPosition, int aAccuracy = 0 ) const;
  383. bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override;
  384. /**
  385. * @return reference designator text.
  386. */
  387. const wxString& GetReference() const
  388. {
  389. return m_reference->GetText();
  390. }
  391. /**
  392. * @param aReference A reference to a wxString object containing the reference designator
  393. * text.
  394. */
  395. void SetReference( const wxString& aReference )
  396. {
  397. m_reference->SetText( aReference );
  398. }
  399. /**
  400. * Bump the current reference by \a aDelta.
  401. */
  402. void IncrementReference( int aDelta );
  403. /**
  404. * @return the value text.
  405. */
  406. const wxString& GetValue() const
  407. {
  408. return m_value->GetText();
  409. }
  410. /**
  411. * @param aValue A reference to a wxString object containing the value text.
  412. */
  413. void SetValue( const wxString& aValue )
  414. {
  415. m_value->SetText( aValue );
  416. }
  417. /// read/write accessors:
  418. FP_TEXT& Value() { return *m_value; }
  419. FP_TEXT& Reference() { return *m_reference; }
  420. /// The const versions to keep the compiler happy.
  421. FP_TEXT& Value() const { return *m_value; }
  422. FP_TEXT& Reference() const { return *m_reference; }
  423. const std::map<wxString, wxString>& GetProperties() const { return m_properties; }
  424. void SetProperties( const std::map<wxString, wxString>& aProps ) { m_properties = aProps; }
  425. const wxString& GetProperty( const wxString& aKey) { return m_properties[ aKey ]; }
  426. bool HasProperty( const wxString& aKey)
  427. {
  428. return m_properties.find( aKey ) != m_properties.end();
  429. }
  430. void SetProperty( const wxString& aKey, const wxString& aVal ) { m_properties[ aKey ] = aVal; }
  431. /**
  432. * Return a #PAD with a matching number.
  433. *
  434. * @note Numbers may not be unique depending on how the footprint was created.
  435. *
  436. * @param aPadNumber the pad number to find.
  437. * @param aSearchAfterMe = not nullptr to find a pad living after aAfterMe
  438. * @return the first matching numbered #PAD is returned or NULL if not found.
  439. */
  440. PAD* FindPadByNumber( const wxString& aPadNumber, PAD* aSearchAfterMe = nullptr ) const;
  441. /**
  442. * Get a pad at \a aPosition on \a aLayerMask in the footprint.
  443. *
  444. * @param aPosition A VECTOR2I object containing the position to hit test.
  445. * @param aLayerMask A layer or layers to mask the hit test.
  446. * @return A pointer to a #PAD object if found otherwise NULL.
  447. */
  448. PAD* GetPad( const VECTOR2I& aPosition, LSET aLayerMask = LSET::AllLayersMask() );
  449. PAD* GetTopLeftPad();
  450. /**
  451. * Return the number of pads.
  452. *
  453. * @param aIncludeNPTH includes non-plated through holes when true. Does not include
  454. * non-plated through holes when false.
  455. * @return the number of pads according to \a aIncludeNPTH.
  456. */
  457. unsigned GetPadCount( INCLUDE_NPTH_T aIncludeNPTH = INCLUDE_NPTH_T(INCLUDE_NPTH) ) const;
  458. /**
  459. * Return the number of unique non-blank pads.
  460. *
  461. * A complex pad can be built with many pads having the same pad name to create a complex
  462. * shape or fragmented solder paste areas.
  463. *
  464. * @param aIncludeNPTH includes non-plated through holes when true. Does not include
  465. * non-plated through holes when false.
  466. * @return the number of unique pads according to \a aIncludeNPTH.
  467. */
  468. unsigned GetUniquePadCount( INCLUDE_NPTH_T aIncludeNPTH = INCLUDE_NPTH_T(INCLUDE_NPTH) ) const;
  469. /**
  470. * Return the next available pad number in the footprint.
  471. *
  472. * @param aFillSequenceGaps true if the numbering should "fill in" gaps in the sequence,
  473. * else return the highest value + 1
  474. * @return the next available pad number
  475. */
  476. wxString GetNextPadNumber( const wxString& aLastPadName ) const;
  477. /**
  478. * Get the type of footprint
  479. * @return "SMD"/"Through hole"/"Other" based on attributes
  480. */
  481. wxString GetTypeName() const;
  482. double GetArea( int aPadding = 0 ) const;
  483. KIID GetLink() const { return m_link; }
  484. void SetLink( const KIID& aLink ) { m_link = aLink; }
  485. BOARD_ITEM* Duplicate() const override;
  486. /**
  487. * Duplicate a given item within the footprint, optionally adding it to the board.
  488. *
  489. * @return the new item, or NULL if the item could not be duplicated.
  490. */
  491. BOARD_ITEM* DuplicateItem( const BOARD_ITEM* aItem, bool aAddToFootprint = false );
  492. /**
  493. * Add \a a3DModel definition to the end of the 3D model list.
  494. *
  495. * @param a3DModel A pointer to a #FP_3DMODEL to add to the list.
  496. */
  497. void Add3DModel( FP_3DMODEL* a3DModel );
  498. SEARCH_RESULT Visit( INSPECTOR inspector, void* testData, const KICAD_T scanTypes[] ) override;
  499. wxString GetClass() const override
  500. {
  501. return wxT( "FOOTPRINT" );
  502. }
  503. wxString GetSelectMenuText( EDA_UNITS aUnits ) const override;
  504. BITMAPS GetMenuImage() const override;
  505. EDA_ITEM* Clone() const override;
  506. /**
  507. * Invoke a function on all BOARD_ITEMs that belong to the footprint (pads, drawings, texts).
  508. *
  509. * @note This function should not add or remove items to the footprint.
  510. *
  511. * @param aFunction is the function to be invoked.
  512. */
  513. void RunOnChildren( const std::function<void (BOARD_ITEM*)>& aFunction ) const;
  514. /**
  515. * Return a set of all layers that this footprint has drawings on similar to ViewGetLayers().
  516. *
  517. * @param aLayers is an array to store layer ids.
  518. * @param aCount is the number of layers stored in the array.
  519. * @param aIncludePads controls whether to also include pad layers.
  520. */
  521. void GetAllDrawingLayers( int aLayers[], int& aCount, bool aIncludePads = true ) const;
  522. virtual void ViewGetLayers( int aLayers[], int& aCount ) const override;
  523. double ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const override;
  524. virtual const BOX2I ViewBBox() const override;
  525. /**
  526. * Test for validity of a name of a footprint to be used in a footprint library
  527. * ( no spaces, dir separators ... ).
  528. *
  529. * @param aName is the name in library to validate.
  530. * @return true if the given name is valid
  531. */
  532. static bool IsLibNameValid( const wxString& aName );
  533. /**
  534. * Test for validity of the name in a library of the footprint ( no spaces, dir
  535. * separators ... ).
  536. *
  537. * @param aUserReadable set to false to get the list of invalid characters or true to get
  538. * a readable form (i.e ' ' = 'space' '\\t'= 'tab').
  539. *
  540. * @return the list of invalid chars in the library name.
  541. */
  542. static const wxChar* StringLibNameInvalidChars( bool aUserReadable );
  543. /**
  544. * Return true if a board footprint differs from the library version.
  545. */
  546. bool FootprintNeedsUpdate( const FOOTPRINT* aLibFootprint );
  547. /**
  548. * Take ownership of caller's heap allocated aInitialComments block.
  549. *
  550. * The comments are single line strings already containing the s-expression comments with
  551. * optional leading whitespace and then a '#' character followed by optional single line
  552. * text (text with no line endings, not even one). This block of single line comments
  553. * will be output upfront of any generated s-expression text in the PCBIO::Format() function.
  554. *
  555. * @note A block of single line comments constitutes a multiline block of single line
  556. * comments. That is, the block is made of consecutive single line comments.
  557. *
  558. * @param aInitialComments is a heap allocated wxArrayString or NULL, which the caller
  559. * gives up ownership of over to this FOOTPRINT.
  560. */
  561. void SetInitialComments( wxArrayString* aInitialComments )
  562. {
  563. delete m_initial_comments;
  564. m_initial_comments = aInitialComments;
  565. }
  566. /**
  567. * Calculate the ratio of total area of the footprint pads and graphical items to the
  568. * area of the footprint. Used by selection tool heuristics.
  569. *
  570. * @return the ratio.
  571. */
  572. double CoverageRatio( const GENERAL_COLLECTOR& aCollector ) const;
  573. static double GetCoverageArea( const BOARD_ITEM* aItem, const GENERAL_COLLECTOR& aCollector );
  574. ///< Return the initial comments block or NULL if none, without transfer of ownership.
  575. const wxArrayString* GetInitialComments() const { return m_initial_comments; }
  576. /**
  577. * Used in DRC to test the courtyard area (a complex polygon).
  578. *
  579. * @return the courtyard polygon.
  580. */
  581. const SHAPE_POLY_SET& GetPolyCourtyard( PCB_LAYER_ID aLayer ) const
  582. {
  583. if( IsBackLayer( aLayer ) )
  584. return m_poly_courtyard_back;
  585. else
  586. return m_poly_courtyard_front;
  587. }
  588. /**
  589. * Build complex polygons of the courtyard areas from graphic items on the courtyard layers.
  590. *
  591. * @note Set the #MALFORMED_F_COURTYARD and #MALFORMED_B_COURTYARD status flags if the given
  592. * courtyard layer does not contain a (single) closed shape.
  593. */
  594. void BuildPolyCourtyards( OUTLINE_ERROR_HANDLER* aErrorHandler = nullptr );
  595. virtual std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER,
  596. FLASHING aFlash = FLASHING::DEFAULT ) const override;
  597. virtual void SwapData( BOARD_ITEM* aImage ) override;
  598. struct cmp_drawings
  599. {
  600. bool operator()( const BOARD_ITEM* itemA, const BOARD_ITEM* itemB ) const;
  601. };
  602. struct cmp_pads
  603. {
  604. bool operator()( const PAD* aFirst, const PAD* aSecond ) const;
  605. };
  606. struct cmp_zones
  607. {
  608. bool operator()( const FP_ZONE* aFirst, const FP_ZONE* aSecond ) const;
  609. };
  610. #if defined(DEBUG)
  611. virtual void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); }
  612. #endif
  613. private:
  614. DRAWINGS m_drawings; // BOARD_ITEMs for drawings on the board, owned by pointer.
  615. PADS m_pads; // PAD items, owned by pointer
  616. FP_ZONES m_fp_zones; // FP_ZONE items, owned by pointer
  617. FP_GROUPS m_fp_groups; // PCB_GROUP items, owned by pointer
  618. EDA_ANGLE m_orient; // Orientation
  619. VECTOR2I m_pos; // Position of footprint on the board in internal units.
  620. FP_TEXT* m_reference; // Component reference designator value (U34, R18..)
  621. FP_TEXT* m_value; // Component value (74LS00, 22K..)
  622. LIB_ID m_fpid; // The #LIB_ID of the FOOTPRINT.
  623. int m_attributes; // Flag bits (see FOOTPRINT_ATTR_T)
  624. int m_fpStatus; // For autoplace: flags (LOCKED, FIELDS_AUTOPLACED)
  625. // Bounding box caching strategy:
  626. // While we attempt to notice the low-hanging fruit operations and update the bounding boxes
  627. // accordingly, we rely mostly on a "if anything changed then the caches are stale" approach.
  628. // We implement this by having PCB_BASE_FRAME's OnModify() method increment an operation
  629. // counter, and storing that as a timestamp for the various caches.
  630. // This means caches will get regenerated often -- but still far less often than if we had no
  631. // caches at all. The principal opitmization would be to change to dirty flag and make sure
  632. // that any edit that could affect the bounding boxes (including edits to the footprint
  633. // children) marked the bounding boxes dirty. It would definitely be faster -- but also more
  634. // fragile.
  635. mutable EDA_RECT m_cachedBoundingBox;
  636. mutable int m_boundingBoxCacheTimeStamp;
  637. mutable EDA_RECT m_cachedVisibleBBox;
  638. mutable int m_visibleBBoxCacheTimeStamp;
  639. mutable EDA_RECT m_cachedTextExcludedBBox;
  640. mutable int m_textExcludedBBoxCacheTimeStamp;
  641. mutable SHAPE_POLY_SET m_cachedHull;
  642. mutable int m_hullCacheTimeStamp;
  643. ZONE_CONNECTION m_zoneConnection;
  644. int m_localClearance;
  645. int m_localSolderMaskMargin; // Solder mask margin
  646. int m_localSolderPasteMargin; // Solder paste margin absolute value
  647. double m_localSolderPasteMarginRatio; // Solder mask margin ratio value of pad size
  648. wxString m_doc; // File name and path for documentation file.
  649. wxString m_keywords; // Search keywords to find footprint in library.
  650. KIID_PATH m_path; // Path to associated symbol ([sheetUUID, .., symbolUUID]).
  651. timestamp_t m_lastEditTime;
  652. int m_arflag; // Use to trace ratsnest and auto routing.
  653. KIID m_link; // Temporary logical link used during editing
  654. LSET m_privateLayers; // Layers visible only in the footprint editor
  655. std::vector<FP_3DMODEL> m_3D_Drawings; // 3D models.
  656. std::map<wxString, wxString> m_properties;
  657. wxArrayString* m_initial_comments; // s-expression comments in the footprint,
  658. // lazily allocated only if needed for speed
  659. SHAPE_POLY_SET m_poly_courtyard_front; // Note that a footprint can have both front and back
  660. SHAPE_POLY_SET m_poly_courtyard_back; // courtyards populated.
  661. };
  662. #endif // FOOTPRINT_H