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