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