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.

367 lines
10 KiB

  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 (C) 1992-2020 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 BOARD_ITEM_STRUCT_H
  25. #define BOARD_ITEM_STRUCT_H
  26. #include <eda_item.h>
  27. #include <eda_units.h>
  28. #include <convert_to_biu.h>
  29. #include <gr_basic.h>
  30. #include <layer_ids.h>
  31. #include <geometry/geometry_utils.h>
  32. class BOARD;
  33. class BOARD_ITEM_CONTAINER;
  34. class SHAPE_POLY_SET;
  35. class PCB_BASE_FRAME;
  36. class SHAPE;
  37. class PCB_GROUP;
  38. /**
  39. * A base class for any item which can be embedded within the #BOARD container class, and
  40. * therefore instances of derived classes should only be found in Pcbnew or other programs
  41. * that use class #BOARD and its contents.
  42. */
  43. class BOARD_ITEM : public EDA_ITEM
  44. {
  45. public:
  46. BOARD_ITEM( BOARD_ITEM* aParent, KICAD_T idtype ) :
  47. EDA_ITEM( aParent, idtype ),
  48. m_layer( F_Cu ),
  49. m_group( nullptr )
  50. {
  51. }
  52. void SetParentGroup( PCB_GROUP* aGroup ) { m_group = aGroup; }
  53. PCB_GROUP* GetParentGroup() const { return m_group; }
  54. // Do not create a copy constructor & operator=.
  55. // The ones generated by the compiler are adequate.
  56. int GetX() const
  57. {
  58. wxPoint p = GetPosition();
  59. return p.x;
  60. }
  61. int GetY() const
  62. {
  63. wxPoint p = GetPosition();
  64. return p.y;
  65. }
  66. /**
  67. * This defaults to the center of the bounding box if not overridden.
  68. *
  69. * @return center point of the item
  70. */
  71. virtual wxPoint GetCenter() const
  72. {
  73. return GetBoundingBox().GetCenter();
  74. }
  75. void SetX( int aX )
  76. {
  77. wxPoint p( aX, GetY() );
  78. SetPosition( p );
  79. }
  80. void SetY( int aY )
  81. {
  82. wxPoint p( GetX(), aY );
  83. SetPosition( p );
  84. }
  85. /**
  86. * Returns information if the object is derived from BOARD_CONNECTED_ITEM.
  87. *
  88. * @return True if the object is of BOARD_CONNECTED_ITEM type, false otherwise.
  89. */
  90. virtual bool IsConnected() const
  91. {
  92. return false;
  93. }
  94. /**
  95. * @return true if the object is on any copper layer, false otherwise.
  96. */
  97. virtual bool IsOnCopperLayer() const
  98. {
  99. return IsCopperLayer( GetLayer() );
  100. }
  101. /**
  102. * A value of wxPoint(0,0) which can be passed to the Draw() functions.
  103. */
  104. static wxPoint ZeroOffset;
  105. /**
  106. * Some pad shapes can be complex (rounded/chamfered rectangle), even without considering
  107. * custom shapes. This routine returns a COMPOUND shape (set of simple shapes which make
  108. * up the pad for use with routing, collision determination, etc).
  109. *
  110. * @note This list can contain a SHAPE_SIMPLE (a simple single-outline non-intersecting
  111. * polygon), but should never contain a SHAPE_POLY_SET (a complex polygon consisting of
  112. * multiple outlines and/or holes).
  113. *
  114. * @param aLayer in case of items spanning multiple layers, only the shapes belonging to aLayer
  115. * will be returned. Pass UNDEFINED_LAYER to return shapes for all layers.
  116. */
  117. virtual std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER ) const;
  118. BOARD_ITEM_CONTAINER* GetParent() const { return (BOARD_ITEM_CONTAINER*) m_parent; }
  119. /**
  120. * Return the primary layer this item is on.
  121. */
  122. virtual PCB_LAYER_ID GetLayer() const { return m_layer; }
  123. /**
  124. * Return a std::bitset of all layers on which the item physically resides.
  125. */
  126. virtual LSET GetLayerSet() const { return LSET( m_layer ); }
  127. virtual void SetLayerSet( LSET aLayers )
  128. {
  129. wxFAIL_MSG( "Attempted to SetLayerSet() on a single-layer object." );
  130. // Derived classes which support multiple layers must implement this
  131. }
  132. /**
  133. * Set the layer this item is on.
  134. *
  135. * This method is virtual because some items (in fact: class DIMENSION)
  136. * have a slightly different initialization.
  137. *
  138. * @param aLayer The layer number.
  139. */
  140. virtual void SetLayer( PCB_LAYER_ID aLayer )
  141. {
  142. m_layer = aLayer;
  143. }
  144. /**
  145. * Create a copy of this #BOARD_ITEM.
  146. */
  147. virtual BOARD_ITEM* Duplicate() const
  148. {
  149. EDA_ITEM* dupe = Clone();
  150. const_cast<KIID&>( dupe->m_Uuid ) = KIID();
  151. return static_cast<BOARD_ITEM*>( dupe );
  152. }
  153. /**
  154. * Swap data between \a aItem and \a aImage.
  155. *
  156. * \a aItem and \a aImage should have the same type.
  157. *
  158. * Used in undo and redo commands to swap values between an item and its copy.
  159. * Only values like layer, size .. which are modified by editing are swapped.
  160. *
  161. * @param aImage the item image which contains data to swap.
  162. */
  163. virtual void SwapData( BOARD_ITEM* aImage );
  164. /**
  165. * Test to see if this object is on the given layer.
  166. *
  167. * Virtual so objects like #PAD, which reside on multiple layers can do their own form
  168. * of testing.
  169. *
  170. * @param aLayer The layer to test for.
  171. * @return true if on given layer, else false.
  172. */
  173. virtual bool IsOnLayer( PCB_LAYER_ID aLayer ) const
  174. {
  175. return m_layer == aLayer;
  176. }
  177. /**
  178. * Test to see if this object is a track or via (or microvia).
  179. *
  180. * @return true if a track or via, else false.
  181. */
  182. bool IsTrack() const
  183. {
  184. return ( Type() == PCB_TRACE_T ) || ( Type() == PCB_VIA_T );
  185. }
  186. /**
  187. * @return true if the object is locked, else false.
  188. */
  189. virtual bool IsLocked() const;
  190. /**
  191. * Modify the 'lock' status for of the item.
  192. */
  193. virtual void SetLocked( bool aLocked )
  194. {
  195. SetState( LOCKED, aLocked );
  196. }
  197. /**
  198. * Delete this object after removing from its parent if it has one.
  199. */
  200. void DeleteStructure();
  201. /**
  202. * Move this object.
  203. *
  204. * @param aMoveVector the move vector for this object.
  205. */
  206. virtual void Move( const wxPoint& aMoveVector )
  207. {
  208. wxFAIL_MSG( "virtual BOARD_ITEM::Move called for " + GetClass() );
  209. }
  210. void Move( const VECTOR2I& aMoveVector )
  211. {
  212. Move( wxPoint( aMoveVector.x, aMoveVector.y ) );
  213. }
  214. /**
  215. * Rotate this object.
  216. *
  217. * @param aRotCentre the rotation point.
  218. * @param aAngle the rotation angle in 0.1 degree.
  219. */
  220. virtual void Rotate( const wxPoint& aRotCentre, double aAngle );
  221. void Rotate( const VECTOR2I& aRotCentre, double aAngle )
  222. {
  223. Rotate( wxPoint( aRotCentre.x, aRotCentre.y ), aAngle );
  224. }
  225. /**
  226. * Flip this object, i.e. change the board side for this object.
  227. *
  228. * @param aCentre the rotation point.
  229. * @param aFlipLeftRight mirror across Y axis instead of X (the default).
  230. */
  231. virtual void Flip( const wxPoint& aCentre, bool aFlipLeftRight );
  232. void Flip( const VECTOR2I& aCentre, bool aFlipLeftRight )
  233. {
  234. Flip( wxPoint( aCentre.x, aCentre.y ), aFlipLeftRight );
  235. }
  236. /**
  237. * Return the #BOARD in which this #BOARD_ITEM resides, or NULL if none.
  238. */
  239. virtual const BOARD* GetBoard() const;
  240. virtual BOARD* GetBoard();
  241. /**
  242. * Return the name of the PCB layer on which the item resides.
  243. *
  244. * @return the layer name associated with this item.
  245. */
  246. wxString GetLayerName() const;
  247. virtual void ViewGetLayers( int aLayers[], int& aCount ) const override;
  248. /**
  249. * Convert the item shape to a closed polygon.
  250. *
  251. * Used in filling zones calculations. Circles and arcs are approximated by segments.
  252. *
  253. * @param aCornerBuffer a buffer to store the polygon.
  254. * @param aClearanceValue the clearance around the pad.
  255. * @param aError the maximum deviation from true circle.
  256. * @param aErrorLoc should the approximation error be placed outside or inside the polygon?
  257. * @param ignoreLineWidth used for edge cut items where the line width is only
  258. * for visualization.
  259. */
  260. virtual void TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
  261. PCB_LAYER_ID aLayer, int aClearanceValue,
  262. int aError, ERROR_LOC aErrorLoc,
  263. bool ignoreLineWidth = false ) const;
  264. struct ptr_cmp
  265. {
  266. bool operator() ( const BOARD_ITEM* a, const BOARD_ITEM* b ) const;
  267. };
  268. protected:
  269. /**
  270. * Return a string (to be shown to the user) describing a layer mask. The BOARD is needed
  271. * because layer names are customizable.
  272. */
  273. virtual wxString layerMaskDescribe() const;
  274. PCB_LAYER_ID m_layer;
  275. PCB_GROUP* m_group;
  276. };
  277. #ifndef SWIG
  278. DECLARE_ENUM_TO_WXANY( PCB_LAYER_ID );
  279. #endif
  280. /**
  281. * A singleton item of this class is returned for a weak reference that no longer exists.
  282. *
  283. * Its sole purpose is to flag the item as having been deleted.
  284. */
  285. class DELETED_BOARD_ITEM : public BOARD_ITEM
  286. {
  287. public:
  288. DELETED_BOARD_ITEM() :
  289. BOARD_ITEM( nullptr, NOT_USED )
  290. {}
  291. wxString GetSelectMenuText( EDA_UNITS aUnits ) const override
  292. {
  293. return _( "(Deleted Item)" );
  294. }
  295. wxString GetClass() const override
  296. {
  297. return wxT( "DELETED_BOARD_ITEM" );
  298. }
  299. // pure virtuals:
  300. void SetPosition( const wxPoint& ) override {}
  301. wxPoint GetPosition() const override { return wxPoint(0, 0); }
  302. static DELETED_BOARD_ITEM* GetInstance()
  303. {
  304. static DELETED_BOARD_ITEM* item = nullptr;
  305. if( !item )
  306. item = new DELETED_BOARD_ITEM();
  307. return item;
  308. }
  309. #if defined(DEBUG)
  310. void Show( int , std::ostream& ) const override {}
  311. #endif
  312. };
  313. #endif /* BOARD_ITEM_STRUCT_H */