-
-
Notifications
You must be signed in to change notification settings - Fork 486
/
footprint.h
1102 lines (915 loc) · 40.8 KB
/
footprint.h
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
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 1992-2024 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
*/
#ifndef FOOTPRINT_H
#define FOOTPRINT_H
#include <deque>
#include <template_fieldnames.h>
#include <board_item_container.h>
#include <board_item.h>
#include <collectors.h>
#include <component_class_manager.h>
#include <embedded_files.h>
#include <layer_ids.h> // ALL_LAYERS definition.
#include <lset.h>
#include <lib_id.h>
#include <list>
#include <zones.h>
#include <convert_shape_list_to_polygon.h>
#include <pcb_item_containers.h>
#include <pcb_text.h>
#include <pcb_field.h>
#include <functional>
#include <math/vector3.h>
class LINE_READER;
class EDA_3D_CANVAS;
class PAD;
class BOARD;
class MSG_PANEL_ITEM;
class SHAPE;
class REPORTER;
namespace KIGFX {
class VIEW;
}
enum INCLUDE_NPTH_T
{
DO_NOT_INCLUDE_NPTH = false,
INCLUDE_NPTH = true
};
/**
* The set of attributes allowed within a FOOTPRINT, using FOOTPRINT::SetAttributes()
* and FOOTPRINT::GetAttributes(). These are to be ORed together when calling
* FOOTPRINT::SetAttributes()
*/
enum FOOTPRINT_ATTR_T
{
FP_THROUGH_HOLE = 0x0001,
FP_SMD = 0x0002,
FP_EXCLUDE_FROM_POS_FILES = 0x0004,
FP_EXCLUDE_FROM_BOM = 0x0008,
FP_BOARD_ONLY = 0x0010, // Footprint has no corresponding symbol
FP_JUST_ADDED = 0x0020, // Footprint just added by netlist update
FP_ALLOW_SOLDERMASK_BRIDGES = 0x0040,
FP_ALLOW_MISSING_COURTYARD = 0x0080,
FP_DNP = 0x0100
};
class FP_3DMODEL
{
public:
FP_3DMODEL() :
// Initialize with sensible values
m_Scale { 1, 1, 1 },
m_Rotation { 0, 0, 0 },
m_Offset { 0, 0, 0 },
m_Opacity( 1.0 ),
m_Show( true )
{
}
VECTOR3D m_Scale; ///< 3D model scaling factor (dimensionless)
VECTOR3D m_Rotation; ///< 3D model rotation (degrees)
VECTOR3D m_Offset; ///< 3D model offset (mm)
double m_Opacity;
wxString m_Filename; ///< The 3D shape filename in 3D library
bool m_Show; ///< Include model in rendering
bool operator==( const FP_3DMODEL& aOther ) const
{
return m_Scale == aOther.m_Scale
&& m_Rotation == aOther.m_Rotation
&& m_Offset == aOther.m_Offset
&& m_Opacity == aOther.m_Opacity
&& m_Filename == aOther.m_Filename
&& m_Show == aOther.m_Show;
}
};
class FOOTPRINT : public BOARD_ITEM_CONTAINER, public EMBEDDED_FILES
{
public:
FOOTPRINT( BOARD* parent );
FOOTPRINT( const FOOTPRINT& aFootprint );
// Move constructor and operator needed due to std containers inside the footprint
FOOTPRINT( FOOTPRINT&& aFootprint );
~FOOTPRINT();
FOOTPRINT& operator=( const FOOTPRINT& aOther );
FOOTPRINT& operator=( FOOTPRINT&& aOther );
void Serialize( google::protobuf::Any &aContainer ) const override;
bool Deserialize( const google::protobuf::Any &aContainer ) override;
static inline bool ClassOf( const EDA_ITEM* aItem )
{
return aItem && aItem->Type() == PCB_FOOTPRINT_T;
}
LSET GetPrivateLayers() const { return m_privateLayers; }
void SetPrivateLayers( LSET aLayers ) { m_privateLayers = aLayers; }
///< @copydoc BOARD_ITEM_CONTAINER::Add()
void Add( BOARD_ITEM* aItem, ADD_MODE aMode = ADD_MODE::INSERT,
bool aSkipConnectivity = false ) override;
///< @copydoc BOARD_ITEM_CONTAINER::Remove()
void Remove( BOARD_ITEM* aItem, REMOVE_MODE aMode = REMOVE_MODE::NORMAL ) override;
/**
* Clear (i.e. force the ORPHANED dummy net info) the net info which
* depends on a given board for all pads of the footprint.
*
* This is needed when a footprint is copied between the fp editor and
* the board editor for instance, because net info become fully broken
*/
void ClearAllNets();
/**
* Old footprints do not always have a valid UUID (some can be set to null uuid)
* However null UUIDs, having a special meaning in editor, create issues when
* editing a footprint
* So all null uuids a re replaced by a valid uuid
* @return true if at least one uuid is changed, false if no change
*/
bool FixUuids();
/**
* Return the bounding box containing pads when the footprint is on the front side,
* orientation 0, position 0,0.
*
* Mainly used in Gerber place file to draw a footprint outline when the courtyard
* is missing or broken.
*
* @return The rectangle containing the pads for the normalized footprint.
*/
BOX2I GetFpPadsLocalBbox() const;
/**
* Return a bounding polygon for the shapes and pads in the footprint.
*
* This operation is slower but more accurate than calculating a bounding box.
*/
SHAPE_POLY_SET GetBoundingHull() const;
bool TextOnly() const;
// Virtual function
const BOX2I GetBoundingBox() const override;
const BOX2I GetBoundingBox( bool aIncludeText ) const;
/**
* Return the bounding box of the footprint on a given set of layers
*/
const BOX2I GetLayerBoundingBox( LSET aLayers ) const;
VECTOR2I GetCenter() const override
{
return GetBoundingBox( false ).GetCenter();
}
PCB_FIELDS& Fields() { return m_fields; }
const PCB_FIELDS& Fields() const { return m_fields; }
std::deque<PAD*>& Pads() { return m_pads; }
const std::deque<PAD*>& Pads() const { return m_pads; }
DRAWINGS& GraphicalItems() { return m_drawings; }
const DRAWINGS& GraphicalItems() const { return m_drawings; }
ZONES& Zones() { return m_zones; }
const ZONES& Zones() const { return m_zones; }
GROUPS& Groups() { return m_groups; }
const GROUPS& Groups() const { return m_groups; }
bool HasThroughHolePads() const;
std::vector<FP_3DMODEL>& Models() { return m_3D_Drawings; }
const std::vector<FP_3DMODEL>& Models() const { return m_3D_Drawings; }
void SetPosition( const VECTOR2I& aPos ) override;
VECTOR2I GetPosition() const override { return m_pos; }
void SetOrientation( const EDA_ANGLE& aNewAngle );
EDA_ANGLE GetOrientation() const { return m_orient; }
/**
* Used as Layer property setter -- performs a flip if necessary to set the footprint layer
* @param aLayer is the target layer (F_Cu or B_Cu)
*/
void SetLayerAndFlip( PCB_LAYER_ID aLayer );
// to make property magic work
PCB_LAYER_ID GetLayer() const override { return BOARD_ITEM::GetLayer(); }
// For property system:
void SetOrientationDegrees( double aOrientation )
{
SetOrientation( EDA_ANGLE( aOrientation, DEGREES_T ) );
}
double GetOrientationDegrees() const
{
return m_orient.AsDegrees();
}
const LIB_ID& GetFPID() const { return m_fpid; }
void SetFPID( const LIB_ID& aFPID )
{
m_fpid = aFPID;
}
wxString GetFPIDAsString() const { return m_fpid.Format(); }
void SetFPIDAsString( const wxString& aFPID ) { m_fpid.Parse( aFPID ); }
wxString GetLibDescription() const { return m_libDescription; }
void SetLibDescription( const wxString& aDesc ) { m_libDescription = aDesc; }
wxString GetKeywords() const { return m_keywords; }
void SetKeywords( const wxString& aKeywords ) { m_keywords = aKeywords; }
const KIID_PATH& GetPath() const { return m_path; }
void SetPath( const KIID_PATH& aPath ) { m_path = aPath; }
wxString GetSheetname() const { return m_sheetname; }
void SetSheetname( const wxString& aSheetname ) { m_sheetname = aSheetname; }
wxString GetSheetfile() const { return m_sheetfile; }
void SetSheetfile( const wxString& aSheetfile ) { m_sheetfile = aSheetfile; }
wxString GetFilters() const { return m_filters; }
void SetFilters( const wxString& aFilters ) { m_filters = aFilters; }
std::optional<int> GetLocalClearance() const { return m_clearance; }
void SetLocalClearance( std::optional<int> aClearance ) { m_clearance = aClearance; }
std::optional<int> GetLocalSolderMaskMargin() const { return m_solderMaskMargin; }
void SetLocalSolderMaskMargin( std::optional<int> aMargin ) { m_solderMaskMargin = aMargin; }
std::optional<int> GetLocalSolderPasteMargin() const { return m_solderPasteMargin; }
void SetLocalSolderPasteMargin( std::optional<int> aMargin ) { m_solderPasteMargin = aMargin; }
std::optional<double> GetLocalSolderPasteMarginRatio() const { return m_solderPasteMarginRatio; }
void SetLocalSolderPasteMarginRatio( std::optional<double> aRatio ) { m_solderPasteMarginRatio = aRatio; }
void SetLocalZoneConnection( ZONE_CONNECTION aType ) { m_zoneConnection = aType; }
ZONE_CONNECTION GetLocalZoneConnection() const { return m_zoneConnection; }
int GetAttributes() const { return m_attributes; }
void SetAttributes( int aAttributes ) { m_attributes = aAttributes; }
void SetFlag( int aFlag ) { m_arflag = aFlag; }
void IncrementFlag() { m_arflag += 1; }
int GetFlag() const { return m_arflag; }
bool IsNetTie() const
{
for( const wxString& group : m_netTiePadGroups )
{
if( !group.IsEmpty() )
return true;
}
return false;
}
std::optional<int> GetLocalClearance( wxString* aSource ) const
{
if( m_clearance.has_value() && aSource )
*aSource = wxString::Format( _( "footprint %s" ), GetReference() );
return m_clearance;
}
/**
* Return any local clearance overrides set in the "classic" (ie: pre-rule) system.
*
* @param aSource [out] optionally reports the source as a user-readable string.
* @return the clearance in internal units.
*/
std::optional<int> GetClearanceOverrides( wxString* aSource ) const
{
return GetLocalClearance( aSource );
}
ZONE_CONNECTION GetZoneConnectionOverrides( wxString* aSource ) const
{
if( m_zoneConnection != ZONE_CONNECTION::INHERITED && aSource )
*aSource = wxString::Format( _( "footprint %s" ), GetReference() );
return m_zoneConnection;
}
/**
* @return a list of pad groups, each of which is allowed to short nets within their group.
* A pad group is a comma-separated list of pad numbers.
*/
const std::vector<wxString>& GetNetTiePadGroups() const { return m_netTiePadGroups; }
void ClearNetTiePadGroups()
{
m_netTiePadGroups.clear();
}
void AddNetTiePadGroup( const wxString& aGroup )
{
m_netTiePadGroups.emplace_back( aGroup );
}
/**
* @return a map from pad numbers to net-tie group indices. If a pad is not a member of
* a net-tie group its index will be -1.
*/
std::map<wxString, int> MapPadNumbersToNetTieGroups() const;
/**
* @return a list of pads that appear in \a aPad's net-tie pad group.
*/
std::vector<PAD*> GetNetTiePads( PAD* aPad ) const;
/**
* Returns the most likely attribute based on pads
* Either FP_THROUGH_HOLE/FP_SMD/OTHER(0)
* @return 0/FP_SMD/FP_THROUGH_HOLE
*/
int GetLikelyAttribute() const;
void Move( const VECTOR2I& aMoveVector ) override;
void Rotate( const VECTOR2I& aRotCentre, const EDA_ANGLE& aAngle ) override;
void Flip( const VECTOR2I& aCentre, FLIP_DIRECTION aFlipDirection ) override;
/**
* Move the reference point of the footprint.
*
* It looks like a move footprint:
* the footprints elements (pads, outlines, edges .. ) are moved
* However:
* - the footprint position is not modified.
* - the relative (local) coordinates of these items are modified
* (a move footprint does not change these local coordinates,
* but changes the footprint position)
*/
void MoveAnchorPosition( const VECTOR2I& aMoveVector );
/**
* @return true if the footprint is flipped, i.e. on the back side of the board
*/
bool IsFlipped() const { return GetLayer() == B_Cu; }
/**
* Use instead of IsFlipped() when you also need to account for unsided footprints (those
* purely on user-layers, etc.).
*/
PCB_LAYER_ID GetSide() const;
/**
* @copydoc BOARD_ITEM::IsOnLayer
*/
bool IsOnLayer( PCB_LAYER_ID aLayer ) const override;
// m_footprintStatus bits:
#define FP_is_LOCKED 0x01 ///< footprint LOCKED: no autoplace allowed
#define FP_is_PLACED 0x02 ///< In autoplace: footprint automatically placed
#define FP_to_PLACE 0x04 ///< In autoplace: footprint waiting for autoplace
#define FP_PADS_are_LOCKED 0x08
bool IsLocked() const override
{
return ( m_fpStatus & FP_is_LOCKED ) != 0;
}
/**
* Set the #MODULE_is_LOCKED bit in the m_ModuleStatus.
*
* @param isLocked true means turn on locked status, else unlock
*/
void SetLocked( bool isLocked ) override
{
if( isLocked )
m_fpStatus |= FP_is_LOCKED;
else
m_fpStatus &= ~FP_is_LOCKED;
}
/**
* @return true if the footprint is flagged with conflicting with some item
*/
bool IsConflicting() const;
bool IsPlaced() const { return m_fpStatus & FP_is_PLACED; }
void SetIsPlaced( bool isPlaced )
{
if( isPlaced )
m_fpStatus |= FP_is_PLACED;
else
m_fpStatus &= ~FP_is_PLACED;
}
bool NeedsPlaced() const { return m_fpStatus & FP_to_PLACE; }
void SetNeedsPlaced( bool needsPlaced )
{
if( needsPlaced )
m_fpStatus |= FP_to_PLACE;
else
m_fpStatus &= ~FP_to_PLACE;
}
bool LegacyPadsLocked() const { return m_fpStatus & FP_PADS_are_LOCKED; }
/**
* Test if footprint attributes for type (SMD/Through hole/Other) match the expected
* type based on the pads in the footprint.
* Footprints with plated through-hole pads should usually be marked through hole even if they
* also have SMD because they might not be auto-placed. Exceptions to this might be shielded
* connectors. Otherwise, footprints with SMD pads should be marked SMD.
* Footprints with no connecting pads should be marked "Other"
*
* @param aErrorHandler callback to handle the error messages generated
*/
void CheckFootprintAttributes( const std::function<void( const wxString& )>& aErrorHandler );
/**
* Run non-board-specific DRC checks on footprint's pads. These are the checks supported by
* both the PCB DRC and the Footprint Editor Footprint Checker.
*
* @param aErrorHandler callback to handle the error messages generated
*/
void CheckPads( UNITS_PROVIDER* aUnitsProvider,
const std::function<void( const PAD*, int, const wxString& )>& aErrorHandler );
/**
* Check for overlapping, different-numbered, non-net-tie pads.
*
* @param aErrorHandler callback to handle the error messages generated
*/
void CheckShortingPads( const std::function<void( const PAD*, const PAD*, int aErrorCode,
const VECTOR2I& )>& aErrorHandler );
/**
* Check for un-allowed shorting of pads in net-tie footprints. If two pads are shorted,
* they must both appear in one of the allowed-shorting lists.
*
* @param aErrorHandler callback to handle the error messages generated
*/
void CheckNetTies( const std::function<void( const BOARD_ITEM* aItem,
const BOARD_ITEM* bItem,
const BOARD_ITEM* cItem,
const VECTOR2I& )>& aErrorHandler );
/**
* Sanity check net-tie pad groups. Pads cannot be listed more than once, and pad numbers
* must correspond to a pad.
*
* @param aErrorHandler callback to handle the error messages generated
*/
void CheckNetTiePadGroups( const std::function<void( const wxString& )>& aErrorHandler );
/**
* Generate pads shapes on layer \a aLayer as polygons and adds these polygons to
* \a aBuffer.
*
* Useful to generate a polygonal representation of a footprint in 3D view and plot functions,
* when a full polygonal approach is needed.
*
* @param aLayer is the layer to consider, or #UNDEFINED_LAYER to consider all layers.
* @param aBuffer i the buffer to store polygons.
* @param aClearance is an additional size to add to pad shapes.
* @param aMaxError is the maximum deviation from true for arcs.
* @param aSkipNPTHPadsWihNoCopper if true, do not add a NPTH pad shape, if the shape has
* same size and position as the hole. Usually, these pads are not drawn on copper
* layers, because there is actually no copper
* Due to diff between layers and holes, these pads must be skipped to be sure
* there is no copper left on the board (for instance when creating Gerber Files or
* 3D shapes). Defaults to false.
* @param aSkipPlatedPads is used on 3D-Viewer to extract plated and non-plated pads.
* @param aSkipNonPlatedPads is used on 3D-Viewer to extract plated and plated pads.
*/
void TransformPadsToPolySet( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aLayer, int aClearance,
int aMaxError, ERROR_LOC aErrorLoc,
bool aSkipNPTHPadsWihNoCopper = false,
bool aSkipPlatedPads = false,
bool aSkipNonPlatedPads = false ) const;
/**
* Generate shapes of graphic items (outlines) on layer \a aLayer as polygons and adds these
* polygons to \a aBuffer.
*
* Useful to generate a polygonal representation of a footprint in 3D view and plot functions,
* when a full polygonal approach is needed.
*
* @param aLayer is the layer to consider, or #UNDEFINED_LAYER to consider all.
* @param aBuffer is the buffer to store polygons.
* @param aClearance is a value to inflate shapes.
* @param aError is the maximum error between true arc and polygon approximation.
* @param aIncludeText set to true to transform text shapes.
* @param aIncludeShapes set to true to transform footprint shapes.
*/
void TransformFPShapesToPolySet( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aLayer, int aClearance,
int aError, ERROR_LOC aErrorLoc,
bool aIncludeText = true,
bool aIncludeShapes = true,
bool aIncludePrivateItems = false ) const;
/**
* This function is the same as TransformFPShapesToPolySet but only generates text.
*/
void TransformFPTextToPolySet( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aLayer, int aClearance,
int aError, ERROR_LOC aErrorLoc ) const
{
TransformFPShapesToPolySet( aBuffer, aLayer, aClearance, aError, aErrorLoc, true, false );
}
/**
* Return the list of system text vars for this footprint.
*/
void GetContextualTextVars( wxArrayString* aVars ) const;
/**
* Resolve any references to system tokens supported by the component.
*
* @param aDepth a counter to limit recursion and circular references.
*/
bool ResolveTextVar( wxString* token, int aDepth = 0 ) const;
/// @copydoc EDA_ITEM::GetMsgPanelInfo
void GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList ) override;
bool HitTest( const VECTOR2I& aPosition, int aAccuracy = 0 ) const override;
/**
* Test if a point is inside the bounding polygon of the footprint.
*
* The other hit test methods are just checking the bounding box, which can be quite
* inaccurate for rotated or oddly-shaped footprints.
*
* @param aPosition is the point to test
* @return true if aPosition is inside the bounding polygon
*/
bool HitTestAccurate( const VECTOR2I& aPosition, int aAccuracy = 0 ) const;
bool HitTest( const BOX2I& aRect, bool aContained, int aAccuracy = 0 ) const override;
/**
* Test if the point hits one or more of the footprint elements on a given layer.
*
* @param aPosition is the point to test
* @param aAccuracy is the hit test accuracy
* @param aLayer is the layer to test
* @return true if aPosition hits a footprint element on aLayer
*/
bool HitTestOnLayer( const VECTOR2I& aPosition, PCB_LAYER_ID aLayer, int aAccuracy = 0 ) const;
bool HitTestOnLayer( const BOX2I& aRect, bool aContained, PCB_LAYER_ID aLayer, int aAccuracy = 0 ) const;
/**
* @return reference designator text.
*/
const wxString& GetReference() const { return Reference().GetText(); }
/**
* @param aReference A reference to a wxString object containing the reference designator
* text.
*/
void SetReference( const wxString& aReference ) { Reference().SetText( aReference ); }
// Property system doesn't like const references
wxString GetReferenceAsString() const
{
return GetReference();
}
/**
* Bump the current reference by \a aDelta.
*/
void IncrementReference( int aDelta );
/**
* @return the value text.
*/
const wxString& GetValue() const { return Value().GetText(); }
/**
* @param aValue A reference to a wxString object containing the value text.
*/
void SetValue( const wxString& aValue ) { Value().SetText( aValue ); }
// Property system doesn't like const references
wxString GetValueAsString() const
{
return GetValue();
}
/// read/write accessors:
PCB_FIELD& Value() { return *GetField( VALUE_FIELD ); }
PCB_FIELD& Reference() { return *GetField( REFERENCE_FIELD ); }
PCB_FIELD& Footprint() { return *GetField( FOOTPRINT_FIELD ); }
/// The const versions to keep the compiler happy.
const PCB_FIELD& Value() const { return *GetField( VALUE_FIELD ); }
const PCB_FIELD& Reference() const { return *GetField( REFERENCE_FIELD ); }
const PCB_FIELD& Footprint() const { return *GetField( FOOTPRINT_FIELD ); }
//-----<Fields>-----------------------------------------------------------
/**
* Return a mandatory field in this symbol.
*
* @note If you need to fetch a user field, use GetFieldById.
*
* @param aFieldType is one of the mandatory field types (REFERENCE_FIELD, VALUE_FIELD, etc.).
* @return is the field at \a aFieldType or NULL if the field does not exist.
*/
PCB_FIELD* GetField( MANDATORY_FIELD_T aFieldType );
const PCB_FIELD* GetField( MANDATORY_FIELD_T aFieldNdx ) const;
/**
* Return a field in this symbol.
*
* @param aFieldId is the id of the field requested. Note that this id ONLY SOMETIMES equates
* to the field's position in the vector.
* @return is the field at \a aFieldType or NULL if the field does not exist.
*/
PCB_FIELD* GetFieldById( int aFieldId );
/**
* Return a field in this symbol.
*
* @param aFieldName is the name of the field
*
* @return is the field with \a aFieldName or NULL if the field does not exist.
*/
PCB_FIELD* GetFieldByName( const wxString& aFieldName );
bool HasFieldByName( const wxString& aFieldName ) const;
/**
* Search for a field named \a aFieldName and returns text associated with this field.
*
* @param aFieldName is the name of the field
*/
wxString GetFieldText( const wxString& aFieldName ) const;
/**
* Populate a std::vector with PCB_TEXTs.
*
* @param aVector is the vector to populate.
* @param aVisibleOnly is used to add only the fields that are visible and contain text.
*/
void GetFields( std::vector<PCB_FIELD*>& aVector, bool aVisibleOnly );
/**
* Return a vector of fields from the symbol
*/
PCB_FIELDS GetFields() { return m_fields; }
const PCB_FIELDS& GetFields() const { return m_fields; }
/**
* Add a field to the symbol.
*
* @param aField is the field to add to this symbol.
*
* @return the newly inserted field.
*/
PCB_FIELD* AddField( const PCB_FIELD& aField );
/**
* Remove a user field from the footprint.
* @param aFieldName is the user fieldName to remove. Attempts to remove a mandatory
* field or a non-existant field are silently ignored.
*/
void RemoveField( const wxString& aFieldName );
/**
* Return the number of fields in this symbol.
*/
int GetFieldCount() const { return (int) m_fields.size(); }
/**
* @brief Apply default board settings to the footprint field text properties.
*
* This is needed because the board settings are not available when the footprint is
* being created in the footprint library cache, and we want these fields to have
* the correct default text properties.
*/
void ApplyDefaultSettings( const BOARD& board, bool aStyleFields, bool aStyleText,
bool aStyleShapes );
bool IsBoardOnly() const { return m_attributes & FP_BOARD_ONLY; }
void SetBoardOnly( bool aIsBoardOnly = true )
{
if( aIsBoardOnly )
m_attributes |= FP_BOARD_ONLY;
else
m_attributes &= ~FP_BOARD_ONLY;
}
bool IsExcludedFromPosFiles() const { return m_attributes & FP_EXCLUDE_FROM_POS_FILES; }
void SetExcludedFromPosFiles( bool aExclude = true )
{
if( aExclude )
m_attributes |= FP_EXCLUDE_FROM_POS_FILES;
else
m_attributes &= ~FP_EXCLUDE_FROM_POS_FILES;
}
bool IsExcludedFromBOM() const { return m_attributes & FP_EXCLUDE_FROM_BOM; }
void SetExcludedFromBOM( bool aExclude = true )
{
if( aExclude )
m_attributes |= FP_EXCLUDE_FROM_BOM;
else
m_attributes &= ~FP_EXCLUDE_FROM_BOM;
}
bool AllowMissingCourtyard() const { return m_attributes & FP_ALLOW_MISSING_COURTYARD; }
void SetAllowMissingCourtyard( bool aAllow = true )
{
if( aAllow )
m_attributes |= FP_ALLOW_MISSING_COURTYARD;
else
m_attributes &= ~FP_ALLOW_MISSING_COURTYARD;
}
bool IsDNP() const { return m_attributes & FP_DNP; }
void SetDNP( bool aDNP = true )
{
if( aDNP )
m_attributes |= FP_DNP;
else
m_attributes &= ~FP_DNP;
}
void SetFileFormatVersionAtLoad( int aVersion ) { m_fileFormatVersionAtLoad = aVersion; }
int GetFileFormatVersionAtLoad() const { return m_fileFormatVersionAtLoad; }
/**
* Return a #PAD with a matching number.
*
* @note Numbers may not be unique depending on how the footprint was created.
*
* @param aPadNumber the pad number to find.
* @param aSearchAfterMe = not nullptr to find a pad living after aAfterMe
* @return the first matching numbered #PAD is returned or NULL if not found.
*/
PAD* FindPadByNumber( const wxString& aPadNumber, PAD* aSearchAfterMe = nullptr ) const;
/**
* Get a pad at \a aPosition on \a aLayerMask in the footprint.
*
* @param aPosition A VECTOR2I object containing the position to hit test.
* @param aLayerMask A layer or layers to mask the hit test.
* @return A pointer to a #PAD object if found otherwise NULL.
*/
PAD* GetPad( const VECTOR2I& aPosition, LSET aLayerMask = LSET::AllLayersMask() );
std::vector<const PAD*> GetPads( const wxString& aPadNumber,
const PAD* aIgnore = nullptr ) const;
/**
* Return the number of pads.
*
* @param aIncludeNPTH includes non-plated through holes when true. Does not include
* non-plated through holes when false.
* @return the number of pads according to \a aIncludeNPTH.
*/
unsigned GetPadCount( INCLUDE_NPTH_T aIncludeNPTH = INCLUDE_NPTH_T(INCLUDE_NPTH) ) const;
/**
* Return the number of unique non-blank pads.
*
* A complex pad can be built with many pads having the same pad name to create a complex
* shape or fragmented solder paste areas.
*
* @param aIncludeNPTH includes non-plated through holes when true. Does not include
* non-plated through holes when false.
* @return the number of unique pads according to \a aIncludeNPTH.
*/
unsigned GetUniquePadCount( INCLUDE_NPTH_T aIncludeNPTH = INCLUDE_NPTH_T(INCLUDE_NPTH) ) const;
/**
* Return the names of the unique, non-blank pads.
*/
std::set<wxString>
GetUniquePadNumbers( INCLUDE_NPTH_T aIncludeNPTH = INCLUDE_NPTH_T(INCLUDE_NPTH) ) const;
/**
* Return the next available pad number in the footprint.
*
* @param aFillSequenceGaps true if the numbering should "fill in" gaps in the sequence,
* else return the highest value + 1
* @return the next available pad number
*/
wxString GetNextPadNumber( const wxString& aLastPadName ) const;
/**
* Position Reference and Value fields at the top and bottom of footprint's bounding box.
*/
void AutoPositionFields();
/**
* Get the type of footprint
* @return "SMD"/"Through hole"/"Other" based on attributes
*/
wxString GetTypeName() const;
double GetArea( int aPadding = 0 ) const;
KIID GetLink() const { return m_link; }
void SetLink( const KIID& aLink ) { m_link = aLink; }
BOARD_ITEM* Duplicate() const override;
/**
* Duplicate a given item within the footprint, optionally adding it to the board.
*
* @return the new item, or NULL if the item could not be duplicated.
*/
BOARD_ITEM* DuplicateItem( const BOARD_ITEM* aItem, bool aAddToFootprint = false );
/**
* Add \a a3DModel definition to the end of the 3D model list.
*
* @param a3DModel A pointer to a #FP_3DMODEL to add to the list.
*/
void Add3DModel( FP_3DMODEL* a3DModel );
INSPECT_RESULT Visit( INSPECTOR inspector, void* testData,
const std::vector<KICAD_T>& aScanTypes ) override;
wxString GetClass() const override
{
return wxT( "FOOTPRINT" );
}
wxString GetItemDescription( UNITS_PROVIDER* aUnitsProvider, bool aFull ) const override;
BITMAPS GetMenuImage() const override;
EDA_ITEM* Clone() const override;
///< @copydoc BOARD_ITEM::RunOnChildren
void RunOnChildren( const std::function<void (BOARD_ITEM*)>& aFunction ) const override;
///< @copydoc BOARD_ITEM::RunOnDescendants
void RunOnDescendants( const std::function<void( BOARD_ITEM* )>& aFunction,
int aDepth = 0 ) const override;
virtual void ViewGetLayers( int aLayers[], int& aCount ) const override;
double ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const override;
virtual const BOX2I ViewBBox() const override;
/**
* Test for validity of a name of a footprint to be used in a footprint library
* ( no spaces, dir separators ... ).
*
* @param aName is the name in library to validate.
* @return true if the given name is valid
*/
static bool IsLibNameValid( const wxString& aName );
/**
* Test for validity of the name in a library of the footprint ( no spaces, dir
* separators ... ).
*
* @param aUserReadable set to false to get the list of invalid characters or true to get
* a readable form (i.e ' ' = 'space' '\\t'= 'tab').
*
* @return the list of invalid chars in the library name.
*/
static const wxChar* StringLibNameInvalidChars( bool aUserReadable );
/**
* Return true if a board footprint differs from the library version.
*/
bool FootprintNeedsUpdate( const FOOTPRINT* aLibFP, int aCompareFlags = 0,
REPORTER* aReporter = nullptr );
/**
* Take ownership of caller's heap allocated aInitialComments block.
*
* The comments are single line strings already containing the s-expression comments with
* optional leading whitespace and then a '#' character followed by optional single line
* text (text with no line endings, not even one). This block of single line comments
* will be output upfront of any generated s-expression text in the PCBIO::Format() function.
*
* @note A block of single line comments constitutes a multiline block of single line
* comments. That is, the block is made of consecutive single line comments.
*
* @param aInitialComments is a heap allocated wxArrayString or NULL, which the caller
* gives up ownership of over to this FOOTPRINT.
*/
void SetInitialComments( wxArrayString* aInitialComments )
{
delete m_initial_comments;
m_initial_comments = aInitialComments;
}
/**
* Calculate the ratio of total area of the footprint pads and graphical items to the
* area of the footprint. Used by selection tool heuristics.
*
* @return the ratio.
*/
double CoverageRatio( const GENERAL_COLLECTOR& aCollector ) const;
static double GetCoverageArea( const BOARD_ITEM* aItem, const GENERAL_COLLECTOR& aCollector );
/// Return the initial comments block or NULL if none, without transfer of ownership.
const wxArrayString* GetInitialComments() const { return m_initial_comments; }
/**
* Used in DRC to test the courtyard area (a complex polygon).
*
* @return the courtyard polygon.
*/
const SHAPE_POLY_SET& GetCourtyard( PCB_LAYER_ID aLayer ) const;
/**
* Return the cached courtyard area. No checks are performed.
*
* @return the cached courtyard polygon.
*/
const SHAPE_POLY_SET& GetCachedCourtyard( PCB_LAYER_ID aLayer ) const;
/**
* Build complex polygons of the courtyard areas from graphic items on the courtyard layers.
*
* @note Set the #MALFORMED_F_COURTYARD and #MALFORMED_B_COURTYARD status flags if the given
* courtyard layer does not contain a (single) closed shape.
*/
void BuildCourtyardCaches( OUTLINE_ERROR_HANDLER* aErrorHandler = nullptr );
// @copydoc BOARD_ITEM::GetEffectiveShape
std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER,
FLASHING aFlash = FLASHING::DEFAULT ) const override;
EMBEDDED_FILES* GetEmbeddedFiles() override
{
return static_cast<EMBEDDED_FILES*>( this );
}
const EMBEDDED_FILES* GetEmbeddedFiles() const
{
return static_cast<const EMBEDDED_FILES*>( this );
}
void EmbedFonts() override;
double Similarity( const BOARD_ITEM& aOther ) const override;
void SetComponentClass( const COMPONENT_CLASS* aClass ) { m_componentClass = aClass; }
const COMPONENT_CLASS* GetComponentClass() const { return m_componentClass; }