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