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-2023 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 // Untangle group parents before doing any deleting
124 for( PCB_GROUP* group : m_groups )
125 {
126 for( BOARD_ITEM* item : group->GetItems() )
127 item->SetParentGroup( nullptr );
128 }
129
130 // Clean up the owned elements
132
133 for( ZONE* zone : m_zones )
134 delete zone;
135
136 m_zones.clear();
137
138 delete m_SolderMask;
139
140 for( FOOTPRINT* footprint : m_footprints )
141 delete footprint;
142
143 m_footprints.clear();
144
145 for( PCB_TRACK* t : m_tracks )
146 delete t;
147
148 m_tracks.clear();
149
150 for( BOARD_ITEM* d : m_drawings )
151 delete d;
152
153 m_drawings.clear();
154
155 for( PCB_GROUP* g : m_groups )
156 delete g;
157
158 m_groups.clear();
159}
160
161
163{
164 if( !GetConnectivity()->Build( this, aReporter ) )
165 return false;
166
168 return true;
169}
170
171
172void BOARD::SetProject( PROJECT* aProject, bool aReferenceOnly )
173{
174 if( m_project )
175 ClearProject();
176
177 m_project = aProject;
178
179 if( aProject && !aReferenceOnly )
180 {
181 PROJECT_FILE& project = aProject->GetProjectFile();
182
183 // Link the design settings object to the project file
184 project.m_BoardSettings = &GetDesignSettings();
185
186 // Set parent, which also will load the values from JSON stored in the project if we don't
187 // have legacy design settings loaded already
188 project.m_BoardSettings->SetParent( &project, !m_LegacyDesignSettingsLoaded );
189
190 // The DesignSettings' netclasses pointer will be pointing to its internal netclasses
191 // list at this point. If we loaded anything into it from a legacy board file then we
192 // want to transfer it over to the project netclasses list.
194 {
195 std::shared_ptr<NET_SETTINGS> legacySettings = GetDesignSettings().m_NetSettings;
196 std::shared_ptr<NET_SETTINGS>& projectSettings = project.NetSettings();
197
198 projectSettings->m_DefaultNetClass = legacySettings->m_DefaultNetClass;
199 projectSettings->m_NetClasses = legacySettings->m_NetClasses;
200 projectSettings->m_NetClassPatternAssignments =
201 std::move( legacySettings->m_NetClassPatternAssignments );
202 }
203
204 // Now update the DesignSettings' netclass pointer to point into the project.
205 GetDesignSettings().m_NetSettings = project.NetSettings();
206 }
207}
208
209
211{
212 if( !m_project )
213 return;
214
216
217 // Owned by the BOARD
218 if( project.m_BoardSettings )
219 {
220 project.ReleaseNestedSettings( project.m_BoardSettings );
221 project.m_BoardSettings = nullptr;
222 }
223
225 GetDesignSettings().SetParent( nullptr );
226 m_project = nullptr;
227}
228
229
231{
232 m_timeStamp++;
233
234 if( !m_IntersectsAreaCache.empty()
235 || !m_EnclosedByAreaCache.empty()
239 || !m_LayerExpressionCache.empty()
240 || !m_ZoneBBoxCache.empty() )
241 {
242 std::unique_lock<std::mutex> cacheLock( m_CachesMutex );
243
244 m_IntersectsAreaCache.clear();
245 m_EnclosedByAreaCache.clear();
250
251 m_ZoneBBoxCache.clear();
252
253 // These are always regenerated before use, but still probably safer to clear them
254 // while we're here.
257 m_DRCZones.clear();
258 m_DRCCopperZones.clear();
260 m_CopperItemRTreeCache = std::make_unique<DRC_RTREE>();
261 }
262 else if( !m_CopperItemRTreeCache )
263 {
264 std::unique_lock<std::mutex> cacheLock( m_CachesMutex );
265 m_CopperItemRTreeCache = std::make_unique<DRC_RTREE>();
266 }
267}
268
269
271{
272 std::set<std::pair<KIID, KIID>> m_ratsnestExclusions;
273
274 for( PCB_MARKER* marker : GetBoard()->Markers() )
275 {
276 if( marker->GetMarkerType() == MARKER_BASE::MARKER_RATSNEST && marker->IsExcluded() )
277 {
278 const std::shared_ptr<RC_ITEM>& rcItem = marker->GetRCItem();
279 m_ratsnestExclusions.emplace( rcItem->GetMainItemID(), rcItem->GetAuxItemID() );
280 m_ratsnestExclusions.emplace( rcItem->GetAuxItemID(), rcItem->GetMainItemID() );
281 }
282 }
283
284 GetConnectivity()->RunOnUnconnectedEdges(
285 [&]( CN_EDGE& aEdge )
286 {
287 if( aEdge.GetSourceNode() && aEdge.GetTargetNode() )
288 {
289 std::pair<KIID, KIID> ids = { aEdge.GetSourceNode()->Parent()->m_Uuid,
290 aEdge.GetTargetNode()->Parent()->m_Uuid };
291
292 aEdge.SetVisible( m_ratsnestExclusions.count( ids ) == 0 );
293 }
294
295 return true;
296 } );
297}
298
299
300std::vector<PCB_MARKER*> BOARD::ResolveDRCExclusions()
301{
302 for( PCB_MARKER* marker : GetBoard()->Markers() )
303 {
304 auto i = m_designSettings->m_DrcExclusions.find( marker->Serialize() );
305
306 if( i != m_designSettings->m_DrcExclusions.end() )
307 {
308 marker->SetExcluded( true );
309 m_designSettings->m_DrcExclusions.erase( i );
310 }
311 }
312
313 std::vector<PCB_MARKER*> newMarkers;
314
315 for( const wxString& exclusionData : m_designSettings->m_DrcExclusions )
316 {
317 PCB_MARKER* marker = PCB_MARKER::Deserialize( exclusionData );
318
319 if( marker )
320 {
321 marker->SetExcluded( true );
322 newMarkers.push_back( marker );
323 }
324 }
325
326 m_designSettings->m_DrcExclusions.clear();
327
328 return newMarkers;
329}
330
331
332bool BOARD::ResolveTextVar( wxString* token, int aDepth ) const
333{
334 if( token->Contains( ':' ) )
335 {
336 wxString remainder;
337 wxString ref = token->BeforeFirst( ':', &remainder );
338 BOARD_ITEM* refItem = GetItem( KIID( ref ) );
339
340 if( refItem && refItem->Type() == PCB_FOOTPRINT_T )
341 {
342 FOOTPRINT* refFP = static_cast<FOOTPRINT*>( refItem );
343
344 if( refFP->ResolveTextVar( &remainder, aDepth + 1 ) )
345 {
346 *token = remainder;
347 return true;
348 }
349 }
350 }
351
352 wxString var = *token;
353
354 if( GetTitleBlock().TextVarResolver( token, m_project ) )
355 {
356 return true;
357 }
358 else if( m_properties.count( var ) )
359 {
360 *token = m_properties.at( var );
361 return true;
362 }
363
364 if( GetProject() && GetProject()->TextVarResolver( token ) )
365 return true;
366
367 return false;
368}
369
370
372{
373 return ZeroOffset;
374}
375
376
377void BOARD::SetPosition( const VECTOR2I& aPos )
378{
379 wxLogWarning( wxT( "This should not be called on the BOARD object") );
380}
381
382
383void BOARD::Move( const VECTOR2I& aMoveVector ) // overload
384{
385 INSPECTOR_FUNC inspector =
386 [&] ( EDA_ITEM* item, void* testData )
387 {
388 BOARD_ITEM* brdItem = static_cast<BOARD_ITEM*>( item );
389
390 // aMoveVector was snapshotted, don't need "data".
391 // Only move the top level group
392 if( brdItem->GetParentGroup() == nullptr )
393 brdItem->Move( aMoveVector );
394
396 };
397
398 Visit( inspector, nullptr, GENERAL_COLLECTOR::BoardLevelItems );
399}
400
401
402TRACKS BOARD::TracksInNet( int aNetCode )
403{
404 TRACKS ret;
405
406 INSPECTOR_FUNC inspector = [aNetCode, &ret]( EDA_ITEM* item, void* testData )
407 {
408 PCB_TRACK* t = static_cast<PCB_TRACK*>( item );
409
410 if( t->GetNetCode() == aNetCode )
411 ret.push_back( t );
412
414 };
415
416 // visit this BOARD's PCB_TRACKs and PCB_VIAs with above TRACK INSPECTOR which
417 // appends all in aNetCode to ret.
418 Visit( inspector, nullptr, GENERAL_COLLECTOR::Tracks );
419
420 return ret;
421}
422
423
424bool BOARD::SetLayerDescr( PCB_LAYER_ID aIndex, const LAYER& aLayer )
425{
426 if( unsigned( aIndex ) < arrayDim( m_layers ) )
427 {
428 m_layers[ aIndex ] = aLayer;
429 return true;
430 }
431
432 return false;
433}
434
435
436const PCB_LAYER_ID BOARD::GetLayerID( const wxString& aLayerName ) const
437{
438 // Check the BOARD physical layer names.
439 for( int layer = 0; layer < PCB_LAYER_ID_COUNT; ++layer )
440 {
441 if ( m_layers[ layer ].m_name == aLayerName || m_layers[ layer ].m_userName == aLayerName )
442 return ToLAYER_ID( layer );
443 }
444
445 // Otherwise fall back to the system standard layer names for virtual layers.
446 for( int layer = 0; layer < PCB_LAYER_ID_COUNT; ++layer )
447 {
448 if( GetStandardLayerName( ToLAYER_ID( layer ) ) == aLayerName )
449 return ToLAYER_ID( layer );
450 }
451
452 return UNDEFINED_LAYER;
453}
454
455
456const wxString BOARD::GetLayerName( PCB_LAYER_ID aLayer ) const
457{
458 // All layer names are stored in the BOARD.
459 if( IsLayerEnabled( aLayer ) )
460 {
461 // Standard names were set in BOARD::BOARD() but they may be over-ridden by
462 // BOARD::SetLayerName(). For copper layers, return the user defined layer name,
463 // if it was set. Otherwise return the Standard English layer name.
464 if( !m_layers[aLayer].m_userName.IsEmpty() )
465 return m_layers[aLayer].m_userName;
466 }
467
468 return GetStandardLayerName( aLayer );
469}
470
471
472bool BOARD::SetLayerName( PCB_LAYER_ID aLayer, const wxString& aLayerName )
473{
474 wxCHECK( !aLayerName.IsEmpty(), false );
475
476 // no quote chars in the name allowed
477 if( aLayerName.Find( wxChar( '"' ) ) != wxNOT_FOUND )
478 return false;
479
480 if( IsLayerEnabled( aLayer ) )
481 {
482 m_layers[aLayer].m_userName = aLayerName;
483 return true;
484 }
485
486 return false;
487}
488
489
491{
492 if( !IsCopperLayer( aLayer ) )
493 return LT_SIGNAL;
494
495 if( IsLayerEnabled( aLayer ) )
496 return m_layers[aLayer].m_type;
497
498 return LT_SIGNAL;
499}
500
501
502bool BOARD::SetLayerType( PCB_LAYER_ID aLayer, LAYER_T aLayerType )
503{
504 if( !IsCopperLayer( aLayer ) )
505 return false;
506
507 if( IsLayerEnabled( aLayer ) )
508 {
509 m_layers[aLayer].m_type = aLayerType;
510 return true;
511 }
512
513 return false;
514}
515
516
517const char* LAYER::ShowType( LAYER_T aType )
518{
519 switch( aType )
520 {
521 default:
522 case LT_SIGNAL: return "signal";
523 case LT_POWER: return "power";
524 case LT_MIXED: return "mixed";
525 case LT_JUMPER: return "jumper";
526 }
527}
528
529
530LAYER_T LAYER::ParseType( const char* aType )
531{
532 if( strcmp( aType, "signal" ) == 0 )
533 return LT_SIGNAL;
534 else if( strcmp( aType, "power" ) == 0 )
535 return LT_POWER;
536 else if( strcmp( aType, "mixed" ) == 0 )
537 return LT_MIXED;
538 else if( strcmp( aType, "jumper" ) == 0 )
539 return LT_JUMPER;
540 else
541 return LT_UNDEFINED;
542}
543
544
546{
548}
549
550
552{
554}
555
556
557int BOARD::LayerDepth( PCB_LAYER_ID aStartLayer, PCB_LAYER_ID aEndLayer ) const
558{
559 if( aStartLayer > aEndLayer )
560 std::swap( aStartLayer, aEndLayer );
561
562 if( aEndLayer == B_Cu )
563 aEndLayer = ToLAYER_ID( F_Cu + GetCopperLayerCount() - 1 );
564
565 return aEndLayer - aStartLayer;
566}
567
568
570{
572}
573
574
576{
577 // If there is no project, assume layer is visible always
578 return GetDesignSettings().IsLayerEnabled( aLayer )
580}
581
582
584{
586}
587
588
590{
591 GetDesignSettings().SetEnabledLayers( aLayerSet );
592}
593
594
596{
597 return GetDesignSettings().IsLayerEnabled( aLayer );
598}
599
600
602{
603 if( m_project )
605}
606
607
609{
610 // Call SetElementVisibility for each item
611 // to ensure specific calculations that can be needed by some items,
612 // just changing the visibility flags could be not sufficient.
613 for( size_t i = 0; i < aSet.size(); i++ )
614 SetElementVisibility( GAL_LAYER_ID_START + static_cast<int>( i ), aSet[i] );
615}
616
617
619{
620 SetVisibleLayers( LSET().set() );
621
622 // Call SetElementVisibility for each item,
623 // to ensure specific calculations that can be needed by some items
625 SetElementVisibility( ii, true );
626}
627
628
630{
632}
633
634
636{
638}
639
640
641void BOARD::SetElementVisibility( GAL_LAYER_ID aLayer, bool isEnabled )
642{
643 if( m_project )
645
646 switch( aLayer )
647 {
648 case LAYER_RATSNEST:
649 {
650 // because we have a tool to show/hide ratsnest relative to a pad or a footprint
651 // so the hide/show option is a per item selection
652
653 for( PCB_TRACK* track : Tracks() )
654 track->SetLocalRatsnestVisible( isEnabled );
655
656 for( FOOTPRINT* footprint : Footprints() )
657 {
658 for( PAD* pad : footprint->Pads() )
659 pad->SetLocalRatsnestVisible( isEnabled );
660 }
661
662 for( ZONE* zone : Zones() )
663 zone->SetLocalRatsnestVisible( isEnabled );
664
665 break;
666 }
667
668 default:
669 ;
670 }
671}
672
673
675{
676 switch( aLayer )
677 {
678 case F_Cu: return IsElementVisible( LAYER_MOD_FR );
679 case B_Cu: return IsElementVisible( LAYER_MOD_BK );
680 default: wxFAIL_MSG( wxT( "BOARD::IsModuleLayerVisible(): bad layer" ) ); return true;
681 }
682}
683
684
685
687{
688 return *m_designSettings;
689}
690
691
693{
695}
696
697
698void BOARD::SetZoneSettings( const ZONE_SETTINGS& aSettings )
699{
701}
702
703
704void BOARD::CacheTriangulation( PROGRESS_REPORTER* aReporter, const std::vector<ZONE*>& aZones )
705{
706 std::vector<ZONE*> zones = aZones;
707
708 if( zones.empty() )
709 zones = m_zones;
710
711 if( zones.empty() )
712 return;
713
714 if( aReporter )
715 aReporter->Report( _( "Tessellating copper zones..." ) );
716
718 std::vector<std::future<size_t>> returns;
719
720 returns.reserve( zones.size() );
721
722 auto cache_zones = [aReporter]( ZONE* aZone ) -> size_t
723 {
724 if( aReporter && aReporter->IsCancelled() )
725 return 0;
726
727 aZone->CacheTriangulation();
728
729 if( aReporter )
730 aReporter->AdvanceProgress();
731
732 return 1;
733 };
734
735 for( ZONE* zone : zones )
736 returns.emplace_back( tp.submit( cache_zones, zone ) );
737
738 // Finalize the triangulation threads
739 for( const std::future<size_t>& ret : returns )
740 {
741 std::future_status status = ret.wait_for( std::chrono::milliseconds( 250 ) );
742
743 while( status != std::future_status::ready )
744 {
745 if( aReporter )
746 aReporter->KeepRefreshing();
747
748 status = ret.wait_for( std::chrono::milliseconds( 250 ) );
749 }
750 }
751}
752
753
754void BOARD::Add( BOARD_ITEM* aBoardItem, ADD_MODE aMode, bool aSkipConnectivity )
755{
756 if( aBoardItem == nullptr )
757 {
758 wxFAIL_MSG( wxT( "BOARD::Add() param error: aBoardItem nullptr" ) );
759 return;
760 }
761
762 switch( aBoardItem->Type() )
763 {
764 case PCB_NETINFO_T:
765 m_NetInfo.AppendNet( (NETINFO_ITEM*) aBoardItem );
766 break;
767
768 // this one uses a vector
769 case PCB_MARKER_T:
770 m_markers.push_back( (PCB_MARKER*) aBoardItem );
771 break;
772
773 // this one uses a vector
774 case PCB_GROUP_T:
775 m_groups.push_back( (PCB_GROUP*) aBoardItem );
776 break;
777
778 // this one uses a vector
779 case PCB_ZONE_T:
780 m_zones.push_back( (ZONE*) aBoardItem );
781 break;
782
783 case PCB_TRACE_T:
784 case PCB_VIA_T:
785 case PCB_ARC_T:
786
787 // N.B. This inserts a small memory leak as we lose the
788 if( !IsCopperLayer( aBoardItem->GetLayer() ) )
789 {
790 wxFAIL_MSG( wxT( "BOARD::Add() Cannot place Track on non-copper layer" ) );
791 return;
792 }
793
794 if( aMode == ADD_MODE::APPEND || aMode == ADD_MODE::BULK_APPEND )
795 m_tracks.push_back( static_cast<PCB_TRACK*>( aBoardItem ) );
796 else
797 m_tracks.push_front( static_cast<PCB_TRACK*>( aBoardItem ) );
798
799 break;
800
801 case PCB_FOOTPRINT_T:
802 if( aMode == ADD_MODE::APPEND || aMode == ADD_MODE::BULK_APPEND )
803 m_footprints.push_back( static_cast<FOOTPRINT*>( aBoardItem ) );
804 else
805 m_footprints.push_front( static_cast<FOOTPRINT*>( aBoardItem ) );
806
807 break;
808
810 case PCB_DIM_CENTER_T:
811 case PCB_DIM_RADIAL_T:
813 case PCB_DIM_LEADER_T:
814 case PCB_SHAPE_T:
815 case PCB_BITMAP_T:
816 case PCB_TEXT_T:
817 case PCB_TEXTBOX_T:
818 case PCB_TARGET_T:
819 if( aMode == ADD_MODE::APPEND || aMode == ADD_MODE::BULK_APPEND )
820 m_drawings.push_back( aBoardItem );
821 else
822 m_drawings.push_front( aBoardItem );
823
824 break;
825
826 // other types may use linked list
827 default:
828 {
829 wxString msg;
830 msg.Printf( wxT( "BOARD::Add() needs work: BOARD_ITEM type (%d) not handled" ),
831 aBoardItem->Type() );
832 wxFAIL_MSG( msg );
833 return;
834 }
835 break;
836 }
837
838 aBoardItem->SetParent( this );
839 aBoardItem->ClearEditFlags();
840
841 if( !aSkipConnectivity )
842 m_connectivity->Add( aBoardItem );
843
844 if( aMode != ADD_MODE::BULK_INSERT && aMode != ADD_MODE::BULK_APPEND )
845 {
847 }
848}
849
850
851void BOARD::FinalizeBulkAdd( std::vector<BOARD_ITEM*>& aNewItems )
852{
854}
855
856
857void BOARD::FinalizeBulkRemove( std::vector<BOARD_ITEM*>& aRemovedItems )
858{
860}
861
862
863void BOARD::Remove( BOARD_ITEM* aBoardItem, REMOVE_MODE aRemoveMode )
864{
865 // find these calls and fix them! Don't send me no stinking' nullptr.
866 wxASSERT( aBoardItem );
867
868 switch( aBoardItem->Type() )
869 {
870 case PCB_NETINFO_T:
871 {
872 NETINFO_ITEM* item = static_cast<NETINFO_ITEM*>( aBoardItem );
874
875 for( FOOTPRINT* fp : m_footprints )
876 {
877 for( PAD* pad : fp->Pads() )
878 {
879 if( pad->GetNet() == item )
880 pad->SetNet( unconnected );
881 }
882 }
883
884 for( ZONE* zone : m_zones )
885 {
886 if( zone->GetNet() == item )
887 zone->SetNet( unconnected );
888 }
889
890 for( PCB_TRACK* track : m_tracks )
891 {
892 if( track->GetNet() == item )
893 track->SetNet( unconnected );
894 }
895
896 m_NetInfo.RemoveNet( item );
897 break;
898 }
899
900 case PCB_MARKER_T:
901 alg::delete_matching( m_markers, aBoardItem );
902 break;
903
904 case PCB_GROUP_T:
905 alg::delete_matching( m_groups, aBoardItem );
906 break;
907
908 case PCB_ZONE_T:
909 alg::delete_matching( m_zones, aBoardItem );
910 break;
911
912 case PCB_FOOTPRINT_T:
913 alg::delete_matching( m_footprints, aBoardItem );
914 break;
915
916 case PCB_TRACE_T:
917 case PCB_ARC_T:
918 case PCB_VIA_T:
919 alg::delete_matching( m_tracks, aBoardItem );
920 break;
921
923 case PCB_DIM_CENTER_T:
924 case PCB_DIM_RADIAL_T:
926 case PCB_DIM_LEADER_T:
927 case PCB_SHAPE_T:
928 case PCB_BITMAP_T:
929 case PCB_TEXT_T:
930 case PCB_TEXTBOX_T:
931 case PCB_TARGET_T:
932 alg::delete_matching( m_drawings, aBoardItem );
933 break;
934
935 // other types may use linked list
936 default:
937 wxFAIL_MSG( wxT( "BOARD::Remove() needs more ::Type() support" ) );
938 }
939
940 aBoardItem->SetFlags( STRUCT_DELETED );
941
942 PCB_GROUP* parentGroup = aBoardItem->GetParentGroup();
943
944 if( parentGroup && !( parentGroup->GetFlags() & STRUCT_DELETED ) )
945 parentGroup->RemoveItem( aBoardItem );
946
947 m_connectivity->Remove( aBoardItem );
948
949 if( aRemoveMode != REMOVE_MODE::BULK )
951}
952
953
954wxString BOARD::GetItemDescription( UNITS_PROVIDER* aUnitsProvider ) const
955{
956 return wxString::Format( _( "PCB" ) );
957}
958
959
961{
962 // the vector does not know how to delete the PCB_MARKER, it holds pointers
963 for( PCB_MARKER* marker : m_markers )
964 delete marker;
965
966 m_markers.clear();
967}
968
969
970void BOARD::DeleteMARKERs( bool aWarningsAndErrors, bool aExclusions )
971{
972 // Deleting lots of items from a vector can be very slow. Copy remaining items instead.
973 MARKERS remaining;
974
975 for( PCB_MARKER* marker : m_markers )
976 {
977 if( ( marker->GetSeverity() == RPT_SEVERITY_EXCLUSION && aExclusions )
978 || ( marker->GetSeverity() != RPT_SEVERITY_EXCLUSION && aWarningsAndErrors ) )
979 {
980 delete marker;
981 }
982 else
983 {
984 remaining.push_back( marker );
985 }
986 }
987
988 m_markers = remaining;
989}
990
991
993{
994 for( FOOTPRINT* footprint : m_footprints )
995 delete footprint;
996
997 m_footprints.clear();
998}
999
1000
1001BOARD_ITEM* BOARD::GetItem( const KIID& aID ) const
1002{
1003 if( aID == niluuid )
1004 return nullptr;
1005
1006 for( PCB_TRACK* track : Tracks() )
1007 {
1008 if( track->m_Uuid == aID )
1009 return track;
1010 }
1011
1012 for( FOOTPRINT* footprint : Footprints() )
1013 {
1014 if( footprint->m_Uuid == aID )
1015 return footprint;
1016
1017 for( PAD* pad : footprint->Pads() )
1018 {
1019 if( pad->m_Uuid == aID )
1020 return pad;
1021 }
1022
1023 if( footprint->Reference().m_Uuid == aID )
1024 return &footprint->Reference();
1025
1026 if( footprint->Value().m_Uuid == aID )
1027 return &footprint->Value();
1028
1029 for( BOARD_ITEM* drawing : footprint->GraphicalItems() )
1030 {
1031 if( drawing->m_Uuid == aID )
1032 return drawing;
1033 }
1034
1035 for( BOARD_ITEM* zone : footprint->Zones() )
1036 {
1037 if( zone->m_Uuid == aID )
1038 return zone;
1039 }
1040
1041 for( PCB_GROUP* group : footprint->Groups() )
1042 {
1043 if( group->m_Uuid == aID )
1044 return group;
1045 }
1046 }
1047
1048 for( ZONE* zone : Zones() )
1049 {
1050 if( zone->m_Uuid == aID )
1051 return zone;
1052 }
1053
1054 for( BOARD_ITEM* drawing : Drawings() )
1055 {
1056 if( drawing->m_Uuid == aID )
1057 return drawing;
1058 }
1059
1060 for( PCB_MARKER* marker : m_markers )
1061 {
1062 if( marker->m_Uuid == aID )
1063 return marker;
1064 }
1065
1066 for( PCB_GROUP* group : m_groups )
1067 {
1068 if( group->m_Uuid == aID )
1069 return group;
1070 }
1071
1072 if( m_Uuid == aID )
1073 return const_cast<BOARD*>( this );
1074
1075 // Not found; weak reference has been deleted.
1077}
1078
1079
1080void BOARD::FillItemMap( std::map<KIID, EDA_ITEM*>& aMap )
1081{
1082 // the board itself
1083 aMap[ m_Uuid ] = this;
1084
1085 for( PCB_TRACK* track : Tracks() )
1086 aMap[ track->m_Uuid ] = track;
1087
1088 for( FOOTPRINT* footprint : Footprints() )
1089 {
1090 aMap[ footprint->m_Uuid ] = footprint;
1091
1092 for( PAD* pad : footprint->Pads() )
1093 aMap[ pad->m_Uuid ] = pad;
1094
1095 aMap[ footprint->Reference().m_Uuid ] = &footprint->Reference();
1096 aMap[ footprint->Value().m_Uuid ] = &footprint->Value();
1097
1098 for( BOARD_ITEM* drawing : footprint->GraphicalItems() )
1099 aMap[ drawing->m_Uuid ] = drawing;
1100 }
1101
1102 for( ZONE* zone : Zones() )
1103 aMap[ zone->m_Uuid ] = zone;
1104
1105 for( BOARD_ITEM* drawing : Drawings() )
1106 aMap[ drawing->m_Uuid ] = drawing;
1107
1108 for( PCB_MARKER* marker : m_markers )
1109 aMap[ marker->m_Uuid ] = marker;
1110
1111 for( PCB_GROUP* group : m_groups )
1112 aMap[ group->m_Uuid ] = group;
1113}
1114
1115
1116wxString BOARD::ConvertCrossReferencesToKIIDs( const wxString& aSource ) const
1117{
1118 wxString newbuf;
1119 size_t sourceLen = aSource.length();
1120
1121 for( size_t i = 0; i < sourceLen; ++i )
1122 {
1123 if( aSource[i] == '$' && i + 1 < sourceLen && aSource[i+1] == '{' )
1124 {
1125 wxString token;
1126 bool isCrossRef = false;
1127
1128 for( i = i + 2; i < sourceLen; ++i )
1129 {
1130 if( aSource[i] == '}' )
1131 break;
1132
1133 if( aSource[i] == ':' )
1134 isCrossRef = true;
1135
1136 token.append( aSource[i] );
1137 }
1138
1139 if( isCrossRef )
1140 {
1141 wxString remainder;
1142 wxString ref = token.BeforeFirst( ':', &remainder );
1143
1144 for( const FOOTPRINT* footprint : Footprints() )
1145 {
1146 if( footprint->GetReference().CmpNoCase( ref ) == 0 )
1147 {
1148 wxString test( remainder );
1149
1150 if( footprint->ResolveTextVar( &test ) )
1151 token = footprint->m_Uuid.AsString() + wxT( ":" ) + remainder;
1152
1153 break;
1154 }
1155 }
1156 }
1157
1158 newbuf.append( wxT( "${" ) + token + wxT( "}" ) );
1159 }
1160 else
1161 {
1162 newbuf.append( aSource[i] );
1163 }
1164 }
1165
1166 return newbuf;
1167}
1168
1169
1170wxString BOARD::ConvertKIIDsToCrossReferences( const wxString& aSource ) const
1171{
1172 wxString newbuf;
1173 size_t sourceLen = aSource.length();
1174
1175 for( size_t i = 0; i < sourceLen; ++i )
1176 {
1177 if( aSource[i] == '$' && i + 1 < sourceLen && aSource[i+1] == '{' )
1178 {
1179 wxString token;
1180 bool isCrossRef = false;
1181
1182 for( i = i + 2; i < sourceLen; ++i )
1183 {
1184 if( aSource[i] == '}' )
1185 break;
1186
1187 if( aSource[i] == ':' )
1188 isCrossRef = true;
1189
1190 token.append( aSource[i] );
1191 }
1192
1193 if( isCrossRef )
1194 {
1195 wxString remainder;
1196 wxString ref = token.BeforeFirst( ':', &remainder );
1197 BOARD_ITEM* refItem = GetItem( KIID( ref ) );
1198
1199 if( refItem && refItem->Type() == PCB_FOOTPRINT_T )
1200 {
1201 token = static_cast<FOOTPRINT*>( refItem )->GetReference() + wxT( ":" )
1202 + remainder;
1203 }
1204 }
1205
1206 newbuf.append( wxT( "${" ) + token + wxT( "}" ) );
1207 }
1208 else
1209 {
1210 newbuf.append( aSource[i] );
1211 }
1212 }
1213
1214 return newbuf;
1215}
1216
1217
1218unsigned BOARD::GetNodesCount( int aNet ) const
1219{
1220 unsigned retval = 0;
1221
1222 for( FOOTPRINT* footprint : Footprints() )
1223 {
1224 for( PAD* pad : footprint->Pads() )
1225 {
1226 if( ( aNet == -1 && pad->GetNetCode() > 0 ) || aNet == pad->GetNetCode() )
1227 retval++;
1228 }
1229 }
1230
1231 return retval;
1232}
1233
1234
1235BOX2I BOARD::ComputeBoundingBox( bool aBoardEdgesOnly ) const
1236{
1237 BOX2I bbox;
1238 LSET visible = GetVisibleLayers();
1239 bool showInvisibleText = IsElementVisible( LAYER_MOD_TEXT_INVISIBLE )
1240 && PgmOrNull() && !PgmOrNull()->m_Printing;
1241
1242 if( aBoardEdgesOnly )
1243 visible.set( Edge_Cuts );
1244
1245 // Check shapes, dimensions, texts, and fiducials
1246 for( BOARD_ITEM* item : m_drawings )
1247 {
1248 if( aBoardEdgesOnly && ( item->GetLayer() != Edge_Cuts || item->Type() != PCB_SHAPE_T ) )
1249 continue;
1250
1251 if( ( item->GetLayerSet() & visible ).any() )
1252 bbox.Merge( item->GetBoundingBox() );
1253 }
1254
1255 // Check footprints
1256 for( FOOTPRINT* footprint : m_footprints )
1257 {
1258 if( !( footprint->GetLayerSet() & visible ).any() )
1259 continue;
1260
1261 if( aBoardEdgesOnly )
1262 {
1263 for( const BOARD_ITEM* edge : footprint->GraphicalItems() )
1264 {
1265 if( edge->GetLayer() == Edge_Cuts && edge->Type() == PCB_FP_SHAPE_T )
1266 bbox.Merge( edge->GetBoundingBox() );
1267 }
1268 }
1269 else
1270 {
1271 bbox.Merge( footprint->GetBoundingBox( true, showInvisibleText ) );
1272 }
1273 }
1274
1275 if( !aBoardEdgesOnly )
1276 {
1277 // Check tracks
1278 for( PCB_TRACK* track : m_tracks )
1279 {
1280 if( ( track->GetLayerSet() & visible ).any() )
1281 bbox.Merge( track->GetBoundingBox() );
1282 }
1283
1284 // Check zones
1285 for( ZONE* aZone : m_zones )
1286 {
1287 if( ( aZone->GetLayerSet() & visible ).any() )
1288 bbox.Merge( aZone->GetBoundingBox() );
1289 }
1290 }
1291
1292 return bbox;
1293}
1294
1295
1296void BOARD::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
1297{
1298 int padCount = 0;
1299 int viaCount = 0;
1300 int trackSegmentCount = 0;
1301 std::set<int> netCodes;
1302 int unconnected = GetConnectivity()->GetUnconnectedCount( true );
1303
1304 for( PCB_TRACK* item : m_tracks )
1305 {
1306 if( item->Type() == PCB_VIA_T )
1307 viaCount++;
1308 else
1309 trackSegmentCount++;
1310
1311 if( item->GetNetCode() > 0 )
1312 netCodes.insert( item->GetNetCode() );
1313 }
1314
1315 for( FOOTPRINT* footprint : Footprints() )
1316 {
1317 for( PAD* pad : footprint->Pads() )
1318 {
1319 padCount++;
1320
1321 if( pad->GetNetCode() > 0 )
1322 netCodes.insert( pad->GetNetCode() );
1323 }
1324 }
1325
1326 aList.emplace_back( _( "Pads" ), wxString::Format( wxT( "%d" ), padCount ) );
1327 aList.emplace_back( _( "Vias" ), wxString::Format( wxT( "%d" ), viaCount ) );
1328 aList.emplace_back( _( "Track Segments" ), wxString::Format( wxT( "%d" ), trackSegmentCount ) );
1329 aList.emplace_back( _( "Nets" ), wxString::Format( wxT( "%d" ), (int) netCodes.size() ) );
1330 aList.emplace_back( _( "Unrouted" ), wxString::Format( wxT( "%d" ), unconnected ) );
1331}
1332
1333
1334INSPECT_RESULT BOARD::Visit( INSPECTOR inspector, void* testData,
1335 const std::vector<KICAD_T>& scanTypes )
1336{
1337#if 0 && defined(DEBUG)
1338 std::cout << GetClass().mb_str() << ' ';
1339#endif
1340
1341 bool footprintsScanned = false;
1342 bool drawingsScanned = false;
1343 bool tracksScanned = false;
1344
1345 for( KICAD_T scanType : scanTypes )
1346 {
1347 switch( scanType )
1348 {
1349 case PCB_T:
1350 if( inspector( this, testData ) == INSPECT_RESULT::QUIT )
1351 return INSPECT_RESULT::QUIT;
1352
1353 break;
1354
1355 /*
1356 * Instances of the requested KICAD_T live in a list, either one that I manage, or one
1357 * that my footprints manage. If it's a type managed by class FOOTPRINT, then simply
1358 * pass it on to each footprint's Visit() function via IterateForward( m_footprints, ... ).
1359 */
1360
1361 case PCB_FOOTPRINT_T:
1362 case PCB_PAD_T:
1363 case PCB_FP_TEXT_T:
1364 case PCB_FP_TEXTBOX_T:
1365 case PCB_FP_SHAPE_T:
1371 case PCB_FP_ZONE_T:
1372 if( !footprintsScanned )
1373 {
1374 if( IterateForward<FOOTPRINT*>( m_footprints, inspector, testData, scanTypes )
1376 {
1377 return INSPECT_RESULT::QUIT;
1378 }
1379
1380 footprintsScanned = true;
1381 }
1382
1383 break;
1384
1385 case PCB_SHAPE_T:
1386 case PCB_BITMAP_T:
1387 case PCB_TEXT_T:
1388 case PCB_TEXTBOX_T:
1389 case PCB_DIM_ALIGNED_T:
1390 case PCB_DIM_CENTER_T:
1391 case PCB_DIM_RADIAL_T:
1393 case PCB_DIM_LEADER_T:
1394 case PCB_TARGET_T:
1395 if( !drawingsScanned )
1396 {
1397 if( IterateForward<BOARD_ITEM*>( m_drawings, inspector, testData, scanTypes )
1399 {
1400 return INSPECT_RESULT::QUIT;
1401 }
1402
1403 drawingsScanned = true;
1404 }
1405
1406 break;
1407
1408 case PCB_VIA_T:
1409 case PCB_TRACE_T:
1410 case PCB_ARC_T:
1411 if( !tracksScanned )
1412 {
1413 if( IterateForward<PCB_TRACK*>( m_tracks, inspector, testData, scanTypes )
1415 {
1416 return INSPECT_RESULT::QUIT;
1417 }
1418
1419 tracksScanned = true;
1420 }
1421
1422 break;
1423
1424 case PCB_MARKER_T:
1425 for( PCB_MARKER* marker : m_markers )
1426 {
1427 if( marker->Visit( inspector, testData, { scanType } ) == INSPECT_RESULT::QUIT )
1428 return INSPECT_RESULT::QUIT;
1429 }
1430
1431 break;
1432
1433 case PCB_ZONE_T:
1434 for( ZONE* zone : m_zones)
1435 {
1436 if( zone->Visit( inspector, testData, { scanType } ) == INSPECT_RESULT::QUIT )
1437 return INSPECT_RESULT::QUIT;
1438 }
1439
1440 break;
1441
1442 case PCB_GROUP_T:
1443 if( IterateForward<PCB_GROUP*>( m_groups, inspector, testData, { scanType } )
1445 {
1446 return INSPECT_RESULT::QUIT;
1447 }
1448
1449 break;
1450
1451 default:
1452 break;
1453 }
1454 }
1455
1457}
1458
1459
1460NETINFO_ITEM* BOARD::FindNet( int aNetcode ) const
1461{
1462 // the first valid netcode is 1 and the last is m_NetInfo.GetCount()-1.
1463 // zero is reserved for "no connection" and is not actually a net.
1464 // nullptr is returned for non valid netcodes
1465
1466 wxASSERT( m_NetInfo.GetNetCount() > 0 );
1467
1468 if( aNetcode == NETINFO_LIST::UNCONNECTED && m_NetInfo.GetNetCount() == 0 )
1470 else
1471 return m_NetInfo.GetNetItem( aNetcode );
1472}
1473
1474
1475NETINFO_ITEM* BOARD::FindNet( const wxString& aNetname ) const
1476{
1477 return m_NetInfo.GetNetItem( aNetname );
1478}
1479
1480
1481FOOTPRINT* BOARD::FindFootprintByReference( const wxString& aReference ) const
1482{
1483 for( FOOTPRINT* footprint : m_footprints )
1484 {
1485 if( aReference == footprint->GetReference() )
1486 return footprint;
1487 }
1488
1489 return nullptr;
1490}
1491
1492
1494{
1495 for( FOOTPRINT* footprint : m_footprints )
1496 {
1497 if( footprint->GetPath() == aPath )
1498 return footprint;
1499 }
1500
1501 return nullptr;
1502}
1503
1504
1506{
1507 std::set<wxString> names;
1508
1509 for( const NETINFO_ITEM* net : m_NetInfo )
1510 {
1511 if( !net->GetNetname().IsEmpty() )
1512 names.insert( net->GetNetname() );
1513 }
1514
1515 return names;
1516}
1517
1518
1520{
1521 wxCHECK( m_project, /*void*/ );
1522
1523 if( !m_project->IsNullProject() )
1525}
1526
1527
1528void BOARD::SynchronizeNetsAndNetClasses( bool aResetTrackAndViaSizes )
1529{
1530 if( !m_project )
1531 return;
1532
1534 std::shared_ptr<NETCLASS>& defaultNetClass = bds.m_NetSettings->m_DefaultNetClass;
1535
1536 for( NETINFO_ITEM* net : m_NetInfo )
1537 net->SetNetClass( bds.m_NetSettings->GetEffectiveNetClass( net->GetNetname() ) );
1538
1539 if( aResetTrackAndViaSizes )
1540 {
1541 // Set initial values for custom track width & via size to match the default
1542 // netclass settings
1543 bds.UseCustomTrackViaSize( false );
1544 bds.SetCustomTrackWidth( defaultNetClass->GetTrackWidth() );
1545 bds.SetCustomViaSize( defaultNetClass->GetViaDiameter() );
1546 bds.SetCustomViaDrill( defaultNetClass->GetViaDrill() );
1547 bds.SetCustomDiffPairWidth( defaultNetClass->GetDiffPairWidth() );
1548 bds.SetCustomDiffPairGap( defaultNetClass->GetDiffPairGap() );
1549 bds.SetCustomDiffPairViaGap( defaultNetClass->GetDiffPairViaGap() );
1550 }
1551
1553}
1554
1555
1557{
1558 int error_count = 0;
1559
1560 for( ZONE* zone : Zones() )
1561 {
1562 if( !zone->IsOnCopperLayer() )
1563 {
1564 zone->SetNetCode( NETINFO_LIST::UNCONNECTED );
1565 continue;
1566 }
1567
1568 if( zone->GetNetCode() != 0 ) // i.e. if this zone is connected to a net
1569 {
1570 const NETINFO_ITEM* net = zone->GetNet();
1571
1572 if( net )
1573 {
1574 zone->SetNetCode( net->GetNetCode() );
1575 }
1576 else
1577 {
1578 error_count++;
1579
1580 // keep Net Name and set m_NetCode to -1 : error flag.
1581 zone->SetNetCode( -1 );
1582 }
1583 }
1584 }
1585
1586 return error_count;
1587}
1588
1589
1590PAD* BOARD::GetPad( const VECTOR2I& aPosition, LSET aLayerSet ) const
1591{
1592 if( !aLayerSet.any() )
1593 aLayerSet = LSET::AllCuMask();
1594
1595 for( FOOTPRINT* footprint : m_footprints )
1596 {
1597 PAD* pad = nullptr;
1598
1599 if( footprint->HitTest( aPosition ) )
1600 pad = footprint->GetPad( aPosition, aLayerSet );
1601
1602 if( pad )
1603 return pad;
1604 }
1605
1606 return nullptr;
1607}
1608
1609
1610PAD* BOARD::GetPad( const PCB_TRACK* aTrace, ENDPOINT_T aEndPoint ) const
1611{
1612 const VECTOR2I& aPosition = aTrace->GetEndPoint( aEndPoint );
1613
1614 LSET lset( aTrace->GetLayer() );
1615
1616 return GetPad( aPosition, lset );
1617}
1618
1619
1620PAD* BOARD::GetPadFast( const VECTOR2I& aPosition, LSET aLayerSet ) const
1621{
1622 for( FOOTPRINT* footprint : Footprints() )
1623 {
1624 for( PAD* pad : footprint->Pads() )
1625 {
1626 if( pad->GetPosition() != aPosition )
1627 continue;
1628
1629 // Pad found, it must be on the correct layer
1630 if( ( pad->GetLayerSet() & aLayerSet ).any() )
1631 return pad;
1632 }
1633 }
1634
1635 return nullptr;
1636}
1637
1638
1639PAD* BOARD::GetPad( std::vector<PAD*>& aPadList, const VECTOR2I& aPosition, LSET aLayerSet ) const
1640{
1641 // Search aPadList for aPosition
1642 // aPadList is sorted by X then Y values, and a fast binary search is used
1643 int idxmax = aPadList.size() - 1;
1644
1645 int delta = aPadList.size();
1646
1647 int idx = 0; // Starting index is the beginning of list
1648
1649 while( delta )
1650 {
1651 // Calculate half size of remaining interval to test.
1652 // Ensure the computed value is not truncated (too small)
1653 if( (delta & 1) && ( delta > 1 ) )
1654 delta++;
1655
1656 delta /= 2;
1657
1658 PAD* pad = aPadList[idx];
1659
1660 if( pad->GetPosition() == aPosition ) // candidate found
1661 {
1662 // The pad must match the layer mask:
1663 if( ( aLayerSet & pad->GetLayerSet() ).any() )
1664 return pad;
1665
1666 // More than one pad can be at aPosition
1667 // search for a pad at aPosition that matched this mask
1668
1669 // search next
1670 for( int ii = idx+1; ii <= idxmax; ii++ )
1671 {
1672 pad = aPadList[ii];
1673
1674 if( pad->GetPosition() != aPosition )
1675 break;
1676
1677 if( ( aLayerSet & pad->GetLayerSet() ).any() )
1678 return pad;
1679 }
1680 // search previous
1681 for( int ii = idx - 1 ;ii >=0; ii-- )
1682 {
1683 pad = aPadList[ii];
1684
1685 if( pad->GetPosition() != aPosition )
1686 break;
1687
1688 if( ( aLayerSet & pad->GetLayerSet() ).any() )
1689 return pad;
1690 }
1691
1692 // Not found:
1693 return nullptr;
1694 }
1695
1696 if( pad->GetPosition().x == aPosition.x ) // Must search considering Y coordinate
1697 {
1698 if( pad->GetPosition().y < aPosition.y ) // Must search after this item
1699 {
1700 idx += delta;
1701
1702 if( idx > idxmax )
1703 idx = idxmax;
1704 }
1705 else // Must search before this item
1706 {
1707 idx -= delta;
1708
1709 if( idx < 0 )
1710 idx = 0;
1711 }
1712 }
1713 else if( pad->GetPosition().x < aPosition.x ) // Must search after this item
1714 {
1715 idx += delta;
1716
1717 if( idx > idxmax )
1718 idx = idxmax;
1719 }
1720 else // Must search before this item
1721 {
1722 idx -= delta;
1723
1724 if( idx < 0 )
1725 idx = 0;
1726 }
1727 }
1728
1729 return nullptr;
1730}
1731
1732
1738bool sortPadsByXthenYCoord( PAD* const & aLH, PAD* const & aRH )
1739{
1740 if( aLH->GetPosition().x == aRH->GetPosition().x )
1741 return aLH->GetPosition().y < aRH->GetPosition().y;
1742
1743 return aLH->GetPosition().x < aRH->GetPosition().x;
1744}
1745
1746
1747void BOARD::GetSortedPadListByXthenYCoord( std::vector<PAD*>& aVector, int aNetCode ) const
1748{
1749 for( FOOTPRINT* footprint : Footprints() )
1750 {
1751 for( PAD* pad : footprint->Pads( ) )
1752 {
1753 if( aNetCode < 0 || pad->GetNetCode() == aNetCode )
1754 aVector.push_back( pad );
1755 }
1756 }
1757
1758 std::sort( aVector.begin(), aVector.end(), sortPadsByXthenYCoord );
1759}
1760
1761
1762std::tuple<int, double, double> BOARD::GetTrackLength( const PCB_TRACK& aTrack ) const
1763{
1764 int count = 0;
1765 double length = 0.0;
1766 double package_length = 0.0;
1767
1768 auto connectivity = GetBoard()->GetConnectivity();
1771
1772 for( BOARD_CONNECTED_ITEM* item : connectivity->GetConnectedItems(
1773 static_cast<const BOARD_CONNECTED_ITEM*>( &aTrack ),
1774 { PCB_TRACE_T, PCB_ARC_T, PCB_VIA_T, PCB_PAD_T } ) )
1775 {
1776 count++;
1777
1778 if( PCB_TRACK* track = dynamic_cast<PCB_TRACK*>( item ) )
1779 {
1780 if( track->Type() == PCB_VIA_T && useHeight )
1781 {
1782 PCB_VIA* via = static_cast<PCB_VIA*>( track );
1783 length += stackup.GetLayerDistance( via->TopLayer(), via->BottomLayer() );
1784 continue;
1785 }
1786 else if( track->Type() == PCB_ARC_T )
1787 {
1788 // Note: we don't apply the clip-to-pad optimization if an arc ends in a pad
1789 // Room for future improvement.
1790 length += track->GetLength();
1791 continue;
1792 }
1793
1794 bool inPad = false;
1795 SEG trackSeg( track->GetStart(), track->GetEnd() );
1796 double segLen = trackSeg.Length();
1797 double segInPadLen = 0;
1798
1799 for( auto pad_it : connectivity->GetConnectedPads( item ) )
1800 {
1801 PAD* pad = static_cast<PAD*>( pad_it );
1802
1803 bool hitStart = pad->HitTest( track->GetStart(), track->GetWidth() / 2 );
1804 bool hitEnd = pad->HitTest( track->GetEnd(), track->GetWidth() / 2 );
1805
1806 if( hitStart && hitEnd )
1807 {
1808 inPad = true;
1809 break;
1810 }
1811 else if( hitStart || hitEnd )
1812 {
1813 VECTOR2I loc;
1814
1815 // We may not collide even if we passed the bounding-box hit test
1816 if( pad->GetEffectivePolygon()->Collide( trackSeg, 0, nullptr, &loc ) )
1817 {
1818 // Part 1: length of the seg to the intersection with the pad poly
1819 if( hitStart )
1820 trackSeg.A = loc;
1821 else
1822 trackSeg.B = loc;
1823
1824 segLen = trackSeg.Length();
1825
1826 // Part 2: length from the intersection to the pad anchor
1827 segInPadLen += ( loc - pad->GetPosition() ).EuclideanNorm();
1828 }
1829 }
1830 }
1831
1832 if( !inPad )
1833 length += segLen + segInPadLen;
1834 }
1835 else if( PAD* pad = dyn_cast<PAD*>( item ) )
1836 {
1837 package_length += pad->GetPadToDieLength();
1838 }
1839 }
1840
1841 return std::make_tuple( count, length, package_length );
1842}
1843
1844
1845FOOTPRINT* BOARD::GetFootprint( const VECTOR2I& aPosition, PCB_LAYER_ID aActiveLayer,
1846 bool aVisibleOnly, bool aIgnoreLocked ) const
1847{
1848 FOOTPRINT* footprint = nullptr;
1849 FOOTPRINT* alt_footprint = nullptr;
1850 int min_dim = 0x7FFFFFFF;
1851 int alt_min_dim = 0x7FFFFFFF;
1852 bool current_layer_back = IsBackLayer( aActiveLayer );
1853
1854 for( FOOTPRINT* candidate : m_footprints )
1855 {
1856 // is the ref point within the footprint's bounds?
1857 if( !candidate->HitTest( aPosition ) )
1858 continue;
1859
1860 // if caller wants to ignore locked footprints, and this one is locked, skip it.
1861 if( aIgnoreLocked && candidate->IsLocked() )
1862 continue;
1863
1864 PCB_LAYER_ID layer = candidate->GetLayer();
1865
1866 // Filter non visible footprints if requested
1867 if( !aVisibleOnly || IsFootprintLayerVisible( layer ) )
1868 {
1869 BOX2I bb = candidate->GetBoundingBox( false, false );
1870
1871 int offx = bb.GetX() + bb.GetWidth() / 2;
1872 int offy = bb.GetY() + bb.GetHeight() / 2;
1873
1874 // off x & offy point to the middle of the box.
1875 int dist = ( aPosition.x - offx ) * ( aPosition.x - offx ) +
1876 ( aPosition.y - offy ) * ( aPosition.y - offy );
1877
1878 if( current_layer_back == IsBackLayer( layer ) )
1879 {
1880 if( dist <= min_dim )
1881 {
1882 // better footprint shown on the active side
1883 footprint = candidate;
1884 min_dim = dist;
1885 }
1886 }
1887 else if( aVisibleOnly && IsFootprintLayerVisible( layer ) )
1888 {
1889 if( dist <= alt_min_dim )
1890 {
1891 // better footprint shown on the other side
1892 alt_footprint = candidate;
1893 alt_min_dim = dist;
1894 }
1895 }
1896 }
1897 }
1898
1899 if( footprint )
1900 return footprint;
1901
1902 if( alt_footprint)
1903 return alt_footprint;
1904
1905 return nullptr;
1906}
1907
1908
1909std::list<ZONE*> BOARD::GetZoneList( bool aIncludeZonesInFootprints ) const
1910{
1911 std::list<ZONE*> zones;
1912
1913 for( ZONE* zone : Zones() )
1914 zones.push_back( zone );
1915
1916 if( aIncludeZonesInFootprints )
1917 {
1918 for( FOOTPRINT* footprint : m_footprints )
1919 {
1920 for( FP_ZONE* zone : footprint->Zones() )
1921 zones.push_back( zone );
1922 }
1923 }
1924
1925 return zones;
1926}
1927
1928
1929ZONE* BOARD::AddArea( PICKED_ITEMS_LIST* aNewZonesList, int aNetcode, PCB_LAYER_ID aLayer,
1930 VECTOR2I aStartPointPosition, ZONE_BORDER_DISPLAY_STYLE aHatch )
1931{
1932 ZONE* new_area = new ZONE( this );
1933
1934 new_area->SetNetCode( aNetcode );
1935 new_area->SetLayer( aLayer );
1936
1937 m_zones.push_back( new_area );
1938
1939 new_area->SetHatchStyle( (ZONE_BORDER_DISPLAY_STYLE) aHatch );
1940
1941 // Add the first corner to the new zone
1942 new_area->AppendCorner( aStartPointPosition, -1 );
1943
1944 if( aNewZonesList )
1945 {
1946 ITEM_PICKER picker( nullptr, new_area, UNDO_REDO::NEWITEM );
1947 aNewZonesList->PushItem( picker );
1948 }
1949
1950 return new_area;
1951}
1952
1953
1955 OUTLINE_ERROR_HANDLER* aErrorHandler )
1956{
1957 int chainingEpsilon = pcbIUScale.mmToIU( 0.02 ); // max dist from one endPt to next startPt
1958
1959 bool success = BuildBoardPolygonOutlines( this, aOutlines, GetDesignSettings().m_MaxError,
1960 chainingEpsilon, aErrorHandler );
1961
1962 // Make polygon strictly simple to avoid issues (especially in 3D viewer)
1964
1965 return success;
1966}
1967
1968
1969const std::vector<PAD*> BOARD::GetPads() const
1970{
1971 std::vector<PAD*> allPads;
1972
1973 for( FOOTPRINT* footprint : Footprints() )
1974 {
1975 for( PAD* pad : footprint->Pads() )
1976 allPads.push_back( pad );
1977 }
1978
1979 return allPads;
1980}
1981
1982
1983const std::vector<BOARD_CONNECTED_ITEM*> BOARD::AllConnectedItems()
1984{
1985 std::vector<BOARD_CONNECTED_ITEM*> items;
1986
1987 for( PCB_TRACK* track : Tracks() )
1988 items.push_back( track );
1989
1990 for( FOOTPRINT* footprint : Footprints() )
1991 {
1992 for( PAD* pad : footprint->Pads() )
1993 items.push_back( pad );
1994 }
1995
1996 for( ZONE* zone : Zones() )
1997 items.push_back( zone );
1998
1999 return items;
2000}
2001
2002
2003void BOARD::MapNets( const BOARD* aDestBoard )
2004{
2006 {
2007 NETINFO_ITEM* netInfo = aDestBoard->FindNet( item->GetNetname() );
2008
2009 if( netInfo )
2010 item->SetNet( netInfo );
2011 else
2012 item->SetNetCode( 0 );
2013 }
2014}
2015
2016
2018{
2019 for ( BOARD_CONNECTED_ITEM* item : AllConnectedItems() )
2020 {
2021 if( FindNet( item->GetNetCode() ) == nullptr )
2022 item->SetNetCode( NETINFO_LIST::ORPHANED );
2023 }
2024}
2025
2026
2028{
2029 if( !alg::contains( m_listeners, aListener ) )
2030 m_listeners.push_back( aListener );
2031}
2032
2033
2035{
2036 auto i = std::find( m_listeners.begin(), m_listeners.end(), aListener );
2037
2038 if( i != m_listeners.end() )
2039 {
2040 std::iter_swap( i, m_listeners.end() - 1 );
2041 m_listeners.pop_back();
2042 }
2043}
2044
2045
2047{
2048 m_listeners.clear();
2049}
2050
2051
2053{
2055}
2056
2057
2058void BOARD::OnItemsChanged( std::vector<BOARD_ITEM*>& aItems )
2059{
2061}
2062
2063
2065{
2068
2070}
2071
2072
2073void BOARD::SetHighLightNet( int aNetCode, bool aMulti )
2074{
2075 if( !m_highLight.m_netCodes.count( aNetCode ) )
2076 {
2077 if( !aMulti )
2078 m_highLight.m_netCodes.clear();
2079
2080 m_highLight.m_netCodes.insert( aNetCode );
2082 }
2083}
2084
2085
2086void BOARD::HighLightON( bool aValue )
2087{
2088 if( m_highLight.m_highLightOn != aValue )
2089 {
2090 m_highLight.m_highLightOn = aValue;
2092 }
2093}
2094
2095
2096wxString BOARD::GroupsSanityCheck( bool repair )
2097{
2098 if( repair )
2099 {
2100 while( GroupsSanityCheckInternal( repair ) != wxEmptyString )
2101 {};
2102
2103 return wxEmptyString;
2104 }
2105 return GroupsSanityCheckInternal( repair );
2106}
2107
2108
2110{
2111 // Cycle detection
2112 //
2113 // Each group has at most one parent group.
2114 // So we start at group 0 and traverse the parent chain, marking groups seen along the way.
2115 // If we ever see a group that we've already marked, that's a cycle.
2116 // If we reach the end of the chain, we know all groups in that chain are not part of any cycle.
2117 //
2118 // Algorithm below is linear in the # of groups because each group is visited only once.
2119 // There may be extra time taken due to the container access calls and iterators.
2120 //
2121 // Groups we know are cycle free
2122 std::unordered_set<PCB_GROUP*> knownCycleFreeGroups;
2123 // Groups in the current chain we're exploring.
2124 std::unordered_set<PCB_GROUP*> currentChainGroups;
2125 // Groups we haven't checked yet.
2126 std::unordered_set<PCB_GROUP*> toCheckGroups;
2127
2128 // Initialize set of groups to check that could participate in a cycle.
2129 for( PCB_GROUP* group : Groups() )
2130 toCheckGroups.insert( group);
2131
2132 while( !toCheckGroups.empty() )
2133 {
2134 currentChainGroups.clear();
2135 PCB_GROUP* group = *toCheckGroups.begin();
2136
2137 while( true )
2138 {
2139 if( currentChainGroups.find( group ) != currentChainGroups.end() )
2140 {
2141 if( repair )
2142 Remove( group );
2143
2144 return "Cycle detected in group membership";
2145 }
2146 else if( knownCycleFreeGroups.find( group ) != knownCycleFreeGroups.end() )
2147 {
2148 // Parent is a group we know does not lead to a cycle
2149 break;
2150 }
2151
2152 currentChainGroups.insert( group );
2153 // We haven't visited currIdx yet, so it must be in toCheckGroups
2154 toCheckGroups.erase( group );
2155
2156 group = group->GetParentGroup();
2157
2158 if( !group )
2159 {
2160 // end of chain and no cycles found in this chain
2161 break;
2162 }
2163 }
2164
2165 // No cycles found in chain, so add it to set of groups we know don't participate
2166 // in a cycle.
2167 knownCycleFreeGroups.insert( currentChainGroups.begin(), currentChainGroups.end() );
2168 }
2169
2170 // Success
2171 return "";
2172}
2173
2174
2176{
2177 bool hasGroup = false;
2178 bool hasMember = false;
2179
2180 for( EDA_ITEM* item : selection )
2181 {
2182 if( item->Type() == PCB_GROUP_T )
2183 hasGroup = true;
2184
2185 if( static_cast<BOARD_ITEM*>( item )->GetParentGroup() )
2186 hasMember = true;
2187 }
2188
2189 GroupLegalOpsField legalOps;
2190
2191 legalOps.create = true;
2192 legalOps.removeItems = hasMember;
2193 legalOps.ungroup = hasGroup;
2194
2195 return legalOps;
2196}
2197
2198
2200{
2201 if( a->Type() != b->Type() )
2202 return a->Type() < b->Type();
2203
2204 if( a->GetLayer() != b->GetLayer() )
2205 return a->GetLayer() < b->GetLayer();
2206
2207 if( a->GetPosition().x != b->GetPosition().x )
2208 return a->GetPosition().x < b->GetPosition().x;
2209
2210 if( a->GetPosition().y != b->GetPosition().y )
2211 return a->GetPosition().y < b->GetPosition().y;
2212
2213 if( a->m_Uuid != b->m_Uuid ) // shopuld be always the case foer valid boards
2214 return a->m_Uuid < b->m_Uuid;
2215
2216 return a < b;
2217}
2218
2219
2221 const BOARD_ITEM* aSecond ) const
2222{
2223 if( aFirst->Type() != aSecond->Type() )
2224 return aFirst->Type() < aSecond->Type();
2225
2226 if( aFirst->GetLayer() != aSecond->GetLayer() )
2227 return aFirst->GetLayer() < aSecond->GetLayer();
2228
2229 if( aFirst->Type() == PCB_SHAPE_T )
2230 {
2231 const PCB_SHAPE* shape = static_cast<const PCB_SHAPE*>( aFirst );
2232 const PCB_SHAPE* other = static_cast<const PCB_SHAPE*>( aSecond );
2233 return shape->Compare( other );
2234 }
2235 else if( aFirst->Type() == PCB_TEXT_T )
2236 {
2237 const PCB_TEXT* text = static_cast<const PCB_TEXT*>( aFirst );
2238 const PCB_TEXT* other = static_cast<const PCB_TEXT*>( aSecond );
2239 return text->Compare( other );
2240 }
2241 else if( aFirst->Type() == PCB_TEXTBOX_T )
2242 {
2243 const PCB_TEXTBOX* textbox = static_cast<const PCB_TEXTBOX*>( aFirst );
2244 const PCB_TEXTBOX* other = static_cast<const PCB_TEXTBOX*>( aSecond );
2245
2246 return textbox->PCB_SHAPE::Compare( other ) && textbox->EDA_TEXT::Compare( other );
2247 }
2248
2249 return aFirst->m_Uuid < aSecond->m_Uuid;
2250}
2251
2252
2254 SHAPE_POLY_SET& aOutlines ) const
2255{
2256 int maxError = GetDesignSettings().m_MaxError;
2257
2258 // convert tracks and vias:
2259 for( const PCB_TRACK* track : m_tracks )
2260 {
2261 if( !track->IsOnLayer( aLayer ) )
2262 continue;
2263
2264 track->TransformShapeToPolygon( aOutlines, aLayer, 0, maxError, ERROR_INSIDE );
2265 }
2266
2267 // convert pads and other copper items in footprints
2268 for( const FOOTPRINT* footprint : m_footprints )
2269 {
2270 footprint->TransformPadsToPolySet( aOutlines, aLayer, 0, maxError, ERROR_INSIDE );
2271
2272 // Microwave footprints may have items on copper layers
2273 footprint->TransformFPShapesToPolySet( aOutlines, aLayer, 0, maxError, ERROR_INSIDE,
2274 true, /* include text */
2275 true, /* include shapes */
2276 false /* include private items */ );
2277
2278 for( const ZONE* zone : footprint->Zones() )
2279 {
2280 if( zone->GetLayerSet().test( aLayer ) )
2281 zone->TransformSolidAreasShapesToPolygon( aLayer, aOutlines );
2282 }
2283 }
2284
2285 // convert copper zones
2286 for( const ZONE* zone : Zones() )
2287 {
2288 if( zone->GetLayerSet().test( aLayer ) )
2289 zone->TransformSolidAreasShapesToPolygon( aLayer, aOutlines );
2290 }
2291
2292 // convert graphic items on copper layers (texts)
2293 for( const BOARD_ITEM* item : m_drawings )
2294 {
2295 if( !item->IsOnLayer( aLayer ) )
2296 continue;
2297
2298 switch( item->Type() )
2299 {
2300 case PCB_SHAPE_T:
2301 {
2302 const PCB_SHAPE* shape = static_cast<const PCB_SHAPE*>( item );
2303 shape->TransformShapeToPolygon( aOutlines, aLayer, 0, maxError, ERROR_INSIDE );
2304 break;
2305 }
2306
2307 case PCB_TEXT_T:
2308 {
2309 const PCB_TEXT* text = static_cast<const PCB_TEXT*>( item );
2310 text->TransformTextToPolySet( aOutlines, aLayer, 0, maxError, ERROR_INSIDE );
2311 break;
2312 }
2313
2314 case PCB_TEXTBOX_T:
2315 {
2316 const PCB_TEXTBOX* textbox = static_cast<const PCB_TEXTBOX*>( item );
2317
2318 // plot border
2319 textbox->PCB_SHAPE::TransformShapeToPolygon( aOutlines, aLayer, 0, maxError,
2320 ERROR_INSIDE );
2321 // plot text
2322 textbox->TransformTextToPolySet( aOutlines, aLayer, 0, maxError, ERROR_INSIDE );
2323 break;
2324 }
2325
2326 default:
2327 break;
2328 }
2329 }
2330}
2331
2332
@ 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:1738
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:58
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition: board_item.h:180
PCB_GROUP * GetParentGroup() const
Definition: board_item.h:72
virtual void Move(const VECTOR2I &aMoveVector)
Move this object.
Definition: board_item.h:266
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
Definition: board_item.cpp:43
static VECTOR2I ZeroOffset
A value of wxPoint(0,0) which can be passed to the Draw() functions.
Definition: board_item.h:141
wxString GetLayerName() const
Return the name of the PCB layer on which the item resides.
Definition: board_item.cpp:94
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:1334
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:674
std::unordered_map< PTR_PTR_LAYER_CACHE_KEY, bool > m_EnclosedByAreaCache
Definition: board.h:1143
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:2052
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:569
void SetPosition(const VECTOR2I &aPos) override
Definition: board.cpp:377
std::map< wxString, wxString > m_properties
Definition: board.h:1192
int m_fileFormatVersionAtLoad
Definition: board.h:1189
LSET GetVisibleLayers() const
A proxy function that calls the correspondent function in m_BoardSettings.
Definition: board.cpp:583
std::vector< ZONE * > m_DRCCopperZones
Definition: board.h:1151
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
Definition: board.cpp:754
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:698
PAD * GetPadFast(const VECTOR2I &aPosition, LSET aLayerMask) const
Return pad found at aPosition on aLayerMask using the fast search method.
Definition: board.cpp:1620
LAYER m_layers[PCB_LAYER_ID_COUNT]
Definition: board.h:1184
static wxString GetStandardLayerName(PCB_LAYER_ID aLayerId)
Return an "English Standard" name of a PCB layer when given aLayerNumber.
Definition: board.h:696
const std::vector< BOARD_CONNECTED_ITEM * > AllConnectedItems()
Definition: board.cpp:1983
bool IsElementVisible(GAL_LAYER_ID aLayer) const
Test whether a given element category is visible.
Definition: board.cpp:635
std::set< wxString > GetNetClassAssignmentCandidates() const
Return the set of netname candidates for netclass assignment.
Definition: board.cpp:1505
const ZONE_SETTINGS & GetZoneSettings() const override
Fetch the zone settings for this container.
Definition: board.cpp:692
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:2003
void RemoveAllListeners()
Remove all listeners.
Definition: board.cpp:2046
FOOTPRINTS m_footprints
Definition: board.h:1179
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:1210
void SetEnabledLayers(LSET aLayerMask)
A proxy function that calls the correspondent function in m_BoardSettings.
Definition: board.cpp:589
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:2027
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:629
ZONES & Zones()
Definition: board.h:313
void SetHighLightNet(int aNetCode, bool aMulti=false)
Select the netcode to be highlighted.
Definition: board.cpp:2073
HIGH_LIGHT_INFO m_highLight
Definition: board.h:1186
bool SetLayerDescr(PCB_LAYER_ID aIndex, const LAYER &aLayer)
Return the type of the copper layer given by aLayer.
Definition: board.cpp:424
NETINFO_ITEM * FindNet(int aNetcode) const
Search for a net with the given netcode.
Definition: board.cpp:1460
BOARD_ITEM * GetItem(const KIID &aID) const
Definition: board.cpp:1001
void InvokeListeners(Func &&aFunc, Args &&... args)
Definition: board.h:1164
void SanitizeNetcodes()
Definition: board.cpp:2017
wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider) const override
Return a user-visible description string of this item.
Definition: board.cpp:954
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:1929
~BOARD()
Definition: board.cpp:121
bool BuildConnectivity(PROGRESS_REPORTER *aReporter=nullptr)
Build or rebuild the board connectivity database for the board, especially the list of connected item...
Definition: board.cpp:162
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:595
LAYER_T GetLayerType(PCB_LAYER_ID aLayer) const
Return the type of the copper layer given by aLayer.
Definition: board.cpp:490
DRAWINGS m_drawings
Definition: board.h:1178
int SetAreasNetCodesFromNetNames()
Set the .m_NetCode member of all copper areas, according to the area Net Name The SetNetCodesFromNetN...
Definition: board.cpp:1556
void SynchronizeNetsAndNetClasses(bool aResetTrackAndViaSizes)
Copy NETCLASS info to each NET, based on NET membership in a NETCLASS.
Definition: board.cpp:1528
void ResetNetHighLight()
Reset all high light data to the init state.
Definition: board.cpp:2064
bool SetLayerName(PCB_LAYER_ID aLayer, const wxString &aLayerName)
Changes the name of the layer given by aLayer.
Definition: board.cpp:472
std::list< ZONE * > GetZoneList(bool aIncludeZonesInFootprints=false) const
Definition: board.cpp:1909
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:2253
bool ResolveTextVar(wxString *token, int aDepth) const
Definition: board.cpp:332
const std::vector< PAD * > GetPads() const
Return a reference to a list of all the pads.
Definition: board.cpp:1969
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:1954
void Move(const VECTOR2I &aMoveVector) override
Move this object.
Definition: board.cpp:383
TITLE_BLOCK & GetTitleBlock()
Definition: board.h:632
BOX2I ComputeBoundingBox(bool aBoardEdgesOnly=false) const
Calculate the bounding box containing all board items (or board edge segments).
Definition: board.cpp:1235
ZONES m_zones
Definition: board.h:1182
FOOTPRINTS & Footprints()
Definition: board.h:307
HIGH_LIGHT_INFO m_highLightPrevious
Definition: board.h:1187
std::unique_ptr< DRC_RTREE > m_CopperItemRTreeCache
Definition: board.h:1146
NETINFO_LIST m_NetInfo
Definition: board.h:1212
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:618
GroupLegalOpsField GroupLegalOps(const PCB_SELECTION &selection) const
Check which selection tool group operations are legal given the selection.
Definition: board.cpp:2175
int GetCopperLayerCount() const
Definition: board.cpp:545
int m_timeStamp
Definition: board.h:1174
std::vector< BOARD_LISTENER * > m_listeners
Definition: board.h:1214
const PCB_LAYER_ID GetLayerID(const wxString &aLayerName) const
Return the ID of a layer.
Definition: board.cpp:436
std::unordered_map< PTR_PTR_CACHE_KEY, bool > m_IntersectsCourtyardCache
Definition: board.h:1139
void IncrementTimeStamp()
Definition: board.cpp:230
std::unordered_map< PTR_PTR_CACHE_KEY, bool > m_IntersectsFCourtyardCache
Definition: board.h:1140
std::shared_ptr< CONNECTIVITY_DATA > m_connectivity
Definition: board.h:1193
int m_DRCMaxPhysicalClearance
Definition: board.h:1153
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:1493
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:857
std::unordered_map< wxString, LSET > m_LayerExpressionCache
Definition: board.h:1144
wxString GroupsSanityCheckInternal(bool repair)
Definition: board.cpp:2109
wxString ConvertCrossReferencesToKIIDs(const wxString &aSource) const
Convert cross-references back and forth between ${refDes:field} and ${kiid:field}.
Definition: board.cpp:1116
TRACKS & Tracks()
Definition: board.h:304
wxString GetClass() const override
Return the class name.
Definition: board.h:881
void SetVisibleLayers(LSET aLayerMask)
A proxy function that calls the correspondent function in m_BoardSettings changes the bit-mask of vis...
Definition: board.cpp:601
bool m_LegacyNetclassesLoaded
True if netclasses were loaded from the file.
Definition: board.h:346
void SetCopperLayerCount(int aCount)
Definition: board.cpp:551
std::unordered_map< const ZONE *, BOX2I > m_ZoneBBoxCache
Definition: board.h:1147
MARKERS & Markers()
Definition: board.h:316
std::unordered_map< PTR_PTR_CACHE_KEY, bool > m_IntersectsBCourtyardCache
Definition: board.h:1141
TRACKS TracksInNet(int aNetCode)
Collect all the TRACKs and VIAs that are members of a net given by aNetCode.
Definition: board.cpp:402
void SetProject(PROJECT *aProject, bool aReferenceOnly=false)
Link a board to a given project.
Definition: board.cpp:172
PROJECT * m_project
Definition: board.h:1198
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:1845
ZONE * m_SolderMask
Definition: board.h:1154
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:1481
unsigned GetNodesCount(int aNet=-1) const
Definition: board.cpp:1218
void FillItemMap(std::map< KIID, EDA_ITEM * > &aMap)
Definition: board.cpp:1080
void SetElementVisibility(GAL_LAYER_ID aLayer, bool aNewState)
Change the visibility of an element category.
Definition: board.cpp:641
bool SetLayerType(PCB_LAYER_ID aLayer, LAYER_T aLayerType)
Change the type of the layer given by aLayer.
Definition: board.cpp:502
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:1747
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:575
int m_DRCMaxClearance
Definition: board.h:1152
void ClearProject()
Definition: board.cpp:210
std::unordered_map< ZONE *, std::unique_ptr< DRC_RTREE > > m_CopperZoneRTreeCache
Definition: board.h:1145
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:851
int LayerDepth(PCB_LAYER_ID aStartLayer, PCB_LAYER_ID aEndLayer) const
Definition: board.cpp:557
void DeleteAllFootprints()
Remove all footprints from the deque and free the memory associated with them.
Definition: board.cpp:992
PROJECT * GetProject() const
Definition: board.h:440
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:1762
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:1296
wxString GroupsSanityCheck(bool repair=false)
Consistency check of internal m_groups structure.
Definition: board.cpp:2096
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:686
std::vector< ZONE * > m_DRCZones
Definition: board.h:1150
PAD * GetPad(const VECTOR2I &aPosition, LSET aLayerMask) const
Find a pad aPosition on aLayer.
Definition: board.cpp:1590
BOARD()
Definition: board.cpp:69
void UpdateRatsnestExclusions()
Update the visibility flags on the current unconnected ratsnest lines.
Definition: board.cpp:270
wxString ConvertKIIDsToCrossReferences(const wxString &aSource) const
Definition: board.cpp:1170
std::vector< PCB_MARKER * > ResolveDRCExclusions()
Rebuild DRC markers from the serialized data in BOARD_DESIGN_SETTINGS.
Definition: board.cpp:300
void SynchronizeProperties()
Copy the current project's text variables into the boards property cache.
Definition: board.cpp:1519
void RemoveListener(BOARD_LISTENER *aListener)
Remove the specified listener.
Definition: board.cpp:2034
void DeleteMARKERs()
Delete all MARKERS from the board.
Definition: board.cpp:960
void Remove(BOARD_ITEM *aBoardItem, REMOVE_MODE aMode=REMOVE_MODE::NORMAL) override
Removes an item from the container.
Definition: board.cpp:863
GROUPS m_groups
Definition: board.h:1181
MARKERS m_markers
Definition: board.h:1177
std::unordered_map< PTR_PTR_LAYER_CACHE_KEY, bool > m_IntersectsAreaCache
Definition: board.h:1142
void HighLightON(bool aValue=true)
Enable or disable net highlighting.
Definition: board.cpp:2086
TRACKS m_tracks
Definition: board.h:1180
std::mutex m_CachesMutex
Definition: board.h:1138
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:2058
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:371
void CacheTriangulation(PROGRESS_REPORTER *aReporter=nullptr, const std::vector< ZONE * > &aZones={})
Definition: board.cpp:704
void SetVisibleElements(const GAL_SET &aMask)
A proxy function that calls the correspondent function in m_BoardSettings.
Definition: board.cpp:608
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.
std::shared_ptr< const CN_ANCHOR > GetSourceNode() const
void SetVisible(bool aVisible)
std::shared_ptr< const CN_ANCHOR > GetTargetNode() const
static DELETED_BOARD_ITEM * GetInstance()
Definition: board_item.h:368
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:139
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:158
EDA_ITEM_FLAGS GetFlags() const
Definition: eda_item.h:142
int Compare(const EDA_SHAPE *aOther) const
Definition: eda_shape.cpp:1508
bool ResolveTextVar(wxString *token, int aDepth=0) const
Resolve any references to system tokens supported by the component.
Definition: footprint.cpp:493
A specialization of ZONE for use in footprints.
Definition: zone.h:910
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:48
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:67
void SetNetCode(int aNetCode)
Definition: netinfo.h:115
int GetNetCode() const
Definition: netinfo.h:114
static const int UNCONNECTED
Constant that forces initialization of a netinfo item to the NETINFO_ITEM ORPHANED (typically -1) whe...
Definition: netinfo.h:382
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:386
static NETINFO_ITEM * OrphanedItem()
Wrapper class, so you can iterate through NETINFO_ITEM*s, not std::pair<int/wxString,...
Definition: netinfo.h:390
unsigned GetNetCount() const
Definition: netinfo.h:356
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:59
VECTOR2I GetPosition() const override
Definition: pad.h:202
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:95
static PCB_MARKER * Deserialize(const wxString &data)
Definition: pcb_marker.cpp:139
void TransformShapeToPolygon(SHAPE_POLY_SET &aBuffer, PCB_LAYER_ID aLayer, int aClearance, int aError, ERROR_LOC aErrorLoc, bool ignoreLineWidth=false) const override
Convert the shape to a closed polygon.
Definition: pcb_shape.cpp:390
void TransformTextToPolySet(SHAPE_POLY_SET &aBuffer, PCB_LAYER_ID aLayer, int aClearance, int aError, ERROR_LOC aErrorLoc) const
Function TransformTextToPolySet Convert the text to a polygonSet describing the actual character stro...
const VECTOR2I & GetEndPoint(ENDPOINT_T aEndPoint) const
Return the selected endpoint (start or end)
Definition: pcb_track.h:122
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:304
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:64
virtual PROJECT_LOCAL_SETTINGS & GetLocalSettings() const
Definition: project.h:155
virtual bool TextVarResolver(wxString *aToken) const
Definition: project.cpp:70
virtual PROJECT_FILE & GetProjectFile() const
Definition: project.h:149
virtual std::map< wxString, wxString > & GetTextVars() const
Definition: project.cpp:82
virtual bool IsNullProject() const
Check if this project is a null project (i.e.
Definition: project.cpp:138
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:326
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.
bool TextVarResolver(wxString *aToken, const PROJECT *aProject) const
Definition: title_block.cpp:96
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:252
virtual void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
Definition: zone.cpp:260
SHAPE_POLY_SET * Outline()
Definition: zone.h:312
void SetHatchStyle(ZONE_BORDER_DISPLAY_STYLE aStyle)
Definition: zone.h:581
void SetLayerSet(LSET aLayerSet) override
Definition: zone.cpp:266
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:760
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:922
bool IsCopperLayer(int aLayerId)
Tests whether a layer is a copper layer.
Definition: layer_ids.h:825
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:932
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:56
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:2220
bool operator()(const BOARD_ITEM *aFirst, const BOARD_ITEM *aSecond) const
Definition: board.cpp:2199
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:530
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:517
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