KiCad PCB EDA Suite
board.cpp
Go to the documentation of this file.
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 wanadoo.fr
5 * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <[email protected]>
6 * Copyright (C) 2011 Wayne Stambaugh <[email protected]>
7 *
8 * Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, you may find one here:
22 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
23 * or you may search the http://www.gnu.org website for the version 2 license,
24 * or you may write to the Free Software Foundation, Inc.,
25 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
26 */
27
28#include <iterator>
29
30#include <wx/log.h>
31
32#include <drc/drc_rtree.h>
34#include <board_commit.h>
35#include <board.h>
36#include <core/arraydim.h>
37#include <core/kicad_algo.h>
40#include <footprint.h>
41#include <pcb_base_frame.h>
42#include <pcb_track.h>
43#include <pcb_marker.h>
44#include <pcb_group.h>
45#include <pcb_target.h>
46#include <pcb_shape.h>
47#include <pcb_bitmap.h>
48#include <pcb_text.h>
49#include <pcb_textbox.h>
50#include <pgm_base.h>
51#include <pcbnew_settings.h>
52#include <progress_reporter.h>
53#include <project.h>
58#include <reporter.h>
60#include <string_utils.h>
61#include <thread_pool.h>
62#include <zone.h>
63
64// This is an odd place for this, but CvPcb won't link if it's in board_item.cpp like I first
65// tried it.
67
68
71 m_LegacyDesignSettingsLoaded( false ),
72 m_LegacyCopperEdgeClearanceLoaded( false ),
73 m_LegacyNetclassesLoaded( false ),
74 m_boardUse( BOARD_USE::NORMAL ),
75 m_timeStamp( 1 ),
76 m_paper( PAGE_INFO::A4 ),
77 m_project( nullptr ),
78 m_designSettings( new BOARD_DESIGN_SETTINGS( nullptr, "board.design_settings" ) ),
79 m_NetInfo( this )
80{
81 // we have not loaded a board yet, assume latest until then.
82 m_fileFormatVersionAtLoad = LEGACY_BOARD_FILE_VERSION;
83
84 for( int layer = 0; layer < PCB_LAYER_ID_COUNT; ++layer )
85 {
87
88 if( IsCopperLayer( layer ) )
89 m_layers[layer].m_type = LT_SIGNAL;
90 else
92 }
93
94 m_SolderMask = new ZONE( this );
95 m_SolderMask->SetLayerSet( LSET().set( F_Mask ).set( B_Mask ) );
96 int infinity = ( std::numeric_limits<int>::max() / 2 ) - pcbIUScale.mmToIU( 1 );
98 m_SolderMask->Outline()->Append( VECTOR2I( -infinity, -infinity ) );
99 m_SolderMask->Outline()->Append( VECTOR2I( -infinity, +infinity ) );
100 m_SolderMask->Outline()->Append( VECTOR2I( +infinity, +infinity ) );
101 m_SolderMask->Outline()->Append( VECTOR2I( +infinity, -infinity ) );
103
105
106 // Initialize default netclass.
107 bds.m_NetSettings->m_DefaultNetClass = std::make_shared<NETCLASS>( NETCLASS::Default );
108 bds.m_NetSettings->m_DefaultNetClass->SetDescription( _( "This is the default net class." ) );
109
110 bds.UseCustomTrackViaSize( false );
111
112 // Initialize ratsnest
113 m_connectivity.reset( new CONNECTIVITY_DATA() );
114
115 // Set flag bits on these that will only be cleared if these are loaded from a legacy file
116 m_LegacyVisibleLayers.reset().set( Rescue );
118}
119
120
122{
123 // Clean up the owned elements
125
126 for( ZONE* zone : m_zones )
127 delete zone;
128
129 m_zones.clear();
130
131 delete m_SolderMask;
132
133 for( FOOTPRINT* footprint : m_footprints )
134 delete footprint;
135
136 m_footprints.clear();
137
138 for( PCB_TRACK* t : m_tracks )
139 delete t;
140
141 m_tracks.clear();
142
143 for( BOARD_ITEM* d : m_drawings )
144 delete d;
145
146 m_drawings.clear();
147
148 for( PCB_GROUP* g : m_groups )
149 delete g;
150
151 m_groups.clear();
152}
153
154
156{
157 GetConnectivity()->Build( this, aReporter );
159}
160
161
162void BOARD::SetProject( PROJECT* aProject, bool aReferenceOnly )
163{
164 if( m_project )
165 ClearProject();
166
167 m_project = aProject;
168
169 if( aProject && !aReferenceOnly )
170 {
171 PROJECT_FILE& project = aProject->GetProjectFile();
172
173 // Link the design settings object to the project file
174 project.m_BoardSettings = &GetDesignSettings();
175
176 // Set parent, which also will load the values from JSON stored in the project if we don't
177 // have legacy design settings loaded already
178 project.m_BoardSettings->SetParent( &project, !m_LegacyDesignSettingsLoaded );
179
180 // The DesignSettings' netclasses pointer will be pointing to its internal netclasses
181 // list at this point. If we loaded anything into it from a legacy board file then we
182 // want to transfer it over to the project netclasses list.
184 {
185 std::shared_ptr<NET_SETTINGS> legacySettings = GetDesignSettings().m_NetSettings;
186 project.NetSettings()->m_DefaultNetClass = legacySettings->m_DefaultNetClass;
187 project.NetSettings()->m_NetClasses = legacySettings->m_NetClasses;
188 }
189
190 // Now update the DesignSettings' netclass pointer to point into the project.
191 GetDesignSettings().m_NetSettings = project.NetSettings();
192 }
193}
194
195
197{
198 if( !m_project )
199 return;
200
202
203 // Owned by the BOARD
204 if( project.m_BoardSettings )
205 {
206 project.ReleaseNestedSettings( project.m_BoardSettings );
207 project.m_BoardSettings = nullptr;
208 }
209
211 GetDesignSettings().SetParent( nullptr );
212 m_project = nullptr;
213}
214
215
217{
218 m_timeStamp++;
219
220 {
221 std::unique_lock<std::mutex> cacheLock( m_CachesMutex );
222 m_IntersectsAreaCache.clear();
223 m_EnclosedByAreaCache.clear();
228
231 m_DRCZones.clear();
232 m_DRCCopperZones.clear();
234 m_CopperItemRTreeCache = std::make_unique<DRC_RTREE>();
235 }
236}
237
238
240{
241 std::set<std::pair<KIID, KIID>> m_ratsnestExclusions;
242
243 for( PCB_MARKER* marker : GetBoard()->Markers() )
244 {
245 if( marker->GetMarkerType() == MARKER_BASE::MARKER_RATSNEST && marker->IsExcluded() )
246 {
247 const std::shared_ptr<RC_ITEM>& rcItem = marker->GetRCItem();
248 m_ratsnestExclusions.emplace( rcItem->GetMainItemID(), rcItem->GetAuxItemID() );
249 m_ratsnestExclusions.emplace( rcItem->GetAuxItemID(), rcItem->GetMainItemID() );
250 }
251 }
252
253 GetConnectivity()->RunOnUnconnectedEdges(
254 [&]( CN_EDGE& aEdge )
255 {
256 std::pair<KIID, KIID> ids = { aEdge.GetSourceNode()->Parent()->m_Uuid,
257 aEdge.GetTargetNode()->Parent()->m_Uuid };
258
259 aEdge.SetVisible( m_ratsnestExclusions.count( ids ) == 0 );
260
261 return true;
262 } );
263}
264
265
266std::vector<PCB_MARKER*> BOARD::ResolveDRCExclusions()
267{
268 for( PCB_MARKER* marker : GetBoard()->Markers() )
269 {
270 auto i = m_designSettings->m_DrcExclusions.find( marker->Serialize() );
271
272 if( i != m_designSettings->m_DrcExclusions.end() )
273 {
274 marker->SetExcluded( true );
275 m_designSettings->m_DrcExclusions.erase( i );
276 }
277 }
278
279 std::vector<PCB_MARKER*> newMarkers;
280
281 for( const wxString& exclusionData : m_designSettings->m_DrcExclusions )
282 {
283 PCB_MARKER* marker = PCB_MARKER::Deserialize( exclusionData );
284
285 if( marker )
286 {
287 marker->SetExcluded( true );
288 newMarkers.push_back( marker );
289 }
290 }
291
292 m_designSettings->m_DrcExclusions.clear();
293
294 return newMarkers;
295}
296
297
298bool BOARD::ResolveTextVar( wxString* token, int aDepth ) const
299{
300 if( GetTitleBlock().TextVarResolver( token, m_project ) )
301 {
302 return true;
303 }
304 else if( m_properties.count( *token ) )
305 {
306 *token = m_properties.at( *token );
307 return true;
308 }
309
310 return false;
311}
312
313
315{
316 return ZeroOffset;
317}
318
319
320void BOARD::SetPosition( const VECTOR2I& aPos )
321{
322 wxLogWarning( wxT( "This should not be called on the BOARD object") );
323}
324
325
326void BOARD::Move( const VECTOR2I& aMoveVector ) // overload
327{
328 INSPECTOR_FUNC inspector =
329 [&] ( EDA_ITEM* item, void* testData )
330 {
331 BOARD_ITEM* brdItem = static_cast<BOARD_ITEM*>( item );
332
333 // aMoveVector was snapshotted, don't need "data".
334 // Only move the top level group
335 if( brdItem->GetParentGroup() == nullptr )
336 brdItem->Move( aMoveVector );
337
339 };
340
341 Visit( inspector, nullptr, GENERAL_COLLECTOR::BoardLevelItems );
342}
343
344
345TRACKS BOARD::TracksInNet( int aNetCode )
346{
347 TRACKS ret;
348
349 INSPECTOR_FUNC inspector = [aNetCode, &ret]( EDA_ITEM* item, void* testData )
350 {
351 PCB_TRACK* t = static_cast<PCB_TRACK*>( item );
352
353 if( t->GetNetCode() == aNetCode )
354 ret.push_back( t );
355
357 };
358
359 // visit this BOARD's PCB_TRACKs and PCB_VIAs with above TRACK INSPECTOR which
360 // appends all in aNetCode to ret.
361 Visit( inspector, nullptr, GENERAL_COLLECTOR::Tracks );
362
363 return ret;
364}
365
366
367bool BOARD::SetLayerDescr( PCB_LAYER_ID aIndex, const LAYER& aLayer )
368{
369 if( unsigned( aIndex ) < arrayDim( m_layers ) )
370 {
371 m_layers[ aIndex ] = aLayer;
372 return true;
373 }
374
375 return false;
376}
377
378
379const PCB_LAYER_ID BOARD::GetLayerID( const wxString& aLayerName ) const
380{
381 // Check the BOARD physical layer names.
382 for( int layer = 0; layer < PCB_LAYER_ID_COUNT; ++layer )
383 {
384 if ( m_layers[ layer ].m_name == aLayerName || m_layers[ layer ].m_userName == aLayerName )
385 return ToLAYER_ID( layer );
386 }
387
388 // Otherwise fall back to the system standard layer names for virtual layers.
389 for( int layer = 0; layer < PCB_LAYER_ID_COUNT; ++layer )
390 {
391 if( GetStandardLayerName( ToLAYER_ID( layer ) ) == aLayerName )
392 return ToLAYER_ID( layer );
393 }
394
395 return UNDEFINED_LAYER;
396}
397
398
399const wxString BOARD::GetLayerName( PCB_LAYER_ID aLayer ) const
400{
401 // All layer names are stored in the BOARD.
402 if( IsLayerEnabled( aLayer ) )
403 {
404 // Standard names were set in BOARD::BOARD() but they may be over-ridden by
405 // BOARD::SetLayerName(). For copper layers, return the user defined layer name,
406 // if it was set. Otherwise return the Standard English layer name.
407 if( !m_layers[aLayer].m_userName.IsEmpty() )
408 return m_layers[aLayer].m_userName;
409 }
410
411 return GetStandardLayerName( aLayer );
412}
413
414
415bool BOARD::SetLayerName( PCB_LAYER_ID aLayer, const wxString& aLayerName )
416{
417 wxCHECK( !aLayerName.IsEmpty(), false );
418
419 // no quote chars in the name allowed
420 if( aLayerName.Find( wxChar( '"' ) ) != wxNOT_FOUND )
421 return false;
422
423 if( IsLayerEnabled( aLayer ) )
424 {
425 m_layers[aLayer].m_userName = aLayerName;
426 return true;
427 }
428
429 return false;
430}
431
432
434{
435 if( !IsCopperLayer( aLayer ) )
436 return LT_SIGNAL;
437
438 if( IsLayerEnabled( aLayer ) )
439 return m_layers[aLayer].m_type;
440
441 return LT_SIGNAL;
442}
443
444
445bool BOARD::SetLayerType( PCB_LAYER_ID aLayer, LAYER_T aLayerType )
446{
447 if( !IsCopperLayer( aLayer ) )
448 return false;
449
450 if( IsLayerEnabled( aLayer ) )
451 {
452 m_layers[aLayer].m_type = aLayerType;
453 return true;
454 }
455
456 return false;
457}
458
459
460const char* LAYER::ShowType( LAYER_T aType )
461{
462 switch( aType )
463 {
464 default:
465 case LT_SIGNAL: return "signal";
466 case LT_POWER: return "power";
467 case LT_MIXED: return "mixed";
468 case LT_JUMPER: return "jumper";
469 }
470}
471
472
473LAYER_T LAYER::ParseType( const char* aType )
474{
475 if( strcmp( aType, "signal" ) == 0 )
476 return LT_SIGNAL;
477 else if( strcmp( aType, "power" ) == 0 )
478 return LT_POWER;
479 else if( strcmp( aType, "mixed" ) == 0 )
480 return LT_MIXED;
481 else if( strcmp( aType, "jumper" ) == 0 )
482 return LT_JUMPER;
483 else
484 return LT_UNDEFINED;
485}
486
487
489{
491}
492
493
495{
497}
498
499
501{
503}
504
505
507{
508 // If there is no project, assume layer is visible always
509 return GetDesignSettings().IsLayerEnabled( aLayer )
511}
512
513
515{
517}
518
519
521{
522 GetDesignSettings().SetEnabledLayers( aLayerSet );
523}
524
525
527{
528 return GetDesignSettings().IsLayerEnabled( aLayer );
529}
530
531
533{
534 if( m_project )
536}
537
538
540{
541 // Call SetElementVisibility for each item
542 // to ensure specific calculations that can be needed by some items,
543 // just changing the visibility flags could be not sufficient.
544 for( size_t i = 0; i < aSet.size(); i++ )
545 SetElementVisibility( GAL_LAYER_ID_START + static_cast<int>( i ), aSet[i] );
546}
547
548
550{
551 SetVisibleLayers( LSET().set() );
552
553 // Call SetElementVisibility for each item,
554 // to ensure specific calculations that can be needed by some items
556 SetElementVisibility( ii, true );
557}
558
559
561{
563}
564
565
567{
569}
570
571
572void BOARD::SetElementVisibility( GAL_LAYER_ID aLayer, bool isEnabled )
573{
574 if( m_project )
576
577 switch( aLayer )
578 {
579 case LAYER_RATSNEST:
580 {
581 // because we have a tool to show/hide ratsnest relative to a pad or a footprint
582 // so the hide/show option is a per item selection
583
584 for( PCB_TRACK* track : Tracks() )
585 track->SetLocalRatsnestVisible( isEnabled );
586
587 for( FOOTPRINT* footprint : Footprints() )
588 {
589 for( PAD* pad : footprint->Pads() )
590 pad->SetLocalRatsnestVisible( isEnabled );
591 }
592
593 for( ZONE* zone : Zones() )
594 zone->SetLocalRatsnestVisible( isEnabled );
595
596 break;
597 }
598
599 default:
600 ;
601 }
602}
603
604
606{
607 switch( aLayer )
608 {
609 case F_Cu: return IsElementVisible( LAYER_MOD_FR );
610 case B_Cu: return IsElementVisible( LAYER_MOD_BK );
611 default: wxFAIL_MSG( wxT( "BOARD::IsModuleLayerVisible(): bad layer" ) ); return true;
612 }
613}
614
615
616
618{
619 return *m_designSettings;
620}
621
622
624{
626}
627
628
629void BOARD::SetZoneSettings( const ZONE_SETTINGS& aSettings )
630{
632}
633
634
635void BOARD::CacheTriangulation( PROGRESS_REPORTER* aReporter, const std::vector<ZONE*>& aZones )
636{
637 std::vector<ZONE*> zones = aZones;
638
639 if( zones.empty() )
640 zones = m_zones;
641
642 if( zones.empty() )
643 return;
644
645 if( aReporter )
646 aReporter->Report( _( "Tessellating copper zones..." ) );
647
649 std::vector<std::future<size_t>> returns;
650
651 returns.reserve( zones.size() );
652
653 auto cache_zones = [aReporter]( ZONE* aZone ) -> size_t
654 {
655 if( aReporter && aReporter->IsCancelled() )
656 return 0;
657
658 aZone->CacheTriangulation();
659
660 if( aReporter )
661 aReporter->AdvanceProgress();
662
663 return 1;
664 };
665
666 for( ZONE* zone : zones )
667 returns.emplace_back( tp.submit( cache_zones, zone ) );
668
669 // Finalize the triangulation threads
670 for( const std::future<size_t>& ret : returns )
671 {
672 std::future_status status = ret.wait_for( std::chrono::milliseconds( 250 ) );
673
674 while( status != std::future_status::ready )
675 {
676 if( aReporter )
677 aReporter->KeepRefreshing();
678
679 status = ret.wait_for( std::chrono::milliseconds( 250 ) );
680 }
681 }
682}
683
684
685void BOARD::Add( BOARD_ITEM* aBoardItem, ADD_MODE aMode, bool aSkipConnectivity )
686{
687 if( aBoardItem == nullptr )
688 {
689 wxFAIL_MSG( wxT( "BOARD::Add() param error: aBoardItem nullptr" ) );
690 return;
691 }
692
693 switch( aBoardItem->Type() )
694 {
695 case PCB_NETINFO_T:
696 m_NetInfo.AppendNet( (NETINFO_ITEM*) aBoardItem );
697 break;
698
699 // this one uses a vector
700 case PCB_MARKER_T:
701 m_markers.push_back( (PCB_MARKER*) aBoardItem );
702 break;
703
704 // this one uses a vector
705 case PCB_GROUP_T:
706 m_groups.push_back( (PCB_GROUP*) aBoardItem );
707 break;
708
709 // this one uses a vector
710 case PCB_ZONE_T:
711 m_zones.push_back( (ZONE*) aBoardItem );
712 break;
713
714 case PCB_TRACE_T:
715 case PCB_VIA_T:
716 case PCB_ARC_T:
717
718 // N.B. This inserts a small memory leak as we lose the
719 if( !IsCopperLayer( aBoardItem->GetLayer() ) )
720 {
721 wxFAIL_MSG( wxT( "BOARD::Add() Cannot place Track on non-copper layer" ) );
722 return;
723 }
724
725 if( aMode == ADD_MODE::APPEND || aMode == ADD_MODE::BULK_APPEND )
726 m_tracks.push_back( static_cast<PCB_TRACK*>( aBoardItem ) );
727 else
728 m_tracks.push_front( static_cast<PCB_TRACK*>( aBoardItem ) );
729
730 break;
731
732 case PCB_FOOTPRINT_T:
733 if( aMode == ADD_MODE::APPEND || aMode == ADD_MODE::BULK_APPEND )
734 m_footprints.push_back( static_cast<FOOTPRINT*>( aBoardItem ) );
735 else
736 m_footprints.push_front( static_cast<FOOTPRINT*>( aBoardItem ) );
737
738 break;
739
741 case PCB_DIM_CENTER_T:
742 case PCB_DIM_RADIAL_T:
744 case PCB_DIM_LEADER_T:
745 case PCB_SHAPE_T:
746 case PCB_BITMAP_T:
747 case PCB_TEXT_T:
748 case PCB_TEXTBOX_T:
749 case PCB_TARGET_T:
750 if( aMode == ADD_MODE::APPEND || aMode == ADD_MODE::BULK_APPEND )
751 m_drawings.push_back( aBoardItem );
752 else
753 m_drawings.push_front( aBoardItem );
754
755 break;
756
757 // other types may use linked list
758 default:
759 {
760 wxString msg;
761 msg.Printf( wxT( "BOARD::Add() needs work: BOARD_ITEM type (%d) not handled" ),
762 aBoardItem->Type() );
763 wxFAIL_MSG( msg );
764 return;
765 }
766 break;
767 }
768
769 aBoardItem->SetParent( this );
770 aBoardItem->ClearEditFlags();
771
772 if( !aSkipConnectivity )
773 m_connectivity->Add( aBoardItem );
774
775 if( aMode != ADD_MODE::BULK_INSERT && aMode != ADD_MODE::BULK_APPEND )
776 {
778 }
779}
780
781
782void BOARD::FinalizeBulkAdd( std::vector<BOARD_ITEM*>& aNewItems )
783{
785}
786
787
788void BOARD::FinalizeBulkRemove( std::vector<BOARD_ITEM*>& aRemovedItems )
789{
791}
792
793
794void BOARD::Remove( BOARD_ITEM* aBoardItem, REMOVE_MODE aRemoveMode )
795{
796 // find these calls and fix them! Don't send me no stinking' nullptr.
797 wxASSERT( aBoardItem );
798
799 switch( aBoardItem->Type() )
800 {
801 case PCB_NETINFO_T:
802 {
803 NETINFO_ITEM* item = static_cast<NETINFO_ITEM*>( aBoardItem );
805
806 for( FOOTPRINT* fp : m_footprints )
807 {
808 for( PAD* pad : fp->Pads() )
809 {
810 if( pad->GetNet() == item )
811 pad->SetNet( unconnected );
812 }
813 }
814
815 for( ZONE* zone : m_zones )
816 {
817 if( zone->GetNet() == item )
818 zone->SetNet( unconnected );
819 }
820
821 for( PCB_TRACK* track : m_tracks )
822 {
823 if( track->GetNet() == item )
824 track->SetNet( unconnected );
825 }
826
827 m_NetInfo.RemoveNet( item );
828 break;
829 }
830
831 case PCB_MARKER_T:
832 alg::delete_matching( m_markers, aBoardItem );
833 break;
834
835 case PCB_GROUP_T:
836 alg::delete_matching( m_groups, aBoardItem );
837 break;
838
839 case PCB_ZONE_T:
840 alg::delete_matching( m_zones, aBoardItem );
841 break;
842
843 case PCB_FOOTPRINT_T:
844 alg::delete_matching( m_footprints, aBoardItem );
845 break;
846
847 case PCB_TRACE_T:
848 case PCB_ARC_T:
849 case PCB_VIA_T:
850 alg::delete_matching( m_tracks, aBoardItem );
851 break;
852
854 case PCB_DIM_CENTER_T:
855 case PCB_DIM_RADIAL_T:
857 case PCB_DIM_LEADER_T:
858 case PCB_SHAPE_T:
859 case PCB_BITMAP_T:
860 case PCB_TEXT_T:
861 case PCB_TEXTBOX_T:
862 case PCB_TARGET_T:
863 alg::delete_matching( m_drawings, aBoardItem );
864 break;
865
866 // other types may use linked list
867 default:
868 wxFAIL_MSG( wxT( "BOARD::Remove() needs more ::Type() support" ) );
869 }
870
871 aBoardItem->SetFlags( STRUCT_DELETED );
872
873 PCB_GROUP* parentGroup = aBoardItem->GetParentGroup();
874
875 if( parentGroup && !( parentGroup->GetFlags() & STRUCT_DELETED ) )
876 parentGroup->RemoveItem( aBoardItem );
877
878 m_connectivity->Remove( aBoardItem );
879
880 if( aRemoveMode != REMOVE_MODE::BULK )
882}
883
884
885wxString BOARD::GetSelectMenuText( UNITS_PROVIDER* aUnitsProvider ) const
886{
887 return wxString::Format( _( "PCB" ) );
888}
889
890
892{
893 // the vector does not know how to delete the PCB_MARKER, it holds pointers
894 for( PCB_MARKER* marker : m_markers )
895 delete marker;
896
897 m_markers.clear();
898}
899
900
901void BOARD::DeleteMARKERs( bool aWarningsAndErrors, bool aExclusions )
902{
903 // Deleting lots of items from a vector can be very slow. Copy remaining items instead.
904 MARKERS remaining;
905
906 for( PCB_MARKER* marker : m_markers )
907 {
908 if( ( marker->GetSeverity() == RPT_SEVERITY_EXCLUSION && aExclusions )
909 || ( marker->GetSeverity() != RPT_SEVERITY_EXCLUSION && aWarningsAndErrors ) )
910 {
911 delete marker;
912 }
913 else
914 {
915 remaining.push_back( marker );
916 }
917 }
918
919 m_markers = remaining;
920}
921
922
924{
925 for( FOOTPRINT* footprint : m_footprints )
926 delete footprint;
927
928 m_footprints.clear();
929}
930
931
932BOARD_ITEM* BOARD::GetItem( const KIID& aID ) const
933{
934 if( aID == niluuid )
935 return nullptr;
936
937 for( PCB_TRACK* track : Tracks() )
938 {
939 if( track->m_Uuid == aID )
940 return track;
941 }
942
943 for( FOOTPRINT* footprint : Footprints() )
944 {
945 if( footprint->m_Uuid == aID )
946 return footprint;
947
948 for( PAD* pad : footprint->Pads() )
949 {
950 if( pad->m_Uuid == aID )
951 return pad;
952 }
953
954 if( footprint->Reference().m_Uuid == aID )
955 return &footprint->Reference();
956
957 if( footprint->Value().m_Uuid == aID )
958 return &footprint->Value();
959
960 for( BOARD_ITEM* drawing : footprint->GraphicalItems() )
961 {
962 if( drawing->m_Uuid == aID )
963 return drawing;
964 }
965
966 for( BOARD_ITEM* zone : footprint->Zones() )
967 {
968 if( zone->m_Uuid == aID )
969 return zone;
970 }
971
972 for( PCB_GROUP* group : footprint->Groups() )
973 {
974 if( group->m_Uuid == aID )
975 return group;
976 }
977 }
978
979 for( ZONE* zone : Zones() )
980 {
981 if( zone->m_Uuid == aID )
982 return zone;
983 }
984
985 for( BOARD_ITEM* drawing : Drawings() )
986 {
987 if( drawing->m_Uuid == aID )
988 return drawing;
989 }
990
991 for( PCB_MARKER* marker : m_markers )
992 {
993 if( marker->m_Uuid == aID )
994 return marker;
995 }
996
997 for( PCB_GROUP* group : m_groups )
998 {
999 if( group->m_Uuid == aID )
1000 return group;
1001 }
1002
1003 if( m_Uuid == aID )
1004 return const_cast<BOARD*>( this );
1005
1006 // Not found; weak reference has been deleted.
1008}
1009
1010
1011void BOARD::FillItemMap( std::map<KIID, EDA_ITEM*>& aMap )
1012{
1013 // the board itself
1014 aMap[ m_Uuid ] = this;
1015
1016 for( PCB_TRACK* track : Tracks() )
1017 aMap[ track->m_Uuid ] = track;
1018
1019 for( FOOTPRINT* footprint : Footprints() )
1020 {
1021 aMap[ footprint->m_Uuid ] = footprint;
1022
1023 for( PAD* pad : footprint->Pads() )
1024 aMap[ pad->m_Uuid ] = pad;
1025
1026 aMap[ footprint->Reference().m_Uuid ] = &footprint->Reference();
1027 aMap[ footprint->Value().m_Uuid ] = &footprint->Value();
1028
1029 for( BOARD_ITEM* drawing : footprint->GraphicalItems() )
1030 aMap[ drawing->m_Uuid ] = drawing;
1031 }
1032
1033 for( ZONE* zone : Zones() )
1034 aMap[ zone->m_Uuid ] = zone;
1035
1036 for( BOARD_ITEM* drawing : Drawings() )
1037 aMap[ drawing->m_Uuid ] = drawing;
1038
1039 for( PCB_MARKER* marker : m_markers )
1040 aMap[ marker->m_Uuid ] = marker;
1041
1042 for( PCB_GROUP* group : m_groups )
1043 aMap[ group->m_Uuid ] = group;
1044}
1045
1046
1047wxString BOARD::ConvertCrossReferencesToKIIDs( const wxString& aSource ) const
1048{
1049 wxString newbuf;
1050 size_t sourceLen = aSource.length();
1051
1052 for( size_t i = 0; i < sourceLen; ++i )
1053 {
1054 if( aSource[i] == '$' && i + 1 < sourceLen && aSource[i+1] == '{' )
1055 {
1056 wxString token;
1057 bool isCrossRef = false;
1058
1059 for( i = i + 2; i < sourceLen; ++i )
1060 {
1061 if( aSource[i] == '}' )
1062 break;
1063
1064 if( aSource[i] == ':' )
1065 isCrossRef = true;
1066
1067 token.append( aSource[i] );
1068 }
1069
1070 if( isCrossRef )
1071 {
1072 wxString remainder;
1073 wxString ref = token.BeforeFirst( ':', &remainder );
1074
1075 for( const FOOTPRINT* footprint : Footprints() )
1076 {
1077 if( footprint->GetReference().CmpNoCase( ref ) == 0 )
1078 {
1079 wxString test( remainder );
1080
1081 if( footprint->ResolveTextVar( &test ) )
1082 token = footprint->m_Uuid.AsString() + wxT( ":" ) + remainder;
1083
1084 break;
1085 }
1086 }
1087 }
1088
1089 newbuf.append( wxT( "${" ) + token + wxT( "}" ) );
1090 }
1091 else
1092 {
1093 newbuf.append( aSource[i] );
1094 }
1095 }
1096
1097 return newbuf;
1098}
1099
1100
1101wxString BOARD::ConvertKIIDsToCrossReferences( const wxString& aSource ) const
1102{
1103 wxString newbuf;
1104 size_t sourceLen = aSource.length();
1105
1106 for( size_t i = 0; i < sourceLen; ++i )
1107 {
1108 if( aSource[i] == '$' && i + 1 < sourceLen && aSource[i+1] == '{' )
1109 {
1110 wxString token;
1111 bool isCrossRef = false;
1112
1113 for( i = i + 2; i < sourceLen; ++i )
1114 {
1115 if( aSource[i] == '}' )
1116 break;
1117
1118 if( aSource[i] == ':' )
1119 isCrossRef = true;
1120
1121 token.append( aSource[i] );
1122 }
1123
1124 if( isCrossRef )
1125 {
1126 wxString remainder;
1127 wxString ref = token.BeforeFirst( ':', &remainder );
1128 BOARD_ITEM* refItem = GetItem( KIID( ref ) );
1129
1130 if( refItem && refItem->Type() == PCB_FOOTPRINT_T )
1131 {
1132 token = static_cast<FOOTPRINT*>( refItem )->GetReference() + wxT( ":" )
1133 + remainder;
1134 }
1135 }
1136
1137 newbuf.append( wxT( "${" ) + token + wxT( "}" ) );
1138 }
1139 else
1140 {
1141 newbuf.append( aSource[i] );
1142 }
1143 }
1144
1145 return newbuf;
1146}
1147
1148
1149unsigned BOARD::GetNodesCount( int aNet ) const
1150{
1151 unsigned retval = 0;
1152
1153 for( FOOTPRINT* footprint : Footprints() )
1154 {
1155 for( PAD* pad : footprint->Pads() )
1156 {
1157 if( ( aNet == -1 && pad->GetNetCode() > 0 ) || aNet == pad->GetNetCode() )
1158 retval++;
1159 }
1160 }
1161
1162 return retval;
1163}
1164
1165
1166BOX2I BOARD::ComputeBoundingBox( bool aBoardEdgesOnly ) const
1167{
1168 BOX2I bbox;
1169 LSET visible = GetVisibleLayers();
1170 bool showInvisibleText = IsElementVisible( LAYER_MOD_TEXT_INVISIBLE )
1171 && PgmOrNull() && !PgmOrNull()->m_Printing;
1172
1173 if( aBoardEdgesOnly )
1174 visible.set( Edge_Cuts );
1175
1176 // Check shapes, dimensions, texts, and fiducials
1177 for( BOARD_ITEM* item : m_drawings )
1178 {
1179 if( aBoardEdgesOnly && ( item->GetLayer() != Edge_Cuts || item->Type() != PCB_SHAPE_T ) )
1180 continue;
1181
1182 if( ( item->GetLayerSet() & visible ).any() )
1183 bbox.Merge( item->GetBoundingBox() );
1184 }
1185
1186 // Check footprints
1187 for( FOOTPRINT* footprint : m_footprints )
1188 {
1189 if( !( footprint->GetLayerSet() & visible ).any() )
1190 continue;
1191
1192 if( aBoardEdgesOnly )
1193 {
1194 for( const BOARD_ITEM* edge : footprint->GraphicalItems() )
1195 {
1196 if( edge->GetLayer() == Edge_Cuts && edge->Type() == PCB_FP_SHAPE_T )
1197 bbox.Merge( edge->GetBoundingBox() );
1198 }
1199 }
1200 else
1201 {
1202 bbox.Merge( footprint->GetBoundingBox( true, showInvisibleText ) );
1203 }
1204 }
1205
1206 if( !aBoardEdgesOnly )
1207 {
1208 // Check tracks
1209 for( PCB_TRACK* track : m_tracks )
1210 {
1211 if( ( track->GetLayerSet() & visible ).any() )
1212 bbox.Merge( track->GetBoundingBox() );
1213 }
1214
1215 // Check zones
1216 for( ZONE* aZone : m_zones )
1217 {
1218 if( ( aZone->GetLayerSet() & visible ).any() )
1219 bbox.Merge( aZone->GetBoundingBox() );
1220 }
1221 }
1222
1223 return bbox;
1224}
1225
1226
1227void BOARD::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
1228{
1229 int padCount = 0;
1230 int viaCount = 0;
1231 int trackSegmentCount = 0;
1232 std::set<int> netCodes;
1233 int unconnected = GetConnectivity()->GetUnconnectedCount( true );
1234
1235 for( PCB_TRACK* item : m_tracks )
1236 {
1237 if( item->Type() == PCB_VIA_T )
1238 viaCount++;
1239 else
1240 trackSegmentCount++;
1241
1242 if( item->GetNetCode() > 0 )
1243 netCodes.insert( item->GetNetCode() );
1244 }
1245
1246 for( FOOTPRINT* footprint : Footprints() )
1247 {
1248 for( PAD* pad : footprint->Pads() )
1249 {
1250 padCount++;
1251
1252 if( pad->GetNetCode() > 0 )
1253 netCodes.insert( pad->GetNetCode() );
1254 }
1255 }
1256
1257 aList.emplace_back( _( "Pads" ), wxString::Format( wxT( "%d" ), padCount ) );
1258 aList.emplace_back( _( "Vias" ), wxString::Format( wxT( "%d" ), viaCount ) );
1259 aList.emplace_back( _( "Track Segments" ), wxString::Format( wxT( "%d" ), trackSegmentCount ) );
1260 aList.emplace_back( _( "Nets" ), wxString::Format( wxT( "%d" ), (int) netCodes.size() ) );
1261 aList.emplace_back( _( "Unrouted" ), wxString::Format( wxT( "%d" ), unconnected ) );
1262}
1263
1264
1265INSPECT_RESULT BOARD::Visit( INSPECTOR inspector, void* testData,
1266 const std::vector<KICAD_T>& scanTypes )
1267{
1268#if 0 && defined(DEBUG)
1269 std::cout << GetClass().mb_str() << ' ';
1270#endif
1271
1272 bool footprintsScanned = false;
1273 bool drawingsScanned = false;
1274 bool tracksScanned = false;
1275
1276 for( KICAD_T scanType : scanTypes )
1277 {
1278 switch( scanType )
1279 {
1280 case PCB_T:
1281 if( inspector( this, testData ) == INSPECT_RESULT::QUIT )
1282 return INSPECT_RESULT::QUIT;
1283
1284 break;
1285
1286 /*
1287 * Instances of the requested KICAD_T live in a list, either one that I manage, or one
1288 * that my footprints manage. If it's a type managed by class FOOTPRINT, then simply
1289 * pass it on to each footprint's Visit() function via IterateForward( m_footprints, ... ).
1290 */
1291
1292 case PCB_FOOTPRINT_T:
1293 case PCB_PAD_T:
1294 case PCB_FP_TEXT_T:
1295 case PCB_FP_TEXTBOX_T:
1296 case PCB_FP_SHAPE_T:
1302 case PCB_FP_ZONE_T:
1303 if( !footprintsScanned )
1304 {
1305 if( IterateForward<FOOTPRINT*>( m_footprints, inspector, testData, scanTypes )
1307 {
1308 return INSPECT_RESULT::QUIT;
1309 }
1310
1311 footprintsScanned = true;
1312 }
1313
1314 break;
1315
1316 case PCB_SHAPE_T:
1317 case PCB_BITMAP_T:
1318 case PCB_TEXT_T:
1319 case PCB_TEXTBOX_T:
1320 case PCB_DIM_ALIGNED_T:
1321 case PCB_DIM_CENTER_T:
1322 case PCB_DIM_RADIAL_T:
1324 case PCB_DIM_LEADER_T:
1325 case PCB_TARGET_T:
1326 if( !drawingsScanned )
1327 {
1328 if( IterateForward<BOARD_ITEM*>( m_drawings, inspector, testData, scanTypes )
1330 {
1331 return INSPECT_RESULT::QUIT;
1332 }
1333
1334 drawingsScanned = true;
1335 }
1336
1337 break;
1338
1339 case PCB_VIA_T:
1340 case PCB_TRACE_T:
1341 case PCB_ARC_T:
1342 if( !tracksScanned )
1343 {
1344 if( IterateForward<PCB_TRACK*>( m_tracks, inspector, testData, scanTypes )
1346 {
1347 return INSPECT_RESULT::QUIT;
1348 }
1349
1350 tracksScanned = true;
1351 }
1352
1353 break;
1354
1355 case PCB_MARKER_T:
1356 for( PCB_MARKER* marker : m_markers )
1357 {
1358 if( marker->Visit( inspector, testData, { scanType } ) == INSPECT_RESULT::QUIT )
1359 return INSPECT_RESULT::QUIT;
1360 }
1361
1362 break;
1363
1364 case PCB_ZONE_T:
1365 for( ZONE* zone : m_zones)
1366 {
1367 if( zone->Visit( inspector, testData, { scanType } ) == INSPECT_RESULT::QUIT )
1368 return INSPECT_RESULT::QUIT;
1369 }
1370
1371 break;
1372
1373 case PCB_GROUP_T:
1374 if( IterateForward<PCB_GROUP*>( m_groups, inspector, testData, { scanType } )
1376 {
1377 return INSPECT_RESULT::QUIT;
1378 }
1379
1380 break;
1381
1382 default:
1383 break;
1384 }
1385 }
1386
1388}
1389
1390
1391NETINFO_ITEM* BOARD::FindNet( int aNetcode ) const
1392{
1393 // the first valid netcode is 1 and the last is m_NetInfo.GetCount()-1.
1394 // zero is reserved for "no connection" and is not actually a net.
1395 // nullptr is returned for non valid netcodes
1396
1397 wxASSERT( m_NetInfo.GetNetCount() > 0 );
1398
1399 if( aNetcode == NETINFO_LIST::UNCONNECTED && m_NetInfo.GetNetCount() == 0 )
1401 else
1402 return m_NetInfo.GetNetItem( aNetcode );
1403}
1404
1405
1406NETINFO_ITEM* BOARD::FindNet( const wxString& aNetname ) const
1407{
1408 return m_NetInfo.GetNetItem( aNetname );
1409}
1410
1411
1412FOOTPRINT* BOARD::FindFootprintByReference( const wxString& aReference ) const
1413{
1414 for( FOOTPRINT* footprint : m_footprints )
1415 {
1416 if( aReference == footprint->GetReference() )
1417 return footprint;
1418 }
1419
1420 return nullptr;
1421}
1422
1423
1425{
1426 for( FOOTPRINT* footprint : m_footprints )
1427 {
1428 if( footprint->GetPath() == aPath )
1429 return footprint;
1430 }
1431
1432 return nullptr;
1433}
1434
1435
1437{
1438 std::set<wxString> names;
1439
1440 for( const NETINFO_ITEM* net : m_NetInfo )
1441 {
1442 if( !net->GetNetname().IsEmpty() )
1443 names.insert( net->GetNetname() );
1444 }
1445
1446 return names;
1447}
1448
1449
1451{
1452 wxCHECK( m_project, /*void*/ );
1453
1454 if( !m_project->IsNullProject() )
1456}
1457
1458
1460{
1461 if( !m_project )
1462 return;
1463
1465 std::shared_ptr<NETCLASS>& defaultNetClass = bds.m_NetSettings->m_DefaultNetClass;
1466
1467 for( NETINFO_ITEM* net : m_NetInfo )
1468 net->SetNetClass( bds.m_NetSettings->GetEffectiveNetClass( net->GetNetname() ) );
1469
1470 // Set initial values for custom track width & via size to match the default
1471 // netclass settings
1472 bds.UseCustomTrackViaSize( false );
1473 bds.SetCustomTrackWidth( defaultNetClass->GetTrackWidth() );
1474 bds.SetCustomViaSize( defaultNetClass->GetViaDiameter() );
1475 bds.SetCustomViaDrill( defaultNetClass->GetViaDrill() );
1476 bds.SetCustomDiffPairWidth( defaultNetClass->GetDiffPairWidth() );
1477 bds.SetCustomDiffPairGap( defaultNetClass->GetDiffPairGap() );
1478 bds.SetCustomDiffPairViaGap( defaultNetClass->GetDiffPairViaGap() );
1479
1481}
1482
1483
1485{
1486 int error_count = 0;
1487
1488 for( ZONE* zone : Zones() )
1489 {
1490 if( !zone->IsOnCopperLayer() )
1491 {
1492 zone->SetNetCode( NETINFO_LIST::UNCONNECTED );
1493 continue;
1494 }
1495
1496 if( zone->GetNetCode() != 0 ) // i.e. if this zone is connected to a net
1497 {
1498 const NETINFO_ITEM* net = zone->GetNet();
1499
1500 if( net )
1501 {
1502 zone->SetNetCode( net->GetNetCode() );
1503 }
1504 else
1505 {
1506 error_count++;
1507
1508 // keep Net Name and set m_NetCode to -1 : error flag.
1509 zone->SetNetCode( -1 );
1510 }
1511 }
1512 }
1513
1514 return error_count;
1515}
1516
1517
1518PAD* BOARD::GetPad( const VECTOR2I& aPosition, LSET aLayerSet ) const
1519{
1520 if( !aLayerSet.any() )
1521 aLayerSet = LSET::AllCuMask();
1522
1523 for( FOOTPRINT* footprint : m_footprints )
1524 {
1525 PAD* pad = nullptr;
1526
1527 if( footprint->HitTest( aPosition ) )
1528 pad = footprint->GetPad( aPosition, aLayerSet );
1529
1530 if( pad )
1531 return pad;
1532 }
1533
1534 return nullptr;
1535}
1536
1537
1538PAD* BOARD::GetPad( const PCB_TRACK* aTrace, ENDPOINT_T aEndPoint ) const
1539{
1540 const VECTOR2I& aPosition = aTrace->GetEndPoint( aEndPoint );
1541
1542 LSET lset( aTrace->GetLayer() );
1543
1544 return GetPad( aPosition, lset );
1545}
1546
1547
1548PAD* BOARD::GetPadFast( const VECTOR2I& aPosition, LSET aLayerSet ) const
1549{
1550 for( FOOTPRINT* footprint : Footprints() )
1551 {
1552 for( PAD* pad : footprint->Pads() )
1553 {
1554 if( pad->GetPosition() != aPosition )
1555 continue;
1556
1557 // Pad found, it must be on the correct layer
1558 if( ( pad->GetLayerSet() & aLayerSet ).any() )
1559 return pad;
1560 }
1561 }
1562
1563 return nullptr;
1564}
1565
1566
1567PAD* BOARD::GetPad( std::vector<PAD*>& aPadList, const VECTOR2I& aPosition, LSET aLayerSet ) const
1568{
1569 // Search aPadList for aPosition
1570 // aPadList is sorted by X then Y values, and a fast binary search is used
1571 int idxmax = aPadList.size() - 1;
1572
1573 int delta = aPadList.size();
1574
1575 int idx = 0; // Starting index is the beginning of list
1576
1577 while( delta )
1578 {
1579 // Calculate half size of remaining interval to test.
1580 // Ensure the computed value is not truncated (too small)
1581 if( (delta & 1) && ( delta > 1 ) )
1582 delta++;
1583
1584 delta /= 2;
1585
1586 PAD* pad = aPadList[idx];
1587
1588 if( pad->GetPosition() == aPosition ) // candidate found
1589 {
1590 // The pad must match the layer mask:
1591 if( ( aLayerSet & pad->GetLayerSet() ).any() )
1592 return pad;
1593
1594 // More than one pad can be at aPosition
1595 // search for a pad at aPosition that matched this mask
1596
1597 // search next
1598 for( int ii = idx+1; ii <= idxmax; ii++ )
1599 {
1600 pad = aPadList[ii];
1601
1602 if( pad->GetPosition() != aPosition )
1603 break;
1604
1605 if( ( aLayerSet & pad->GetLayerSet() ).any() )
1606 return pad;
1607 }
1608 // search previous
1609 for( int ii = idx - 1 ;ii >=0; ii-- )
1610 {
1611 pad = aPadList[ii];
1612
1613 if( pad->GetPosition() != aPosition )
1614 break;
1615
1616 if( ( aLayerSet & pad->GetLayerSet() ).any() )
1617 return pad;
1618 }
1619
1620 // Not found:
1621 return nullptr;
1622 }
1623
1624 if( pad->GetPosition().x == aPosition.x ) // Must search considering Y coordinate
1625 {
1626 if( pad->GetPosition().y < aPosition.y ) // Must search after this item
1627 {
1628 idx += delta;
1629
1630 if( idx > idxmax )
1631 idx = idxmax;
1632 }
1633 else // Must search before this item
1634 {
1635 idx -= delta;
1636
1637 if( idx < 0 )
1638 idx = 0;
1639 }
1640 }
1641 else if( pad->GetPosition().x < aPosition.x ) // Must search after this item
1642 {
1643 idx += delta;
1644
1645 if( idx > idxmax )
1646 idx = idxmax;
1647 }
1648 else // Must search before this item
1649 {
1650 idx -= delta;
1651
1652 if( idx < 0 )
1653 idx = 0;
1654 }
1655 }
1656
1657 return nullptr;
1658}
1659
1660
1666bool sortPadsByXthenYCoord( PAD* const & aLH, PAD* const & aRH )
1667{
1668 if( aLH->GetPosition().x == aRH->GetPosition().x )
1669 return aLH->GetPosition().y < aRH->GetPosition().y;
1670
1671 return aLH->GetPosition().x < aRH->GetPosition().x;
1672}
1673
1674
1675void BOARD::GetSortedPadListByXthenYCoord( std::vector<PAD*>& aVector, int aNetCode ) const
1676{
1677 for( FOOTPRINT* footprint : Footprints() )
1678 {
1679 for( PAD* pad : footprint->Pads( ) )
1680 {
1681 if( aNetCode < 0 || pad->GetNetCode() == aNetCode )
1682 aVector.push_back( pad );
1683 }
1684 }
1685
1686 std::sort( aVector.begin(), aVector.end(), sortPadsByXthenYCoord );
1687}
1688
1689
1691{
1692 GetConnectivity()->Remove( aPad );
1693
1695
1696 aPad->DeleteStructure();
1697}
1698
1699
1700std::tuple<int, double, double> BOARD::GetTrackLength( const PCB_TRACK& aTrack ) const
1701{
1702 int count = 0;
1703 double length = 0.0;
1704 double package_length = 0.0;
1705
1706 auto connectivity = GetBoard()->GetConnectivity();
1709
1710 for( BOARD_CONNECTED_ITEM* item : connectivity->GetConnectedItems(
1711 static_cast<const BOARD_CONNECTED_ITEM*>( &aTrack ),
1712 { PCB_TRACE_T, PCB_ARC_T, PCB_VIA_T, PCB_PAD_T } ) )
1713 {
1714 count++;
1715
1716 if( PCB_TRACK* track = dynamic_cast<PCB_TRACK*>( item ) )
1717 {
1718 if( track->Type() == PCB_VIA_T && useHeight )
1719 {
1720 PCB_VIA* via = static_cast<PCB_VIA*>( track );
1721 length += stackup.GetLayerDistance( via->TopLayer(), via->BottomLayer() );
1722 continue;
1723 }
1724 else if( track->Type() == PCB_ARC_T )
1725 {
1726 // Note: we don't apply the clip-to-pad optimization if an arc ends in a pad
1727 // Room for future improvement.
1728 length += track->GetLength();
1729 continue;
1730 }
1731
1732 bool inPad = false;
1733 SEG trackSeg( track->GetStart(), track->GetEnd() );
1734 double segLen = trackSeg.Length();
1735 double segInPadLen = 0;
1736
1737 for( auto pad_it : connectivity->GetConnectedPads( item ) )
1738 {
1739 PAD* pad = static_cast<PAD*>( pad_it );
1740
1741 bool hitStart = pad->HitTest( track->GetStart(), track->GetWidth() / 2 );
1742 bool hitEnd = pad->HitTest( track->GetEnd(), track->GetWidth() / 2 );
1743
1744 if( hitStart && hitEnd )
1745 {
1746 inPad = true;
1747 break;
1748 }
1749 else if( hitStart || hitEnd )
1750 {
1751 VECTOR2I loc;
1752
1753 // We may not collide even if we passed the bounding-box hit test
1754 if( pad->GetEffectivePolygon()->Collide( trackSeg, 0, nullptr, &loc ) )
1755 {
1756 // Part 1: length of the seg to the intersection with the pad poly
1757 if( hitStart )
1758 trackSeg.A = loc;
1759 else
1760 trackSeg.B = loc;
1761
1762 segLen = trackSeg.Length();
1763
1764 // Part 2: length from the intersection to the pad anchor
1765 segInPadLen += ( loc - pad->GetPosition() ).EuclideanNorm();
1766 }
1767 }
1768 }
1769
1770 if( !inPad )
1771 length += segLen + segInPadLen;
1772 }
1773 else if( PAD* pad = dyn_cast<PAD*>( item ) )
1774 {
1775 package_length += pad->GetPadToDieLength();
1776 }
1777 }
1778
1779 return std::make_tuple( count, length, package_length );
1780}
1781
1782
1783FOOTPRINT* BOARD::GetFootprint( const VECTOR2I& aPosition, PCB_LAYER_ID aActiveLayer,
1784 bool aVisibleOnly, bool aIgnoreLocked ) const
1785{
1786 FOOTPRINT* footprint = nullptr;
1787 FOOTPRINT* alt_footprint = nullptr;
1788 int min_dim = 0x7FFFFFFF;
1789 int alt_min_dim = 0x7FFFFFFF;
1790 bool current_layer_back = IsBackLayer( aActiveLayer );
1791
1792 for( FOOTPRINT* candidate : m_footprints )
1793 {
1794 // is the ref point within the footprint's bounds?
1795 if( !candidate->HitTest( aPosition ) )
1796 continue;
1797
1798 // if caller wants to ignore locked footprints, and this one is locked, skip it.
1799 if( aIgnoreLocked && candidate->IsLocked() )
1800 continue;
1801
1802 PCB_LAYER_ID layer = candidate->GetLayer();
1803
1804 // Filter non visible footprints if requested
1805 if( !aVisibleOnly || IsFootprintLayerVisible( layer ) )
1806 {
1807 BOX2I bb = candidate->GetBoundingBox( false, false );
1808
1809 int offx = bb.GetX() + bb.GetWidth() / 2;
1810 int offy = bb.GetY() + bb.GetHeight() / 2;
1811
1812 // off x & offy point to the middle of the box.
1813 int dist = ( aPosition.x - offx ) * ( aPosition.x - offx ) +
1814 ( aPosition.y - offy ) * ( aPosition.y - offy );
1815
1816 if( current_layer_back == IsBackLayer( layer ) )
1817 {
1818 if( dist <= min_dim )
1819 {
1820 // better footprint shown on the active side
1821 footprint = candidate;
1822 min_dim = dist;
1823 }
1824 }
1825 else if( aVisibleOnly && IsFootprintLayerVisible( layer ) )
1826 {
1827 if( dist <= alt_min_dim )
1828 {
1829 // better footprint shown on the other side
1830 alt_footprint = candidate;
1831 alt_min_dim = dist;
1832 }
1833 }
1834 }
1835 }
1836
1837 if( footprint )
1838 return footprint;
1839
1840 if( alt_footprint)
1841 return alt_footprint;
1842
1843 return nullptr;
1844}
1845
1846
1847std::list<ZONE*> BOARD::GetZoneList( bool aIncludeZonesInFootprints ) const
1848{
1849 std::list<ZONE*> zones;
1850
1851 for( ZONE* zone : Zones() )
1852 zones.push_back( zone );
1853
1854 if( aIncludeZonesInFootprints )
1855 {
1856 for( FOOTPRINT* footprint : m_footprints )
1857 {
1858 for( FP_ZONE* zone : footprint->Zones() )
1859 zones.push_back( zone );
1860 }
1861 }
1862
1863 return zones;
1864}
1865
1866
1867ZONE* BOARD::AddArea( PICKED_ITEMS_LIST* aNewZonesList, int aNetcode, PCB_LAYER_ID aLayer,
1868 VECTOR2I aStartPointPosition, ZONE_BORDER_DISPLAY_STYLE aHatch )
1869{
1870 ZONE* new_area = new ZONE( this );
1871
1872 new_area->SetNetCode( aNetcode );
1873 new_area->SetLayer( aLayer );
1874
1875 m_zones.push_back( new_area );
1876
1877 new_area->SetHatchStyle( (ZONE_BORDER_DISPLAY_STYLE) aHatch );
1878
1879 // Add the first corner to the new zone
1880 new_area->AppendCorner( aStartPointPosition, -1 );
1881
1882 if( aNewZonesList )
1883 {
1884 ITEM_PICKER picker( nullptr, new_area, UNDO_REDO::NEWITEM );
1885 aNewZonesList->PushItem( picker );
1886 }
1887
1888 return new_area;
1889}
1890
1891
1893 OUTLINE_ERROR_HANDLER* aErrorHandler )
1894{
1895 int chainingEpsilon = pcbIUScale.mmToIU( 0.02 ); // max dist from one endPt to next startPt
1896
1897 bool success = BuildBoardPolygonOutlines( this, aOutlines, GetDesignSettings().m_MaxError,
1898 chainingEpsilon, aErrorHandler );
1899
1900 // Make polygon strictly simple to avoid issues (especially in 3D viewer)
1902
1903 return success;
1904}
1905
1906
1907const std::vector<PAD*> BOARD::GetPads() const
1908{
1909 std::vector<PAD*> allPads;
1910
1911 for( FOOTPRINT* footprint : Footprints() )
1912 {
1913 for( PAD* pad : footprint->Pads() )
1914 allPads.push_back( pad );
1915 }
1916
1917 return allPads;
1918}
1919
1920
1921const std::vector<BOARD_CONNECTED_ITEM*> BOARD::AllConnectedItems()
1922{
1923 std::vector<BOARD_CONNECTED_ITEM*> items;
1924
1925 for( PCB_TRACK* track : Tracks() )
1926 items.push_back( track );
1927
1928 for( FOOTPRINT* footprint : Footprints() )
1929 {
1930 for( PAD* pad : footprint->Pads() )
1931 items.push_back( pad );
1932 }
1933
1934 for( ZONE* zone : Zones() )
1935 items.push_back( zone );
1936
1937 return items;
1938}
1939
1940
1941void BOARD::MapNets( const BOARD* aDestBoard )
1942{
1944 {
1945 NETINFO_ITEM* netInfo = aDestBoard->FindNet( item->GetNetname() );
1946
1947 if( netInfo )
1948 item->SetNet( netInfo );
1949 else
1950 item->SetNetCode( 0 );
1951 }
1952}
1953
1954
1956{
1957 for ( BOARD_CONNECTED_ITEM* item : AllConnectedItems() )
1958 {
1959 if( FindNet( item->GetNetCode() ) == nullptr )
1960 item->SetNetCode( NETINFO_LIST::ORPHANED );
1961 }
1962}
1963
1964
1966{
1967 if( !alg::contains( m_listeners, aListener ) )
1968 m_listeners.push_back( aListener );
1969}
1970
1971
1973{
1974 auto i = std::find( m_listeners.begin(), m_listeners.end(), aListener );
1975
1976 if( i != m_listeners.end() )
1977 {
1978 std::iter_swap( i, m_listeners.end() - 1 );
1979 m_listeners.pop_back();
1980 }
1981}
1982
1983
1985{
1986 m_listeners.clear();
1987}
1988
1989
1991{
1993}
1994
1995
1996void BOARD::OnItemsChanged( std::vector<BOARD_ITEM*>& aItems )
1997{
1999}
2000
2001
2003{
2006
2008}
2009
2010
2011void BOARD::SetHighLightNet( int aNetCode, bool aMulti )
2012{
2013 if( !m_highLight.m_netCodes.count( aNetCode ) )
2014 {
2015 if( !aMulti )
2016 m_highLight.m_netCodes.clear();
2017
2018 m_highLight.m_netCodes.insert( aNetCode );
2020 }
2021}
2022
2023
2024void BOARD::HighLightON( bool aValue )
2025{
2026 if( m_highLight.m_highLightOn != aValue )
2027 {
2028 m_highLight.m_highLightOn = aValue;
2030 }
2031}
2032
2033
2034wxString BOARD::GroupsSanityCheck( bool repair )
2035{
2036 if( repair )
2037 {
2038 while( GroupsSanityCheckInternal( repair ) != wxEmptyString )
2039 {};
2040
2041 return wxEmptyString;
2042 }
2043 return GroupsSanityCheckInternal( repair );
2044}
2045
2046
2048{
2049 // Cycle detection
2050 //
2051 // Each group has at most one parent group.
2052 // So we start at group 0 and traverse the parent chain, marking groups seen along the way.
2053 // If we ever see a group that we've already marked, that's a cycle.
2054 // If we reach the end of the chain, we know all groups in that chain are not part of any cycle.
2055 //
2056 // Algorithm below is linear in the # of groups because each group is visited only once.
2057 // There may be extra time taken due to the container access calls and iterators.
2058 //
2059 // Groups we know are cycle free
2060 std::unordered_set<PCB_GROUP*> knownCycleFreeGroups;
2061 // Groups in the current chain we're exploring.
2062 std::unordered_set<PCB_GROUP*> currentChainGroups;
2063 // Groups we haven't checked yet.
2064 std::unordered_set<PCB_GROUP*> toCheckGroups;
2065
2066 // Initialize set of groups to check that could participate in a cycle.
2067 for( PCB_GROUP* group : Groups() )
2068 toCheckGroups.insert( group);
2069
2070 while( !toCheckGroups.empty() )
2071 {
2072 currentChainGroups.clear();
2073 PCB_GROUP* group = *toCheckGroups.begin();
2074
2075 while( true )
2076 {
2077 if( currentChainGroups.find( group ) != currentChainGroups.end() )
2078 {
2079 if( repair )
2080 Remove( group );
2081
2082 return "Cycle detected in group membership";
2083 }
2084 else if( knownCycleFreeGroups.find( group ) != knownCycleFreeGroups.end() )
2085 {
2086 // Parent is a group we know does not lead to a cycle
2087 break;
2088 }
2089
2090 currentChainGroups.insert( group );
2091 // We haven't visited currIdx yet, so it must be in toCheckGroups
2092 toCheckGroups.erase( group );
2093
2094 group = group->GetParentGroup();
2095
2096 if( !group )
2097 {
2098 // end of chain and no cycles found in this chain
2099 break;
2100 }
2101 }
2102
2103 // No cycles found in chain, so add it to set of groups we know don't participate
2104 // in a cycle.
2105 knownCycleFreeGroups.insert( currentChainGroups.begin(), currentChainGroups.end() );
2106 }
2107
2108 // Success
2109 return "";
2110}
2111
2112
2114{
2115 bool hasGroup = false;
2116 bool hasMember = false;
2117
2118 for( EDA_ITEM* item : selection )
2119 {
2120 if( item->Type() == PCB_GROUP_T )
2121 hasGroup = true;
2122
2123 if( static_cast<BOARD_ITEM*>( item )->GetParentGroup() )
2124 hasMember = true;
2125 }
2126
2127 GroupLegalOpsField legalOps;
2128
2129 legalOps.create = true;
2130 legalOps.removeItems = hasMember;
2131 legalOps.ungroup = hasGroup;
2132 legalOps.enter = hasGroup && selection.Size() == 1;
2133
2134 return legalOps;
2135}
2136
2137
2139{
2140 if( a->Type() != b->Type() )
2141 return a->Type() < b->Type();
2142
2143 if( a->GetLayer() != b->GetLayer() )
2144 return a->GetLayer() < b->GetLayer();
2145
2146 if( a->GetPosition().x != b->GetPosition().x )
2147 return a->GetPosition().x < b->GetPosition().x;
2148
2149 if( a->GetPosition().y != b->GetPosition().y )
2150 return a->GetPosition().y < b->GetPosition().y;
2151
2152 if( a->m_Uuid != b->m_Uuid ) // shopuld be always the case foer valid boards
2153 return a->m_Uuid < b->m_Uuid;
2154
2155 return a < b;
2156}
2157
2158
2160 const BOARD_ITEM* aSecond ) const
2161{
2162 if( aFirst->Type() != aSecond->Type() )
2163 return aFirst->Type() < aSecond->Type();
2164
2165 if( aFirst->GetLayer() != aSecond->GetLayer() )
2166 return aFirst->GetLayer() < aSecond->GetLayer();
2167
2168 if( aFirst->Type() == PCB_SHAPE_T )
2169 {
2170 const PCB_SHAPE* shape = static_cast<const PCB_SHAPE*>( aFirst );
2171 const PCB_SHAPE* other = static_cast<const PCB_SHAPE*>( aSecond );
2172 return shape->Compare( other );
2173 }
2174 else if( aFirst->Type() == PCB_TEXT_T )
2175 {
2176 const PCB_TEXT* text = static_cast<const PCB_TEXT*>( aFirst );
2177 const PCB_TEXT* other = static_cast<const PCB_TEXT*>( aSecond );
2178 return text->Compare( other );
2179 }
2180 else if( aFirst->Type() == PCB_TEXTBOX_T )
2181 {
2182 const PCB_TEXTBOX* textbox = static_cast<const PCB_TEXTBOX*>( aFirst );
2183 const PCB_TEXTBOX* other = static_cast<const PCB_TEXTBOX*>( aSecond );
2184
2185 return textbox->PCB_SHAPE::Compare( other ) && textbox->EDA_TEXT::Compare( other );
2186 }
2187
2188 return aFirst->m_Uuid < aSecond->m_Uuid;
2189}
2190
2191
2193 SHAPE_POLY_SET& aOutlines ) const
2194{
2195 int maxError = GetDesignSettings().m_MaxError;
2196
2197 // convert tracks and vias:
2198 for( const PCB_TRACK* track : m_tracks )
2199 {
2200 if( !track->IsOnLayer( aLayer ) )
2201 continue;
2202
2203 track->TransformShapeWithClearanceToPolygon( aOutlines, aLayer, 0, maxError,
2204 ERROR_INSIDE );
2205 }
2206
2207 // convert pads and other copper items in footprints
2208 for( const FOOTPRINT* footprint : m_footprints )
2209 {
2210 footprint->TransformPadsWithClearanceToPolygon( aOutlines, aLayer, 0, maxError,
2211 ERROR_INSIDE );
2212
2213 // Microwave footprints may have items on copper layers
2214 footprint->TransformFPShapesWithClearanceToPolygon( aOutlines, aLayer, 0, maxError,
2216 true, /* include text */
2217 true, /* include shapes */
2218 false /* include private items */ );
2219
2220 for( const ZONE* zone : footprint->Zones() )
2221 {
2222 if( zone->GetLayerSet().test( aLayer ) )
2223 zone->TransformSolidAreasShapesToPolygon( aLayer, aOutlines );
2224 }
2225 }
2226
2227 // convert copper zones
2228 for( const ZONE* zone : Zones() )
2229 {
2230 if( zone->GetLayerSet().test( aLayer ) )
2231 zone->TransformSolidAreasShapesToPolygon( aLayer, aOutlines );
2232 }
2233
2234 // convert graphic items on copper layers (texts)
2235 for( const BOARD_ITEM* item : m_drawings )
2236 {
2237 if( !item->IsOnLayer( aLayer ) )
2238 continue;
2239
2240 switch( item->Type() )
2241 {
2242 case PCB_SHAPE_T:
2243 {
2244 const PCB_SHAPE* shape = static_cast<const PCB_SHAPE*>( item );
2245 shape->TransformShapeWithClearanceToPolygon( aOutlines, aLayer, 0, maxError,
2246 ERROR_INSIDE );
2247 break;
2248 }
2249
2250 case PCB_TEXT_T:
2251 {
2252 const PCB_TEXT* text = static_cast<const PCB_TEXT*>( item );
2253 text->TransformTextShapeWithClearanceToPolygon( aOutlines, aLayer, 0, maxError,
2254 ERROR_INSIDE );
2255 break;
2256 }
2257
2258 case PCB_TEXTBOX_T:
2259 {
2260 const PCB_TEXTBOX* textbox = static_cast<const PCB_TEXTBOX*>( item );
2261
2262 // plot border
2263 textbox->PCB_SHAPE::TransformShapeWithClearanceToPolygon( aOutlines, aLayer, 0,
2264 maxError, ERROR_INSIDE );
2265 // plot text
2266 textbox->TransformTextShapeWithClearanceToPolygon( aOutlines, aLayer, 0, maxError,
2267 ERROR_INSIDE );
2268 break;
2269 }
2270
2271 default:
2272 break;
2273 }
2274 }
2275}
2276
2277
@ NORMAL
Use all material properties from model file.
constexpr std::size_t arrayDim(T const (&)[N]) noexcept
Returns # of elements in an array.
Definition: arraydim.h:31
constexpr EDA_IU_SCALE pcbIUScale
Definition: base_units.h:109
bool sortPadsByXthenYCoord(PAD *const &aLH, PAD *const &aRH)
Used by #GetSortedPadListByXCoord to sort a pad list by X coordinate value.
Definition: board.cpp:1666
BOARD_USE
Flags to specify how the board is being used.
Definition: board.h:255
LAYER_T
The allowed types of layers, same as Specctra DSN spec.
Definition: board.h:143
@ LT_POWER
Definition: board.h:146
@ LT_MIXED
Definition: board.h:147
@ LT_UNDEFINED
Definition: board.h:144
@ LT_JUMPER
Definition: board.h:148
@ LT_SIGNAL
Definition: board.h:145
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
bool SetNetCode(int aNetCode, bool aNoAssert)
Set net using a net code.
Container for design settings for a BOARD object.
void UseCustomTrackViaSize(bool aEnabled)
Enables/disables custom track/via size settings.
void SetCustomDiffPairWidth(int aWidth)
Sets custom track width for differential pairs (i.e.
std::shared_ptr< NET_SETTINGS > m_NetSettings
void SetCustomTrackWidth(int aWidth)
Sets custom width for track (i.e.
void SetEnabledLayers(LSET aMask)
Change the bit-mask of enabled layers to aMask.
LSET GetEnabledLayers() const
Return a bit-mask of all the layers that are enabled.
void SetCustomViaSize(int aSize)
Set custom size for via diameter (i.e.
void SetCustomDiffPairGap(int aGap)
Sets custom gap for differential pairs (i.e.
bool IsLayerEnabled(PCB_LAYER_ID aLayerId) const
Test whether a given layer aLayerId is enabled.
BOARD_STACKUP & GetStackupDescriptor()
void SetCustomViaDrill(int aDrill)
Sets custom size for via drill (i.e.
void SetDefaultZoneSettings(const ZONE_SETTINGS &aSettings)
ZONE_SETTINGS & GetDefaultZoneSettings()
bool m_UseHeightForLengthCalcs
Enable inclusion of stackup height in track length measurements and length tuning.
void SetCopperLayerCount(int aNewLayerCount)
Set the copper layer count to aNewLayerCount.
void SetCustomDiffPairViaGap(int aGap)
Sets custom via gap for differential pairs (i.e.
Abstract interface for BOARD_ITEMs capable of storing other items inside.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:50
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition: board_item.h:167
void DeleteStructure()
Delete this object after removing from its parent if it has one.
Definition: board_item.cpp:144
PCB_GROUP * GetParentGroup() const
Definition: board_item.h:62
virtual void Move(const VECTOR2I &aMoveVector)
Move this object.
Definition: board_item.h:253
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
Definition: board_item.cpp:37
static VECTOR2I ZeroOffset
A value of wxPoint(0,0) which can be passed to the Draw() functions.
Definition: board_item.h:131
wxString GetLayerName() const
Return the name of the PCB layer on which the item resides.
Definition: board_item.cpp:88
virtual void OnBoardNetSettingsChanged(BOARD &aBoard)
Definition: board.h:244
virtual void OnBoardItemsAdded(BOARD &aBoard, std::vector< BOARD_ITEM * > &aBoardItem)
Definition: board.h:241
virtual void OnBoardItemsChanged(BOARD &aBoard, std::vector< BOARD_ITEM * > &aBoardItem)
Definition: board.h:246
virtual void OnBoardItemChanged(BOARD &aBoard, BOARD_ITEM *aBoardItem)
Definition: board.h:245
virtual void OnBoardItemRemoved(BOARD &aBoard, BOARD_ITEM *aBoardItem)
Definition: board.h:242
virtual void OnBoardItemAdded(BOARD &aBoard, BOARD_ITEM *aBoardItem)
Definition: board.h:240
virtual void OnBoardHighlightNetChanged(BOARD &aBoard)
Definition: board.h:247
virtual void OnBoardItemsRemoved(BOARD &aBoard, std::vector< BOARD_ITEM * > &aBoardItem)
Definition: board.h:243
Manage layers needed to make a physical board.
int GetLayerDistance(PCB_LAYER_ID aFirstLayer, PCB_LAYER_ID aSecondLayer) const
Calculate the distance (height) between the two given copper layers.
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:265
INSPECT_RESULT Visit(INSPECTOR inspector, void *testData, const std::vector< KICAD_T > &scanTypes) override
May be re-implemented for each derived class in order to handle all the types given by its member dat...
Definition: board.cpp:1265
bool IsFootprintLayerVisible(PCB_LAYER_ID aLayer) const
Expect either of the two layers on which a footprint can reside, and returns whether that layer is vi...
Definition: board.cpp:605
std::unordered_map< PTR_PTR_LAYER_CACHE_KEY, bool > m_EnclosedByAreaCache
Definition: board.h:1150
void OnItemChanged(BOARD_ITEM *aItem)
Notify the board and its listeners that an item on the board has been modified in some way.
Definition: board.cpp:1990
bool m_LegacyDesignSettingsLoaded
True if the legacy board design settings were loaded from a file.
Definition: board.h:342
LSET GetEnabledLayers() const
A proxy function that calls the corresponding function in m_BoardSettings.
Definition: board.cpp:500
void SetPosition(const VECTOR2I &aPos) override
Definition: board.cpp:320
std::map< wxString, wxString > m_properties
Definition: board.h:1198
int m_fileFormatVersionAtLoad
Definition: board.h:1195
LSET GetVisibleLayers() const
A proxy function that calls the correspondent function in m_BoardSettings.
Definition: board.cpp:514
std::vector< ZONE * > m_DRCCopperZones
Definition: board.h:1157
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
Definition: board.cpp:685
GAL_SET m_LegacyVisibleItems
Definition: board.h:339
void SetZoneSettings(const ZONE_SETTINGS &aSettings) override
Set the zone settings for this container.
Definition: board.cpp:629
PAD * GetPadFast(const VECTOR2I &aPosition, LSET aLayerMask) const
Return pad found at aPosition on aLayerMask using the fast search method.
Definition: board.cpp:1548
LAYER m_layers[PCB_LAYER_ID_COUNT]
Definition: board.h:1190
static wxString GetStandardLayerName(PCB_LAYER_ID aLayerId)
Return an "English Standard" name of a PCB layer when given aLayerNumber.
Definition: board.h:694
const std::vector< BOARD_CONNECTED_ITEM * > AllConnectedItems()
Definition: board.cpp:1921
bool IsElementVisible(GAL_LAYER_ID aLayer) const
Test whether a given element category is visible.
Definition: board.cpp:566
std::set< wxString > GetNetClassAssignmentCandidates() const
Return the set of netname candidates for netclass assignment.
Definition: board.cpp:1436
const ZONE_SETTINGS & GetZoneSettings() const override
Fetch the zone settings for this container.
Definition: board.cpp:623
void MapNets(const BOARD *aDestBoard)
Map all nets in the given board to nets with the same name (if any) in the destination board.
Definition: board.cpp:1941
void RemoveAllListeners()
Remove all listeners.
Definition: board.cpp:1984
FOOTPRINTS m_footprints
Definition: board.h:1185
std::unique_ptr< BOARD_DESIGN_SETTINGS > m_designSettings
All of the board design settings are stored as a JSON object inside the project file.
Definition: board.h:1216
void SetEnabledLayers(LSET aLayerMask)
A proxy function that calls the correspondent function in m_BoardSettings.
Definition: board.cpp:520
void AddListener(BOARD_LISTENER *aListener)
Add a listener to the board to receive calls whenever something on the board has been modified.
Definition: board.cpp:1965
void SetProperties(const std::map< wxString, wxString > &aProps)
Definition: board.h:333
GAL_SET GetVisibleElements() const
Return a set of all the element categories that are visible.
Definition: board.cpp:560
ZONES & Zones()
Definition: board.h:313
void SetHighLightNet(int aNetCode, bool aMulti=false)
Select the netcode to be highlighted.
Definition: board.cpp:2011
void PadDelete(PAD *aPad)
Delete a given pad from the BOARD by removing it from its footprint and from the m_NetInfo.
Definition: board.cpp:1690
HIGH_LIGHT_INFO m_highLight
Definition: board.h:1192
bool SetLayerDescr(PCB_LAYER_ID aIndex, const LAYER &aLayer)
Return the type of the copper layer given by aLayer.
Definition: board.cpp:367
NETINFO_ITEM * FindNet(int aNetcode) const
Search for a net with the given netcode.
Definition: board.cpp:1391
BOARD_ITEM * GetItem(const KIID &aID) const
Definition: board.cpp:932
void InvokeListeners(Func &&aFunc, Args &&... args)
Definition: board.h:1170
void SanitizeNetcodes()
Definition: board.cpp:1955
ZONE * AddArea(PICKED_ITEMS_LIST *aNewZonesList, int aNetcode, PCB_LAYER_ID aLayer, VECTOR2I aStartPointPosition, ZONE_BORDER_DISPLAY_STYLE aHatch)
Add an empty copper area to board areas list.
Definition: board.cpp:1867
~BOARD()
Definition: board.cpp:121
void SynchronizeNetsAndNetClasses()
Copy NETCLASS info to each NET, based on NET membership in a NETCLASS.
Definition: board.cpp:1459
bool IsLayerEnabled(PCB_LAYER_ID aLayer) const
A proxy function that calls the correspondent function in m_BoardSettings tests whether a given layer...
Definition: board.cpp:526
LAYER_T GetLayerType(PCB_LAYER_ID aLayer) const
Return the type of the copper layer given by aLayer.
Definition: board.cpp:433
DRAWINGS m_drawings
Definition: board.h:1184
int SetAreasNetCodesFromNetNames()
Set the .m_NetCode member of all copper areas, according to the area Net Name The SetNetCodesFromNetN...
Definition: board.cpp:1484
void ResetNetHighLight()
Reset all high light data to the init state.
Definition: board.cpp:2002
bool SetLayerName(PCB_LAYER_ID aLayer, const wxString &aLayerName)
Changes the name of the layer given by aLayer.
Definition: board.cpp:415
std::list< ZONE * > GetZoneList(bool aIncludeZonesInFootprints=false) const
Definition: board.cpp:1847
void ConvertBrdLayerToPolygonalContours(PCB_LAYER_ID aLayer, SHAPE_POLY_SET &aOutlines) const
Build a set of polygons which are the outlines of copper items (pads, tracks, vias,...
Definition: board.cpp:2192
bool ResolveTextVar(wxString *token, int aDepth) const
Definition: board.cpp:298
const std::vector< PAD * > GetPads() const
Return a reference to a list of all the pads.
Definition: board.cpp:1907
bool GetBoardPolygonOutlines(SHAPE_POLY_SET &aOutlines, OUTLINE_ERROR_HANDLER *aErrorHandler=nullptr)
Extract the board outlines and build a closed polygon from lines, arcs and circle items on edge cut l...
Definition: board.cpp:1892
void Move(const VECTOR2I &aMoveVector) override
Move this object.
Definition: board.cpp:326
TITLE_BLOCK & GetTitleBlock()
Definition: board.h:630
BOX2I ComputeBoundingBox(bool aBoardEdgesOnly=false) const
Calculate the bounding box containing all board items (or board edge segments).
Definition: board.cpp:1166
ZONES m_zones
Definition: board.h:1188
FOOTPRINTS & Footprints()
Definition: board.h:307
HIGH_LIGHT_INFO m_highLightPrevious
Definition: board.h:1193
std::unique_ptr< DRC_RTREE > m_CopperItemRTreeCache
Definition: board.h:1153
NETINFO_LIST m_NetInfo
Definition: board.h:1218
LSET m_LegacyVisibleLayers
Visibility settings stored in board prior to 6.0, only used for loading legacy files.
Definition: board.h:338
void SetVisibleAlls()
Change the bit-mask of visible element categories and layers.
Definition: board.cpp:549
GroupLegalOpsField GroupLegalOps(const PCB_SELECTION &selection) const
Check which selection tool group operations are legal given the selection.
Definition: board.cpp:2113
int GetCopperLayerCount() const
Definition: board.cpp:488
int m_timeStamp
Definition: board.h:1180
std::vector< BOARD_LISTENER * > m_listeners
Definition: board.h:1220
const PCB_LAYER_ID GetLayerID(const wxString &aLayerName) const
Return the ID of a layer.
Definition: board.cpp:379
std::unordered_map< PTR_PTR_CACHE_KEY, bool > m_IntersectsCourtyardCache
Definition: board.h:1146
void IncrementTimeStamp()
Definition: board.cpp:216
std::unordered_map< PTR_PTR_CACHE_KEY, bool > m_IntersectsFCourtyardCache
Definition: board.h:1147
std::shared_ptr< CONNECTIVITY_DATA > m_connectivity
Definition: board.h:1199
int m_DRCMaxPhysicalClearance
Definition: board.h:1159
GROUPS & Groups()
The groups must maintain the following invariants.
Definition: board.h:327
FOOTPRINT * FindFootprintByPath(const KIID_PATH &aPath) const
Search for a FOOTPRINT within this board with the given path.
Definition: board.cpp:1424
void FinalizeBulkRemove(std::vector< BOARD_ITEM * > &aRemovedItems)
Must be used if Remove() is used using a BULK_x REMOVE_MODE to generate a change event for listeners.
Definition: board.cpp:788
std::unordered_map< wxString, LSET > m_LayerExpressionCache
Definition: board.h:1151
wxString GroupsSanityCheckInternal(bool repair)
Definition: board.cpp:2047
wxString ConvertCrossReferencesToKIIDs(const wxString &aSource) const
Convert cross-references back and forth between ${refDes:field} and ${kiid:field}.
Definition: board.cpp:1047
TRACKS & Tracks()
Definition: board.h:304
wxString GetClass() const override
Return the class name.
Definition: board.h:879
void SetVisibleLayers(LSET aLayerMask)
A proxy function that calls the correspondent function in m_BoardSettings changes the bit-mask of vis...
Definition: board.cpp:532
bool m_LegacyNetclassesLoaded
True if netclasses were loaded from the file.
Definition: board.h:346
void SetCopperLayerCount(int aCount)
Definition: board.cpp:494
MARKERS & Markers()
Definition: board.h:316
std::unordered_map< PTR_PTR_CACHE_KEY, bool > m_IntersectsBCourtyardCache
Definition: board.h:1148
TRACKS TracksInNet(int aNetCode)
Collect all the TRACKs and VIAs that are members of a net given by aNetCode.
Definition: board.cpp:345
void SetProject(PROJECT *aProject, bool aReferenceOnly=false)
Link a board to a given project.
Definition: board.cpp:162
PROJECT * m_project
Definition: board.h:1204
FOOTPRINT * GetFootprint(const VECTOR2I &aPosition, PCB_LAYER_ID aActiveLayer, bool aVisibleOnly, bool aIgnoreLocked=false) const
Get a footprint by its bounding rectangle at aPosition on aLayer.
Definition: board.cpp:1783
ZONE * m_SolderMask
Definition: board.h:1160
DRAWINGS & Drawings()
Definition: board.h:310
FOOTPRINT * FindFootprintByReference(const wxString &aReference) const
Search for a FOOTPRINT within this board with the given reference designator.
Definition: board.cpp:1412
unsigned GetNodesCount(int aNet=-1) const
Definition: board.cpp:1149
void FillItemMap(std::map< KIID, EDA_ITEM * > &aMap)
Definition: board.cpp:1011
void SetElementVisibility(GAL_LAYER_ID aLayer, bool aNewState)
Change the visibility of an element category.
Definition: board.cpp:572
bool SetLayerType(PCB_LAYER_ID aLayer, LAYER_T aLayerType)
Change the type of the layer given by aLayer.
Definition: board.cpp:445
void GetSortedPadListByXthenYCoord(std::vector< PAD * > &aVector, int aNetCode=-1) const
First empties then fills the vector with all pads and sorts them by increasing x coordinate,...
Definition: board.cpp:1675
bool IsLayerVisible(PCB_LAYER_ID aLayer) const
A proxy function that calls the correspondent function in m_BoardSettings tests whether a given layer...
Definition: board.cpp:506
int m_DRCMaxClearance
Definition: board.h:1158
void ClearProject()
Definition: board.cpp:196
wxString GetSelectMenuText(UNITS_PROVIDER *aUnitsProvider) const override
Return the text to display to be used in the selection clarification context menu when multiple items...
Definition: board.cpp:885
std::unordered_map< ZONE *, std::unique_ptr< DRC_RTREE > > m_CopperZoneRTreeCache
Definition: board.h:1152
void FinalizeBulkAdd(std::vector< BOARD_ITEM * > &aNewItems)
Must be used if Add() is used using a BULK_x ADD_MODE to generate a change event for listeners.
Definition: board.cpp:782
void DeleteAllFootprints()
Remove all footprints from the deque and free the memory associated with them.
Definition: board.cpp:923
std::tuple< int, double, double > GetTrackLength(const PCB_TRACK &aTrack) const
Return data on the length and number of track segments connected to a given track.
Definition: board.cpp:1700
void GetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList) override
Populate aList of MSG_PANEL_ITEM objects with it's internal state for display purposes.
Definition: board.cpp:1227
wxString GroupsSanityCheck(bool repair=false)
Consistency check of internal m_groups structure.
Definition: board.cpp:2034
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:617
std::vector< ZONE * > m_DRCZones
Definition: board.h:1156
PAD * GetPad(const VECTOR2I &aPosition, LSET aLayerMask) const
Find a pad aPosition on aLayer.
Definition: board.cpp:1518
BOARD()
Definition: board.cpp:69
void UpdateRatsnestExclusions()
Update the visibility flags on the current unconnected ratsnest lines.
Definition: board.cpp:239
wxString ConvertKIIDsToCrossReferences(const wxString &aSource) const
Definition: board.cpp:1101
std::vector< PCB_MARKER * > ResolveDRCExclusions()
Rebuild DRC markers from the serialized data in BOARD_DESIGN_SETTINGS.
Definition: board.cpp:266
void SynchronizeProperties()
Copy the current project's text variables into the boards property cache.
Definition: board.cpp:1450
void RemoveListener(BOARD_LISTENER *aListener)
Remove the specified listener.
Definition: board.cpp:1972
void DeleteMARKERs()
Delete all MARKERS from the board.
Definition: board.cpp:891
void Remove(BOARD_ITEM *aBoardItem, REMOVE_MODE aMode=REMOVE_MODE::NORMAL) override
Removes an item from the container.
Definition: board.cpp:794
GROUPS m_groups
Definition: board.h:1187
MARKERS m_markers
Definition: board.h:1183
std::unordered_map< PTR_PTR_LAYER_CACHE_KEY, bool > m_IntersectsAreaCache
Definition: board.h:1149
void HighLightON(bool aValue=true)
Enable or disable net highlighting.
Definition: board.cpp:2024
TRACKS m_tracks
Definition: board.h:1186
std::mutex m_CachesMutex
Definition: board.h:1145
void OnItemsChanged(std::vector< BOARD_ITEM * > &aItems)
Notify the board and its listeners that an item on the board has been modified in some way.
Definition: board.cpp:1996
std::shared_ptr< CONNECTIVITY_DATA > GetConnectivity() const
Return a list of missing connections between components/tracks.
Definition: board.h:424
VECTOR2I GetPosition() const override
Definition: board.cpp:314
void BuildConnectivity(PROGRESS_REPORTER *aReporter=nullptr)
Build or rebuild the board connectivity database for the board, especially the list of connected item...
Definition: board.cpp:155
void CacheTriangulation(PROGRESS_REPORTER *aReporter=nullptr, const std::vector< ZONE * > &aZones={})
Definition: board.cpp:635
void SetVisibleElements(const GAL_SET &aMask)
A proxy function that calls the correspondent function in m_BoardSettings.
Definition: board.cpp:539
coord_type GetHeight() const
Definition: box2.h:188
coord_type GetY() const
Definition: box2.h:181
coord_type GetWidth() const
Definition: box2.h:187
coord_type GetX() const
Definition: box2.h:180
BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
Definition: box2.h:588
CN_EDGE represents a point-to-point connection, whether realized or unrealized (ie: tracks etc.
void SetVisible(bool aVisible)
std::shared_ptr< CN_ANCHOR > GetTargetNode() const
std::shared_ptr< CN_ANCHOR > GetSourceNode() const
static DELETED_BOARD_ITEM * GetInstance()
Definition: board_item.h:356
The base class for create windows for drawing purpose.
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:85
virtual VECTOR2I GetPosition() const
Definition: eda_item.h:249
void SetFlags(EDA_ITEM_FLAGS aMask)
Definition: eda_item.h:142
const KIID m_Uuid
Definition: eda_item.h:492
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:97
virtual void SetParent(EDA_ITEM *aParent)
Definition: eda_item.h:100
void ClearEditFlags()
Definition: eda_item.h:160
EDA_ITEM_FLAGS GetFlags() const
Definition: eda_item.h:144
int Compare(const EDA_SHAPE *aOther) const
Definition: eda_shape.cpp:1451
A specialization of ZONE for use in footprints.
Definition: zone.h:897
Helper for storing and iterating over GAL_LAYER_IDs.
Definition: layer_ids.h:296
GAL_SET & set()
Definition: layer_ids.h:311
static const std::vector< KICAD_T > BoardLevelItems
A scan list for all primary board items, omitting items which are subordinate to a FOOTPRINT,...
Definition: collectors.h:235
static const std::vector< KICAD_T > Tracks
A scan list for only TRACKs and ARCs.
Definition: collectors.h:255
void Clear()
Definition: board.h:214
std::set< int > m_netCodes
Definition: board.h:211
bool m_highLightOn
Definition: board.h:212
Definition: kiid.h:47
LSET is a set of PCB_LAYER_IDs.
Definition: layer_ids.h:530
static LSET AllLayersMask()
Definition: lset.cpp:808
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:773
void SetExcluded(bool aExcluded)
Definition: marker_base.h:98
void SetParent(JSON_SETTINGS *aParent, bool aLoadFromFile=true)
static const char Default[]
the name of the default NETCLASS
Definition: netclass.h:49
Handle the data for a net.
Definition: netinfo.h:66
void SetNetCode(int aNetCode)
Definition: netinfo.h:114
int GetNetCode() const
Definition: netinfo.h:113
static const int UNCONNECTED
Constant that forces initialization of a netinfo item to the NETINFO_ITEM ORPHANED (typically -1) whe...
Definition: netinfo.h:373
static const int ORPHANED
NETINFO_ITEM meaning that there was no net assigned for an item, as there was no board storing net li...
Definition: netinfo.h:377
static NETINFO_ITEM * OrphanedItem()
Wrapper class, so you can iterate through NETINFO_ITEM*s, not std::pair<int/wxString,...
Definition: netinfo.h:381
unsigned GetNetCount() const
Definition: netinfo.h:347
void RemoveNet(NETINFO_ITEM *aNet)
Remove a net from the net list.
NETINFO_ITEM * GetNetItem(int aNetCode) const
void AppendNet(NETINFO_ITEM *aNewElement)
Add aNewElement to the end of the net list.
Definition: pad.h:58
VECTOR2I GetPosition() const override
Definition: pad.h:196
Describe the page size and margins of a paper page on which to eventually print or plot.
Definition: page_info.h:54
A set of BOARD_ITEMs (i.e., without duplicates).
Definition: pcb_group.h:51
bool RemoveItem(BOARD_ITEM *aItem)
Remove item from group.
Definition: pcb_group.cpp:52
static PCB_MARKER * Deserialize(const wxString &data)
Definition: pcb_marker.cpp:131
void TransformShapeWithClearanceToPolygon(SHAPE_POLY_SET &aCornerBuffer, PCB_LAYER_ID aLayer, int aClearanceValue, int aError, ERROR_LOC aErrorLoc, bool ignoreLineWidth=false) const override
Convert the shape to a closed polygon.
Definition: pcb_shape.cpp:383
void TransformTextShapeWithClearanceToPolygon(SHAPE_POLY_SET &aCornerBuffer, PCB_LAYER_ID aLayer, int aClearanceValue, int aError, ERROR_LOC aErrorLoc) const
Function TransformTextShapeWithClearanceToPolygon Convert the text to a polygonSet describing the act...
const VECTOR2I & GetEndPoint(ENDPOINT_T aEndPoint) const
Return the selected endpoint (start or end)
Definition: pcb_track.h:120
bool m_Printing
wxWidgets on MSW tends to crash if you spool up more than one print job at a time.
Definition: pgm_base.h:298
A holder to handle information on schematic or board items.
void PushItem(const ITEM_PICKER &aItem)
Push aItem to the top of the list.
A progress reporter interface for use in multi-threaded environments.
virtual bool IsCancelled() const =0
virtual bool KeepRefreshing(bool aWait=false)=0
Update the UI (if any).
virtual void Report(const wxString &aMessage)=0
Display aMessage in the progress bar dialog.
virtual void AdvanceProgress()=0
Increment the progress bar length (inside the current virtual zone).
The backing store for a PROJECT, in JSON format.
Definition: project_file.h:65
LSET m_VisibleLayers
Board settings.
GAL_SET m_VisibleItems
The GAL layers (aka items) that are turned on for viewing (.
Container for project specific data.
Definition: project.h:63
virtual PROJECT_LOCAL_SETTINGS & GetLocalSettings() const
Definition: project.h:154
virtual PROJECT_FILE & GetProjectFile() const
Definition: project.h:148
virtual std::map< wxString, wxString > & GetTextVars() const
Definition: project.cpp:81
virtual bool IsNullProject() const
Check if this project is a null project (i.e.
Definition: project.cpp:137
Definition: seg.h:42
VECTOR2I A
Definition: seg.h:49
VECTOR2I B
Definition: seg.h:50
int Length() const
Return the length (this).
Definition: seg.h:351
int Size() const
Returns the number of selected parts.
Definition: selection.h:113
Represent a set of closed polygons.
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Add a new vertex to the contour indexed by aOutline and aHole (defaults to the outline of the last po...
void Simplify(POLYGON_MODE aFastMode)
int NewOutline()
Creates a new hole in a given outline.
ZONE_SETTINGS handles zones parameters.
Definition: zone_settings.h:70
Handle a list of polygons defining a copper zone.
Definition: zone.h:57
void SetMinThickness(int aMinThickness)
Definition: zone.h:245
virtual void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
Definition: zone.cpp:251
SHAPE_POLY_SET * Outline()
Definition: zone.h:305
void SetHatchStyle(ZONE_BORDER_DISPLAY_STYLE aStyle)
Definition: zone.h:575
void SetLayerSet(LSET aLayerSet) override
Definition: zone.cpp:257
bool AppendCorner(VECTOR2I aPosition, int aHoleIdx, bool aAllowDuplication=false)
Add a new corner to the zone outline (to the main outline or a hole)
Definition: zone.cpp:696
bool BuildBoardPolygonOutlines(BOARD *aBoard, SHAPE_POLY_SET &aOutlines, int aErrorMax, int aChainingEpsilon, OUTLINE_ERROR_HANDLER *aErrorHandler)
Extracts the board outlines and build a closed polygon from lines, arcs and circle items on edge cut ...
const std::function< void(const wxString &msg, BOARD_ITEM *itemA, BOARD_ITEM *itemB, const VECTOR2I &pt)> OUTLINE_ERROR_HANDLER
PGM_BASE * PgmOrNull()
similar to PGM_BASE& Pgm(), but return a reference that can be nullptr when running a shared lib from...
Definition: cvpcb.cpp:125
#define _(s)
INSPECT_RESULT
Definition: eda_item.h:42
const INSPECTOR_FUNC & INSPECTOR
Definition: eda_item.h:78
std::function< INSPECT_RESULT(EDA_ITEM *aItem, void *aTestData) > INSPECTOR_FUNC
Used to inspect and possibly collect the (search) results of iterating over a list or tree of KICAD_T...
Definition: eda_item.h:75
#define STRUCT_DELETED
flag indication structures to be erased
@ ERROR_INSIDE
KIID niluuid(0)
bool IsBackLayer(PCB_LAYER_ID aLayerId)
Layer classification: check if it's a back layer.
Definition: layer_ids.h:920
bool IsCopperLayer(int aLayerId)
Tests whether a layer is a copper layer.
Definition: layer_ids.h:823
GAL_LAYER_ID
GAL layers are "virtual" layers, i.e.
Definition: layer_ids.h:190
@ LAYER_MOD_TEXT_INVISIBLE
text marked as invisible
Definition: layer_ids.h:200
@ GAL_LAYER_ID_START
Definition: layer_ids.h:191
@ GAL_LAYER_ID_BITMASK_END
This is the end of the layers used for visibility bit masks in legacy board files.
Definition: layer_ids.h:226
@ LAYER_RATSNEST
Definition: layer_ids.h:204
@ LAYER_MOD_FR
show footprints on front
Definition: layer_ids.h:208
@ LAYER_MOD_BK
show footprints on back
Definition: layer_ids.h:209
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:59
@ Edge_Cuts
Definition: layer_ids.h:113
@ B_Mask
Definition: layer_ids.h:106
@ B_Cu
Definition: layer_ids.h:95
@ F_Mask
Definition: layer_ids.h:107
@ UNDEFINED_LAYER
Definition: layer_ids.h:60
@ Rescue
Definition: layer_ids.h:133
@ PCB_LAYER_ID_COUNT
Definition: layer_ids.h:137
@ F_Cu
Definition: layer_ids.h:64
#define GAL_LAYER_INDEX(x)
Use this macro to convert a GAL layer to a 0-indexed offset from LAYER_VIAS.
Definition: layer_ids.h:264
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:926
void delete_matching(_Container &__c, _Value __value)
Covers for the horrifically named std::remove and std::remove_if (neither of which remove anything).
Definition: kicad_algo.h:164
bool contains(const _Container &__container, _Value __value)
Returns true if the container contains the given value.
Definition: kicad_algo.h:99
ENDPOINT_T
Definition: pcb_track.h:54
see class PGM_BASE
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
Class that computes missing connections on a PCB.
@ RPT_SEVERITY_EXCLUSION
bool operator()(const BOARD_ITEM *aFirst, const BOARD_ITEM *aSecond) const
Definition: board.cpp:2159
bool operator()(const BOARD_ITEM *aFirst, const BOARD_ITEM *aSecond) const
Definition: board.cpp:2138
constexpr int mmToIU(double mm) const
Definition: base_units.h:89
Container to hold information pertinent to a layer of a BOARD.
Definition: board.h:156
static LAYER_T ParseType(const char *aType)
Convert a string to a LAYER_T.
Definition: board.cpp:473
LAYER_T m_type
The type of the layer.
Definition: board.h:184
static const char * ShowType(LAYER_T aType)
Convert a LAYER_T enum to a string representation of the layer type.
Definition: board.cpp:460
wxString m_name
The canonical name of the layer.
Definition: board.h:182
wxString m_userName
The user defined name of the layer.
Definition: board.h:183
constexpr int delta
thread_pool & GetKiCadThreadPool()
Get a reference to the current thread pool.
Definition: thread_pool.cpp:32
static thread_pool * tp
Definition: thread_pool.cpp:30
BS::thread_pool thread_pool
Definition: thread_pool.h:30
double EuclideanNorm(const VECTOR2I &vector)
Definition: trigo.h:129
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition: typeinfo.h:78
@ PCB_FP_DIM_ALIGNED_T
class PCB_DIM_ALIGNED, a linear dimension (graphic item)
Definition: typeinfo.h:95
@ PCB_T
Definition: typeinfo.h:82
@ PCB_SHAPE_T
class PCB_SHAPE, a segment not on copper layers
Definition: typeinfo.h:88
@ PCB_DIM_ORTHOGONAL_T
class PCB_DIM_ORTHOGONAL, a linear dimension constrained to x/y
Definition: typeinfo.h:110
@ PCB_FP_SHAPE_T
class FP_SHAPE, a footprint edge
Definition: typeinfo.h:94
@ PCB_DIM_LEADER_T
class PCB_DIM_LEADER, a leader dimension (graphic item)
Definition: typeinfo.h:107
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:102
@ PCB_FP_TEXTBOX_T
class FP_TEXTBOX, wrapped text in a footprint
Definition: typeinfo.h:93
@ PCB_DIM_CENTER_T
class PCB_DIM_CENTER, a center point marking (graphic item)
Definition: typeinfo.h:108
@ PCB_GROUP_T
class PCB_GROUP, a set of BOARD_ITEMs
Definition: typeinfo.h:115
@ PCB_TEXTBOX_T
class PCB_TEXTBOX, wrapped text on a layer
Definition: typeinfo.h:91
@ PCB_ZONE_T
class ZONE, a copper pour area
Definition: typeinfo.h:112
@ PCB_TEXT_T
class PCB_TEXT, text on a layer
Definition: typeinfo.h:90
@ PCB_FP_DIM_CENTER_T
class PCB_DIM_CENTER, a center point marking (graphic item)
Definition: typeinfo.h:97
@ PCB_MARKER_T
class PCB_MARKER, a marker used to show something
Definition: typeinfo.h:104
@ PCB_TARGET_T
class PCB_TARGET, a target (graphic item)
Definition: typeinfo.h:111
@ PCB_FP_DIM_ORTHOGONAL_T
class PCB_DIM_ORTHOGONAL, a linear dimension constrained to x/y
Definition: typeinfo.h:99
@ PCB_FP_DIM_LEADER_T
class PCB_DIM_LEADER, a leader dimension (graphic item)
Definition: typeinfo.h:96
@ PCB_FOOTPRINT_T
class FOOTPRINT, a footprint
Definition: typeinfo.h:86
@ PCB_DIM_ALIGNED_T
class PCB_DIM_ALIGNED, a linear dimension (graphic item)
Definition: typeinfo.h:106
@ PCB_FP_ZONE_T
class ZONE, managed by a footprint
Definition: typeinfo.h:100
@ PCB_BITMAP_T
class PCB_BITMAP, bitmap on a layer
Definition: typeinfo.h:89
@ PCB_FP_DIM_RADIAL_T
class PCB_DIM_RADIAL, a radius or diameter dimension
Definition: typeinfo.h:98
@ PCB_PAD_T
class PAD, a pad in a footprint
Definition: typeinfo.h:87
@ PCB_FP_TEXT_T
class FP_TEXT, text in a footprint
Definition: typeinfo.h:92
@ PCB_ARC_T
class PCB_ARC, an arc track segment on a copper layer
Definition: typeinfo.h:103
@ PCB_NETINFO_T
class NETINFO_ITEM, a description of a net
Definition: typeinfo.h:114
@ PCB_TRACE_T
class PCB_TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:101
@ PCB_DIM_RADIAL_T
class PCB_DIM_RADIAL, a radius or diameter dimension
Definition: typeinfo.h:109
VECTOR2< int > VECTOR2I
Definition: vector2d.h:618
ZONE_BORDER_DISPLAY_STYLE
Zone border styles.
Definition: zone_settings.h:49