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.

518 lines
15 KiB

3 years ago
2 years ago
  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2018 Jean-Pierre Charras, jp.charras at wandadoo.fr
  5. * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License
  9. * as published by the Free Software Foundation; either version 2
  10. * of the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, you may find one here:
  19. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  20. * or you may search the http://www.gnu.org website for the version 2 license,
  21. * or you may write to the Free Software Foundation, Inc.,
  22. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  23. */
  24. #pragma once
  25. #include <core/mirror.h>
  26. #include <eda_item.h>
  27. #include <geometry/approximation.h>
  28. #include <layer_ids.h>
  29. #include <lseq.h>
  30. #include <lset.h>
  31. #include <stroke_params.h>
  32. #include <geometry/eda_angle.h>
  33. class BOARD;
  34. class BOARD_DESIGN_SETTINGS;
  35. class BOARD_ITEM_CONTAINER;
  36. class SHAPE_POLY_SET;
  37. class SHAPE_SEGMENT;
  38. class PCB_BASE_FRAME;
  39. class SHAPE;
  40. class PCB_GROUP;
  41. class FOOTPRINT;
  42. namespace KIFONT
  43. {
  44. class METRICS;
  45. }
  46. /**
  47. * Conditionally flashed vias and pads that interact with zones of different priority can be
  48. * very squirrelly.
  49. *
  50. * In particular, when filling a higher-priority zone that does -not- connect to a via/pad, we
  51. * don't know whether or not a lower-priority zone will subsequently connect -- so we can't
  52. * determine clearance because we don't know what the final flashing state will be.
  53. *
  54. * We therefore force the flashing state if the highest-priority zone with the same net -can-
  55. * connect (whether or not it does in the end), and otherwise force the zone-connection state
  56. * to no-connection (even though a lower priority zone -might- have otherwise connected to it.
  57. */
  58. enum ZONE_LAYER_OVERRIDE
  59. {
  60. ZLO_NONE,
  61. ZLO_FORCE_FLASHED,
  62. ZLO_FORCE_NO_ZONE_CONNECTION
  63. };
  64. /**
  65. * A base class for any item which can be embedded within the #BOARD container class, and
  66. * therefore instances of derived classes should only be found in Pcbnew or other programs
  67. * that use class #BOARD and its contents.
  68. */
  69. class BOARD_ITEM : public EDA_ITEM
  70. {
  71. public:
  72. BOARD_ITEM( BOARD_ITEM* aParent, KICAD_T idtype, PCB_LAYER_ID aLayer = F_Cu ) :
  73. EDA_ITEM( aParent, idtype, false, true ),
  74. m_layer( aLayer ),
  75. m_isKnockout( false ),
  76. m_isLocked( false ),
  77. m_group( nullptr )
  78. {
  79. }
  80. ~BOARD_ITEM();
  81. virtual void CopyFrom( const BOARD_ITEM* aOther );
  82. void SetParentGroup( PCB_GROUP* aGroup ) { m_group = aGroup; }
  83. PCB_GROUP* GetParentGroup() const { return m_group; }
  84. // Do not create a copy constructor & operator=.
  85. // The ones generated by the compiler are adequate.
  86. int GetX() const
  87. {
  88. VECTOR2I p = GetPosition();
  89. return p.x;
  90. }
  91. int GetY() const
  92. {
  93. VECTOR2I p = GetPosition();
  94. return p.y;
  95. }
  96. /**
  97. * This defaults to the center of the bounding box if not overridden.
  98. *
  99. * @return center point of the item
  100. */
  101. virtual VECTOR2I GetCenter() const
  102. {
  103. return GetBoundingBox().GetCenter();
  104. }
  105. void SetX( int aX )
  106. {
  107. VECTOR2I p( aX, GetY() );
  108. SetPosition( p );
  109. }
  110. void SetY( int aY )
  111. {
  112. VECTOR2I p( GetX(), aY );
  113. SetPosition( p );
  114. }
  115. /**
  116. * Returns information if the object is derived from BOARD_CONNECTED_ITEM.
  117. *
  118. * @return True if the object is of BOARD_CONNECTED_ITEM type, false otherwise.
  119. */
  120. virtual bool IsConnected() const
  121. {
  122. return false;
  123. }
  124. /**
  125. * Return a measure of how likely the other object is to represent the same
  126. * object. The scale runs from 0.0 (definitely different objects) to 1.0 (same)
  127. *
  128. * This is a pure virtual function. Derived classes must implement this.
  129. */
  130. virtual double Similarity( const BOARD_ITEM& aItem ) const = 0;
  131. virtual bool operator==( const BOARD_ITEM& aItem ) const = 0;
  132. /**
  133. * @return true if the object is on any copper layer, false otherwise.
  134. */
  135. virtual bool IsOnCopperLayer() const
  136. {
  137. return IsCopperLayer( GetLayer() );
  138. }
  139. virtual bool HasHole() const
  140. {
  141. return false;
  142. }
  143. virtual bool HasDrilledHole() const
  144. {
  145. return false;
  146. }
  147. /**
  148. * Checks if the given object is tented (its copper shape is covered by solder mask) on a given
  149. * side of the board.
  150. * @param aLayer is the layer to check tenting mode for: F_Cu and F_Mask are treated identically
  151. * as are B_Cu and B_Mask
  152. * @return true if the object is tented on the given side
  153. */
  154. virtual bool IsTented( PCB_LAYER_ID aLayer ) const
  155. {
  156. return false;
  157. }
  158. /**
  159. * A value of wxPoint(0,0) which can be passed to the Draw() functions.
  160. */
  161. static VECTOR2I ZeroOffset;
  162. /**
  163. * Some pad shapes can be complex (rounded/chamfered rectangle), even without considering
  164. * custom shapes. This routine returns a COMPOUND shape (set of simple shapes which make
  165. * up the pad for use with routing, collision determination, etc).
  166. *
  167. * @note This list can contain a SHAPE_SIMPLE (a simple single-outline non-intersecting
  168. * polygon), but should never contain a SHAPE_POLY_SET (a complex polygon consisting of
  169. * multiple outlines and/or holes).
  170. *
  171. * @param aLayer in case of items spanning multiple layers, only the shapes belonging to aLayer
  172. * will be returned. Pass UNDEFINED_LAYER to return shapes for all layers.
  173. * @param aFlash optional parameter allowing a caller to force the pad to be flashed (or not
  174. * flashed) on the current layer (default is to honour the pad's setting and
  175. * the current connections for the given layer).
  176. */
  177. virtual std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER,
  178. FLASHING aFlash = FLASHING::DEFAULT ) const;
  179. virtual std::shared_ptr<SHAPE_SEGMENT> GetEffectiveHoleShape() const;
  180. /**
  181. * Invoke a function on all children.
  182. *
  183. * @note This function should not add or remove items to the parent.
  184. */
  185. virtual void RunOnChildren( const std::function<void( BOARD_ITEM* )>& aFunction, RECURSE_MODE aMode ) const {}
  186. BOARD_ITEM_CONTAINER* GetParent() const { return (BOARD_ITEM_CONTAINER*) m_parent; }
  187. FOOTPRINT* GetParentFootprint() const;
  188. VECTOR2I GetFPRelativePosition() const;
  189. void SetFPRelativePosition( const VECTOR2I& aPos );
  190. /**
  191. * Check if this item has line stoke properties.
  192. *
  193. * @see #STROKE_PARAMS
  194. */
  195. virtual bool HasLineStroke() const { return false; }
  196. virtual STROKE_PARAMS GetStroke() const;
  197. virtual void SetStroke( const STROKE_PARAMS& aStroke );
  198. const KIFONT::METRICS& GetFontMetrics() const;
  199. /**
  200. * Return the primary layer this item is on.
  201. */
  202. virtual PCB_LAYER_ID GetLayer() const { return m_layer; }
  203. /**
  204. * Return the total number of layers for the board that this item resides on.
  205. */
  206. virtual int BoardLayerCount() const;
  207. /**
  208. * Return the total number of copper layers for the board that this item resides on.
  209. */
  210. virtual int BoardCopperLayerCount() const;
  211. /**
  212. * Return the LSET for the board that this item resides on.
  213. */
  214. virtual LSET BoardLayerSet() const;
  215. /**
  216. * Return a std::bitset of all layers on which the item physically resides.
  217. */
  218. virtual LSET GetLayerSet() const
  219. {
  220. if( m_layer == UNDEFINED_LAYER )
  221. return LSET();
  222. else
  223. return LSET( { m_layer } );
  224. }
  225. virtual void SetLayerSet( const LSET& aLayers )
  226. {
  227. if( aLayers.count() == 1 )
  228. {
  229. SetLayer( aLayers.Seq()[0] );
  230. return;
  231. }
  232. wxFAIL_MSG( wxT( "Attempted to SetLayerSet() on a single-layer object." ) );
  233. // Derived classes which support multiple layers must implement this
  234. }
  235. bool IsSideSpecific() const;
  236. /**
  237. * Set the layer this item is on.
  238. *
  239. * This method is virtual because some items (in fact: class DIMENSION)
  240. * have a slightly different initialization.
  241. *
  242. * @param aLayer The layer number.
  243. */
  244. virtual void SetLayer( PCB_LAYER_ID aLayer )
  245. {
  246. m_layer = aLayer;
  247. }
  248. /**
  249. * Create a copy of this #BOARD_ITEM.
  250. */
  251. virtual BOARD_ITEM* Duplicate() const;
  252. /**
  253. * Swap data between \a aItem and \a aImage.
  254. *
  255. * \a aItem and \a aImage should have the same type.
  256. *
  257. * Used in undo and redo commands to swap values between an item and its copy.
  258. * Only values like layer, size .. which are modified by editing are swapped.
  259. *
  260. * @param aImage the item image which contains data to swap.
  261. */
  262. void SwapItemData( BOARD_ITEM* aImage );
  263. /**
  264. * Test to see if this object is on the given layer.
  265. *
  266. * Virtual so objects like #PAD, which reside on multiple layers can do their own form
  267. * of testing.
  268. *
  269. * @param aLayer The layer to test for.
  270. * @return true if on given layer, else false.
  271. */
  272. virtual bool IsOnLayer( PCB_LAYER_ID aLayer ) const
  273. {
  274. return m_layer == aLayer;
  275. }
  276. virtual bool IsKnockout() const { return m_isKnockout; }
  277. virtual void SetIsKnockout( bool aKnockout ) { m_isKnockout = aKnockout; }
  278. virtual bool IsLocked() const;
  279. virtual void SetLocked( bool aLocked ) { m_isLocked = aLocked; }
  280. virtual void StyleFromSettings( const BOARD_DESIGN_SETTINGS& settings ) { }
  281. /**
  282. * Delete this object after removing from its parent if it has one.
  283. */
  284. void DeleteStructure();
  285. /**
  286. * Move this object.
  287. *
  288. * @param aMoveVector the move vector for this object.
  289. */
  290. virtual void Move( const VECTOR2I& aMoveVector )
  291. {
  292. wxFAIL_MSG( wxT( "virtual BOARD_ITEM::Move called for " ) + GetClass() );
  293. }
  294. /**
  295. * Rotate this object.
  296. *
  297. * @param aRotCentre the rotation center point.
  298. */
  299. virtual void Rotate( const VECTOR2I& aRotCentre, const EDA_ANGLE& aAngle );
  300. /**
  301. * Flip this object, i.e. change the board side for this object.
  302. *
  303. * @param aCentre the rotation point.
  304. * @param aFlipDirection the flip direction
  305. */
  306. virtual void Flip( const VECTOR2I& aCentre, FLIP_DIRECTION aFlipDirection );
  307. /**
  308. * Mirror this object relative to a given horizontal axis the layer is not changed.
  309. *
  310. * @param aCentre the mirror point.
  311. * @param aMirrorAroundXAxis mirror across X axis instead of Y (the default).
  312. */
  313. virtual void Mirror( const VECTOR2I& aCentre, FLIP_DIRECTION aFlipDirection );
  314. /**
  315. * Perform any normalization required after a user rotate and/or flip.
  316. */
  317. virtual void Normalize() {}
  318. /**
  319. * Perform any normalization required to compare 2 graphics, especially
  320. * if the can be rotated and/or flipped.
  321. * Similar to Normalize(), but more changes can be made
  322. */
  323. virtual void NormalizeForCompare() { Normalize(); }
  324. /**
  325. * Return the #BOARD in which this #BOARD_ITEM resides, or NULL if none.
  326. */
  327. virtual const BOARD* GetBoard() const;
  328. virtual BOARD* GetBoard();
  329. /**
  330. * For "parent" property.
  331. * @return the parent footprint's ref or the parent item's UUID.
  332. */
  333. wxString GetParentAsString() const;
  334. /**
  335. * Return the name of the PCB layer on which the item resides.
  336. *
  337. * @return the layer name associated with this item.
  338. */
  339. wxString GetLayerName() const;
  340. virtual std::vector<int> ViewGetLayers() const override;
  341. /**
  342. * Convert the item shape to a closed polygon. Circles and arcs are approximated by segments.
  343. *
  344. * @param aBuffer a buffer to store the polygon.
  345. * @param aClearance the clearance around the pad.
  346. * @param aError the maximum deviation from true circle.
  347. * @param aErrorLoc should the approximation error be placed outside or inside the polygon?
  348. * @param ignoreLineWidth used for edge cut items where the line width is only
  349. * for visualization.
  350. */
  351. virtual void TransformShapeToPolygon( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aLayer,
  352. int aClearance, int aError, ERROR_LOC aErrorLoc,
  353. bool ignoreLineWidth = false ) const;
  354. /**
  355. * Convert the item shape to a polyset. Circles and arcs are approximated by segments; hatched
  356. * fills will be included.
  357. *
  358. * @param aBuffer a buffer to store the polygon.
  359. * @param aClearance the clearance around the pad.
  360. * @param aError the maximum deviation from true circle.
  361. * @param aErrorLoc should the approximation error be placed outside or inside the polygon?
  362. * @param ignoreLineWidth used for edge cut items where the line width is only
  363. * for visualization.
  364. */
  365. virtual void TransformShapeToPolySet( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aLayer,
  366. int aClearance, int aError, ERROR_LOC aErrorLoc ) const
  367. {
  368. TransformShapeToPolygon( aBuffer, aLayer, aClearance, aError, aErrorLoc );
  369. }
  370. enum COMPARE_FLAGS : int
  371. {
  372. DRC = 0x01
  373. };
  374. struct ptr_cmp
  375. {
  376. bool operator() ( const BOARD_ITEM* a, const BOARD_ITEM* b ) const;
  377. };
  378. protected:
  379. /**
  380. * Return a string (to be shown to the user) describing a layer mask.
  381. */
  382. virtual wxString layerMaskDescribe() const;
  383. virtual void swapData( BOARD_ITEM* aImage );
  384. protected:
  385. PCB_LAYER_ID m_layer;
  386. bool m_isKnockout;
  387. bool m_isLocked;
  388. PCB_GROUP* m_group;
  389. };
  390. #ifndef SWIG
  391. DECLARE_ENUM_TO_WXANY( PCB_LAYER_ID );
  392. #endif
  393. /**
  394. * A singleton item of this class is returned for a weak reference that no longer exists.
  395. *
  396. * Its sole purpose is to flag the item as having been deleted.
  397. */
  398. class DELETED_BOARD_ITEM : public BOARD_ITEM
  399. {
  400. public:
  401. DELETED_BOARD_ITEM() :
  402. BOARD_ITEM( nullptr, NOT_USED )
  403. {}
  404. wxString GetItemDescription( UNITS_PROVIDER* aUnitsProvider, bool aFull ) const override
  405. {
  406. return _( "(Deleted Item)" );
  407. }
  408. wxString GetClass() const override
  409. {
  410. return wxT( "DELETED_BOARD_ITEM" );
  411. }
  412. // pure virtuals:
  413. void SetPosition( const VECTOR2I& ) override {}
  414. VECTOR2I GetPosition() const override { return VECTOR2I( 0, 0 ); }
  415. static DELETED_BOARD_ITEM* GetInstance()
  416. {
  417. static DELETED_BOARD_ITEM* item = nullptr;
  418. if( !item )
  419. item = new DELETED_BOARD_ITEM();
  420. return item;
  421. }
  422. double Similarity( const BOARD_ITEM& aItem ) const override
  423. {
  424. return ( this == &aItem ) ? 1.0 : 0.0;
  425. }
  426. bool operator==( const BOARD_ITEM& aBoardItem ) const override
  427. {
  428. return ( this == &aBoardItem );
  429. }
  430. bool operator==( const DELETED_BOARD_ITEM& aOther ) const
  431. {
  432. return ( this == &aOther );
  433. }
  434. #if defined(DEBUG)
  435. void Show( int , std::ostream& ) const override {}
  436. #endif
  437. };