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 The 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#include <algorithm>
30
31#include <wx/log.h>
32
33#include <drc/drc_rtree.h>
35#include <board_commit.h>
36#include <board.h>
37#include <core/arraydim.h>
38#include <core/kicad_algo.h>
41#include <footprint.h>
42#include <font/outline_font.h>
44#include <lset.h>
45#include <pcb_base_frame.h>
46#include <pcb_track.h>
47#include <pcb_marker.h>
48#include <pcb_group.h>
49#include <pcb_generator.h>
50#include <pcb_point.h>
51#include <pcb_target.h>
52#include <pcb_shape.h>
53#include <pcb_barcode.h>
54#include <pcb_text.h>
55#include <pcb_textbox.h>
56#include <pcb_table.h>
57#include <pcb_dimension.h>
58#include <pgm_base.h>
59#include <pcbnew_settings.h>
60#include <progress_reporter.h>
61#include <project.h>
67#include <reporter.h>
68#include <tool/tool_manager.h>
70#include <string_utils.h>
71#include <thread_pool.h>
72#include <zone.h>
73#include <mutex>
74#include <pcb_board_outline.h>
75
76// This is an odd place for this, but CvPcb won't link if it's in board_item.cpp like I first
77// tried it.
79
80
87 m_timeStamp( 1 ),
89 m_project( nullptr ),
91 m_designSettings( new BOARD_DESIGN_SETTINGS( nullptr, "board.design_settings" ) ),
92 m_NetInfo( this ),
93 m_embedFonts( false ),
94 m_embeddedFilesDelegate( nullptr ),
96 m_lengthDelayCalc( std::make_unique<LENGTH_DELAY_CALCULATION>( this ) )
97{
98 // A too small value do not allow connecting 2 shapes (i.e. segments) not exactly connected
99 // A too large value do not allow safely connecting 2 shapes like very short segments.
101
104 m_boardOutline = new PCB_BOARD_OUTLINE( this );
105
106 // we have not loaded a board yet, assume latest until then.
107 m_fileFormatVersionAtLoad = LEGACY_BOARD_FILE_VERSION;
108
109 for( int layer = 0; layer < PCB_LAYER_ID_COUNT; ++layer )
110 {
111 m_layers[layer].m_name = GetStandardLayerName( ToLAYER_ID( layer ) );
112
113 if( IsCopperLayer( layer ) )
114 m_layers[layer].m_type = LT_SIGNAL;
115 else if( layer >= User_1 && layer & 1 )
116 m_layers[layer].m_type = LT_AUX;
117 else
118 m_layers[layer].m_type = LT_UNDEFINED;
119 }
120
122
123 // Creates a zone to show sloder mask bridges created by a min web value
124 // it it just to show them
125 m_SolderMaskBridges = new ZONE( this );
127 m_SolderMaskBridges->SetLayerSet( LSET().set( F_Mask ).set( B_Mask ) );
128 int infinity = ( std::numeric_limits<int>::max() / 2 ) - pcbIUScale.mmToIU( 1 );
129 m_SolderMaskBridges->Outline()->NewOutline();
130 m_SolderMaskBridges->Outline()->Append( VECTOR2I( -infinity, -infinity ) );
131 m_SolderMaskBridges->Outline()->Append( VECTOR2I( -infinity, +infinity ) );
132 m_SolderMaskBridges->Outline()->Append( VECTOR2I( +infinity, +infinity ) );
133 m_SolderMaskBridges->Outline()->Append( VECTOR2I( +infinity, -infinity ) );
134 m_SolderMaskBridges->SetMinThickness( 0 );
135
137
138 // Initialize default netclass.
139 bds.m_NetSettings->SetDefaultNetclass( std::make_shared<NETCLASS>( NETCLASS::Default ) );
141 _( "This is the default net class." ) );
142
143 bds.UseCustomTrackViaSize( false );
144
145 // Initialize ratsnest
146 m_connectivity.reset( new CONNECTIVITY_DATA() );
147
148 // Set flag bits on these that will only be cleared if these are loaded from a legacy file
149 m_LegacyVisibleLayers.reset().set( Rescue );
151}
152
153
155{
156 m_itemByIdCache.clear();
157
158 // Clean up the owned elements
160
161 delete m_SolderMaskBridges;
162
163 BOARD_ITEM_SET ownedItems = GetItemSet();
164
165 m_zones.clear();
166 m_footprints.clear();
167 m_tracks.clear();
168 m_drawings.clear();
169 m_groups.clear();
170 m_points.clear();
171
172 // Generators not currently returned by GetItemSet
173 for( PCB_GENERATOR* g : m_generators )
174 ownedItems.insert( g );
175
176 delete m_boardOutline;
177 m_generators.clear();
178
179 // Delete the owned items after clearing the containers, because some item dtors
180 // cause call chains that query the containers
181 for( BOARD_ITEM* item : ownedItems )
182 delete item;
183
184 // Remove any listeners
186}
187
188
190{
191 if( !GetConnectivity()->Build( this, aReporter ) )
192 return false;
193
195 return true;
196}
197
198
199void BOARD::SetProject( PROJECT* aProject, bool aReferenceOnly )
200{
201 if( m_project )
202 ClearProject();
203
204 m_project = aProject;
205
206 if( aProject && !aReferenceOnly )
207 {
208 PROJECT_FILE& project = aProject->GetProjectFile();
209
210 // Link the design settings object to the project file
211 project.m_BoardSettings = &GetDesignSettings();
212
213 // Set parent, which also will load the values from JSON stored in the project if we don't
214 // have legacy design settings loaded already
215 project.m_BoardSettings->SetParent( &project, !m_LegacyDesignSettingsLoaded );
216
217 // The DesignSettings' netclasses pointer will be pointing to its internal netclasses
218 // list at this point. If we loaded anything into it from a legacy board file then we
219 // want to transfer it over to the project netclasses list.
221 {
222 std::shared_ptr<NET_SETTINGS> legacySettings = GetDesignSettings().m_NetSettings;
223 std::shared_ptr<NET_SETTINGS>& projectSettings = project.NetSettings();
224
225 projectSettings->SetDefaultNetclass( legacySettings->GetDefaultNetclass() );
226 projectSettings->SetNetclasses( legacySettings->GetNetclasses() );
227 projectSettings->SetNetclassPatternAssignments(
228 std::move( legacySettings->GetNetclassPatternAssignments() ) );
229 }
230
231 // Now update the DesignSettings' netclass pointer to point into the project.
232 GetDesignSettings().m_NetSettings = project.NetSettings();
233 }
234}
235
236
238{
239 if( !m_project )
240 return;
241
242 PROJECT_FILE& project = m_project->GetProjectFile();
243
244 // Owned by the BOARD
245 if( project.m_BoardSettings )
246 {
247 project.ReleaseNestedSettings( project.m_BoardSettings );
248 project.m_BoardSettings = nullptr;
249 }
250
252 GetDesignSettings().SetParent( nullptr );
253 m_project = nullptr;
254}
255
256
258{
259 std::unique_lock<std::shared_mutex> writeLock( m_CachesMutex );
260
261 m_timeStamp++;
262
263 if( !m_IntersectsAreaCache.empty()
264 || !m_EnclosedByAreaCache.empty()
268 || !m_LayerExpressionCache.empty()
269 || !m_ZoneBBoxCache.empty()
271 || m_maxClearanceValue.has_value()
272 || !m_itemByIdCache.empty() )
273 {
274 m_IntersectsAreaCache.clear();
275 m_EnclosedByAreaCache.clear();
280
281 m_ZoneBBoxCache.clear();
282
283 m_CopperItemRTreeCache = nullptr;
284
285 // These are always regenerated before use, but still probably safer to clear them
286 // while we're here.
289 m_DRCZones.clear();
290 m_DRCCopperZones.clear();
293
294 m_maxClearanceValue.reset();
295
296 m_itemByIdCache.clear();
297 }
298}
299
300
302{
303 std::set<std::pair<KIID, KIID>> m_ratsnestExclusions;
304
305 for( PCB_MARKER* marker : GetBoard()->Markers() )
306 {
307 if( marker->GetMarkerType() == MARKER_BASE::MARKER_RATSNEST && marker->IsExcluded() )
308 {
309 const std::shared_ptr<RC_ITEM>& rcItem = marker->GetRCItem();
310 m_ratsnestExclusions.emplace( rcItem->GetMainItemID(), rcItem->GetAuxItemID() );
311 m_ratsnestExclusions.emplace( rcItem->GetAuxItemID(), rcItem->GetMainItemID() );
312 }
313 }
314
316 [&]( CN_EDGE& aEdge )
317 {
318 if( aEdge.GetSourceNode() && aEdge.GetTargetNode()
319 && !aEdge.GetSourceNode()->Dirty() && !aEdge.GetTargetNode()->Dirty() )
320 {
321 std::pair<KIID, KIID> ids = { aEdge.GetSourceNode()->Parent()->m_Uuid,
322 aEdge.GetTargetNode()->Parent()->m_Uuid };
323
324 aEdge.SetVisible( m_ratsnestExclusions.count( ids ) == 0 );
325 }
326
327 return true;
328 } );
329}
330
331
333{
334 m_designSettings->m_DrcExclusions.clear();
335 m_designSettings->m_DrcExclusionComments.clear();
336
337 for( PCB_MARKER* marker : m_markers )
338 {
339 if( marker->IsExcluded() )
340 {
341 wxString serialized = marker->SerializeToString();
342 m_designSettings->m_DrcExclusions.insert( serialized );
343 m_designSettings->m_DrcExclusionComments[ serialized ] = marker->GetComment();
344 }
345 }
346
347 if( m_project )
348 {
349 if( PROJECT_FILE* projectFile = &m_project->GetProjectFile() )
350 {
351 if( BOARD_DESIGN_SETTINGS* prjSettings = projectFile->m_BoardSettings )
352 {
353 prjSettings->m_DrcExclusions = m_designSettings->m_DrcExclusions;
354 prjSettings->m_DrcExclusionComments = m_designSettings->m_DrcExclusionComments;
355 }
356 }
357 }
358}
359
360std::set<wxString>::iterator FindByFirstNFields( std::set<wxString>& strSet, const wxString& searchStr, char delimiter,
361 int n )
362{
363 wxString searchPrefix = searchStr;
364
365 // Extract first n fields from the search string
366 int delimiterCount = 0;
367 size_t pos = 0;
368
369 while( pos < searchPrefix.length() && delimiterCount < n )
370 {
371 if( searchPrefix[pos] == delimiter )
372 delimiterCount++;
373
374 pos++;
375 }
376
377 if( delimiterCount == n )
378 searchPrefix = searchPrefix.Left( pos - 1 ); // Exclude the nth delimiter
379
380 for( auto it = strSet.begin(); it != strSet.end(); ++it )
381 {
382 if( it->StartsWith( searchPrefix + delimiter ) || *it == searchPrefix )
383 return it;
384 }
385
386 return strSet.end();
387}
388
389std::vector<PCB_MARKER*> BOARD::ResolveDRCExclusions( bool aCreateMarkers )
390{
391 std::set<wxString> exclusions = m_designSettings->m_DrcExclusions;
392 std::map<wxString, wxString> comments = m_designSettings->m_DrcExclusionComments;
393
394 m_designSettings->m_DrcExclusions.clear();
395 m_designSettings->m_DrcExclusionComments.clear();
396
397 for( PCB_MARKER* marker : GetBoard()->Markers() )
398 {
399 std::set<wxString>::iterator it;
400 wxString serialized = marker->SerializeToString();
401 wxString matchedExclusion;
402
403 if( !serialized.Contains( "unconnected_items" ) )
404 {
405 it = exclusions.find( serialized );
406
407 if( it != exclusions.end() )
408 matchedExclusion = *it;
409 }
410 else
411 {
412 const int numberOfFieldsExcludingIds = 3;
413 const char delimiter = '|';
414 it = FindByFirstNFields( exclusions, serialized, delimiter, numberOfFieldsExcludingIds );
415
416 if( it != exclusions.end() )
417 matchedExclusion = *it;
418 }
419
420 if( it != exclusions.end() )
421 {
422 marker->SetExcluded( true, comments[matchedExclusion] );
423
424 // Exclusion still valid; store back to BOARD_DESIGN_SETTINGS
425 m_designSettings->m_DrcExclusions.insert( matchedExclusion );
426 m_designSettings->m_DrcExclusionComments[matchedExclusion] = comments[matchedExclusion];
427
428 exclusions.erase( it );
429 }
430 }
431
432 std::vector<PCB_MARKER*> newMarkers;
433
434 if( aCreateMarkers )
435 {
436 for( const wxString& serialized : exclusions )
437 {
438 PCB_MARKER* marker = PCB_MARKER::DeserializeFromString( serialized );
439
440 if( !marker )
441 continue;
442
443 std::vector<KIID> ids = marker->GetRCItem()->GetIDs();
444
445 int uuidCount = 0;
446
447 for( const KIID& uuid : ids )
448 {
449 if( uuidCount < 1 || uuid != niluuid )
450 {
451 if( !ResolveItem( uuid, true ) )
452 {
453 delete marker;
454 marker = nullptr;
455 break;
456 }
457 }
458 uuidCount++;
459 }
460
461 if( marker )
462 {
463 marker->SetExcluded( true, comments[ serialized ] );
464 newMarkers.push_back( marker );
465
466 // Exclusion still valid; store back to BOARD_DESIGN_SETTINGS
467 m_designSettings->m_DrcExclusions.insert( serialized );
468 m_designSettings->m_DrcExclusionComments[ serialized ] = comments[ serialized ];
469 }
470 }
471 }
472
473 return newMarkers;
474}
475
476
477void BOARD::GetContextualTextVars( wxArrayString* aVars ) const
478{
479 auto add =
480 [&]( const wxString& aVar )
481 {
482 if( !alg::contains( *aVars, aVar ) )
483 aVars->push_back( aVar );
484 };
485
486 add( wxT( "LAYER" ) );
487 add( wxT( "FILENAME" ) );
488 add( wxT( "FILEPATH" ) );
489 add( wxT( "PROJECTNAME" ) );
490 add( wxT( "DRC_ERROR <message_text>" ) );
491 add( wxT( "DRC_WARNING <message_text>" ) );
492
494
495 if( GetProject() )
496 {
497 for( std::pair<wxString, wxString> entry : GetProject()->GetTextVars() )
498 add( entry.first );
499 }
500}
501
502
503bool BOARD::ResolveTextVar( wxString* token, int aDepth ) const
504{
505 if( token->Contains( ':' ) )
506 {
507 wxString remainder;
508 wxString ref = token->BeforeFirst( ':', &remainder );
509 BOARD_ITEM* refItem = ResolveItem( KIID( ref ), true );
510
511 if( refItem && refItem->Type() == PCB_FOOTPRINT_T )
512 {
513 FOOTPRINT* refFP = static_cast<FOOTPRINT*>( refItem );
514
515 if( refFP->ResolveTextVar( &remainder, aDepth + 1 ) )
516 {
517 *token = std::move( remainder );
518 return true;
519 }
520 }
521 }
522
523 if( token->IsSameAs( wxT( "FILENAME" ) ) )
524 {
525 wxFileName fn( GetFileName() );
526 *token = fn.GetFullName();
527 return true;
528 }
529 else if( token->IsSameAs( wxT( "FILEPATH" ) ) )
530 {
531 wxFileName fn( GetFileName() );
532 *token = fn.GetFullPath();
533 return true;
534 }
535 else if( token->IsSameAs( wxT( "PROJECTNAME" ) ) && GetProject() )
536 {
537 *token = GetProject()->GetProjectName();
538 return true;
539 }
540
541 wxString var = *token;
542
543 if( m_properties.count( var ) )
544 {
545 *token = m_properties.at( var );
546 return true;
547 }
548 else if( GetTitleBlock().TextVarResolver( token, m_project ) )
549 {
550 return true;
551 }
552
553 if( GetProject() && GetProject()->TextVarResolver( token ) )
554 return true;
555
556 return false;
557}
558
559
560bool BOARD::IsEmpty() const
561{
562 return m_drawings.empty() && m_footprints.empty() && m_tracks.empty() && m_zones.empty() && m_points.empty();
563}
564
565
567{
568 return ZeroOffset;
569}
570
571
572void BOARD::SetPosition( const VECTOR2I& aPos )
573{
574 wxLogWarning( wxT( "This should not be called on the BOARD object") );
575}
576
577
578void BOARD::Move( const VECTOR2I& aMoveVector ) // overload
579{
580 INSPECTOR_FUNC inspector =
581 [&] ( EDA_ITEM* item, void* testData )
582 {
583 if( item->IsBOARD_ITEM() )
584 {
585 BOARD_ITEM* board_item = static_cast<BOARD_ITEM*>( item );
586
587 // aMoveVector was snapshotted, don't need "data".
588 // Only move the top level group
589 if( !board_item->GetParentGroup() && !board_item->GetParentFootprint() )
590 board_item->Move( aMoveVector );
591 }
592
594 };
595
596 Visit( inspector, nullptr, GENERAL_COLLECTOR::BoardLevelItems );
597}
598
599
600void BOARD::RunOnChildren( const std::function<void( BOARD_ITEM* )>& aFunction, RECURSE_MODE aMode ) const
601{
602 try
603 {
604 for( PCB_TRACK* track : m_tracks )
605 aFunction( track );
606
607 for( ZONE* zone : m_zones )
608 aFunction( zone );
609
610 for( PCB_MARKER* marker : m_markers )
611 aFunction( marker );
612
613 for( PCB_GROUP* group : m_groups )
614 aFunction( group );
615
616 for( PCB_POINT* point : m_points )
617 aFunction( point );
618
619 for( FOOTPRINT* footprint : m_footprints )
620 {
621 aFunction( footprint );
622
623 if( aMode == RECURSE_MODE::RECURSE )
624 footprint->RunOnChildren( aFunction, RECURSE_MODE::RECURSE );
625 }
626
627 for( BOARD_ITEM* drawing : m_drawings )
628 {
629 aFunction( drawing );
630
631 if( aMode == RECURSE_MODE::RECURSE )
632 drawing->RunOnChildren( aFunction, RECURSE_MODE::RECURSE );
633 }
634 }
635 catch( std::bad_function_call& )
636 {
637 wxFAIL_MSG( wxT( "Error running BOARD::RunOnChildren" ) );
638 }
639}
640
641
643{
644 TRACKS ret;
645
646 INSPECTOR_FUNC inspector = [aNetCode, &ret]( EDA_ITEM* item, void* testData )
647 {
648 PCB_TRACK* t = static_cast<PCB_TRACK*>( item );
649
650 if( t->GetNetCode() == aNetCode )
651 ret.push_back( t );
652
654 };
655
656 // visit this BOARD's PCB_TRACKs and PCB_VIAs with above TRACK INSPECTOR which
657 // appends all in aNetCode to ret.
658 Visit( inspector, nullptr, GENERAL_COLLECTOR::Tracks );
659
660 return ret;
661}
662
663
664bool BOARD::SetLayerDescr( PCB_LAYER_ID aIndex, const LAYER& aLayer )
665{
666 m_layers[ aIndex ] = aLayer;
668 return true;
669}
670
671
672PCB_LAYER_ID BOARD::GetLayerID( const wxString& aLayerName ) const
673{
674 // Check the BOARD physical layer names.
675 for( auto& [ layer_id, layer ] : m_layers )
676 {
677 if( layer.m_name == aLayerName || layer.m_userName == aLayerName )
678 return ToLAYER_ID( layer_id );
679 }
680
681 // Otherwise fall back to the system standard layer names for virtual layers.
682 for( int layer = 0; layer < PCB_LAYER_ID_COUNT; ++layer )
683 {
684 if( GetStandardLayerName( ToLAYER_ID( layer ) ) == aLayerName )
685 return ToLAYER_ID( layer );
686 }
687
688 return UNDEFINED_LAYER;
689}
690
691
692const wxString BOARD::GetLayerName( PCB_LAYER_ID aLayer ) const
693{
694 // All layer names are stored in the BOARD.
695 if( IsLayerEnabled( aLayer ) )
696 {
697 auto it = m_layers.find( aLayer );
698
699 // Standard names were set in BOARD::BOARD() but they may be over-ridden by
700 // BOARD::SetLayerName(). For copper layers, return the user defined layer name,
701 // if it was set. Otherwise return the Standard English layer name.
702 if( it != m_layers.end() && !it->second.m_userName.IsEmpty() )
703 return it->second.m_userName;
704 }
705
706 return GetStandardLayerName( aLayer );
707}
708
709
710bool BOARD::SetLayerName( PCB_LAYER_ID aLayer, const wxString& aLayerName )
711{
712 if( aLayerName.IsEmpty() )
713 {
714 // If the name is empty, we clear the user name.
715 m_layers[aLayer].m_userName.clear();
716 }
717 else
718 {
719 // no quote chars in the name allowed
720 if( aLayerName.Find( wxChar( '"' ) ) != wxNOT_FOUND )
721 return false;
722
723 if( IsLayerEnabled( aLayer ) )
724 {
725 m_layers[aLayer].m_userName = aLayerName;
727 return true;
728 }
729 }
730
731 return false;
732}
733
734
736{
737 return ::IsFrontLayer( aLayer ) || GetLayerType( aLayer ) == LT_FRONT;
738}
739
740
742{
743 return ::IsBackLayer( aLayer ) || GetLayerType( aLayer ) == LT_BACK;
744}
745
746
748{
749 if( IsLayerEnabled( aLayer ) )
750 {
751 auto it = m_layers.find( aLayer );
752
753 if( it != m_layers.end() )
754 return it->second.m_type;
755 }
756
757 if( aLayer >= User_1 && !IsCopperLayer( aLayer ) )
758 return LT_AUX;
759 else if( IsCopperLayer( aLayer ) )
760 return LT_SIGNAL;
761 else
762 return LT_UNDEFINED;
763}
764
765
766bool BOARD::SetLayerType( PCB_LAYER_ID aLayer, LAYER_T aLayerType )
767{
768 if( IsLayerEnabled( aLayer ) )
769 {
770 m_layers[aLayer].m_type = aLayerType;
772 return true;
773 }
774
775 return false;
776}
777
778
779const char* LAYER::ShowType( LAYER_T aType )
780{
781 switch( aType )
782 {
783 default:
784 case LT_SIGNAL: return "signal";
785 case LT_POWER: return "power";
786 case LT_MIXED: return "mixed";
787 case LT_JUMPER: return "jumper";
788 case LT_AUX: return "auxiliary";
789 case LT_FRONT: return "front";
790 case LT_BACK: return "back";
791 }
792}
793
794
795LAYER_T LAYER::ParseType( const char* aType )
796{
797 if( strcmp( aType, "signal" ) == 0 ) return LT_SIGNAL;
798 else if( strcmp( aType, "power" ) == 0 ) return LT_POWER;
799 else if( strcmp( aType, "mixed" ) == 0 ) return LT_MIXED;
800 else if( strcmp( aType, "jumper" ) == 0 ) return LT_JUMPER;
801 else if( strcmp( aType, "auxiliary" ) == 0 ) return LT_AUX;
802 else if( strcmp( aType, "front" ) == 0 ) return LT_FRONT;
803 else if( strcmp( aType, "back" ) == 0 ) return LT_BACK;
804 else return LT_UNDEFINED;
805}
806
807
809{
810 for( int layer = F_Cu; layer < PCB_LAYER_ID_COUNT; ++layer )
811 m_layers[layer].m_opposite = ::FlipLayer( ToLAYER_ID( layer ), GetCopperLayerCount() );
812
813 // Match up similary-named front/back user layers
814 for( int layer = User_1; layer <= PCB_LAYER_ID_COUNT; layer += 2 )
815 {
816 if( m_layers[layer].m_opposite != layer ) // already paired
817 continue;
818
819 if( m_layers[layer].m_type != LT_FRONT && m_layers[layer].m_type != LT_BACK )
820 continue;
821
822 wxString principalName = m_layers[layer].m_userName.AfterFirst( '.' );
823
824 for( int ii = layer + 2; ii <= PCB_LAYER_ID_COUNT; ii += 2 )
825 {
826 if( m_layers[ii].m_opposite != ii ) // already paired
827 continue;
828
829 if( m_layers[ii].m_type != LT_FRONT && m_layers[ii].m_type != LT_BACK )
830 continue;
831
832 if( m_layers[layer].m_type == m_layers[ii].m_type )
833 continue;
834
835 wxString candidate = m_layers[ii].m_userName.AfterFirst( '.' );
836
837 if( !candidate.IsEmpty() && candidate == principalName )
838 {
839 m_layers[layer].m_opposite = ii;
840 m_layers[ii].m_opposite = layer;
841 break;
842 }
843 }
844 }
845
846 // Match up non-custom-named consecutive front/back user layer pairs
847 for( int layer = User_1; layer < PCB_LAYER_ID_COUNT - 2; layer += 2 )
848 {
849 int next = layer + 2;
850
851 // ignore already-matched layers
852 if( m_layers[layer].m_opposite != layer || m_layers[next].m_opposite != next )
853 continue;
854
855 // ignore layer pairs that aren't consecutive front/back
856 if( m_layers[layer].m_type != LT_FRONT || m_layers[next].m_type != LT_BACK )
857 continue;
858
859 if( m_layers[layer].m_userName != m_layers[layer].m_name
860 && m_layers[next].m_userName != m_layers[next].m_name )
861 {
862 m_layers[layer].m_opposite = next;
863 m_layers[next].m_opposite = layer;
864 }
865 }
866}
867
868
870{
871 auto it = m_layers.find( aLayer );
872 return it == m_layers.end() ? aLayer : ToLAYER_ID( it->second.m_opposite );
873}
874
875
880
881
883{
885}
886
887
892
893
895{
897}
898
900{
901 int imax = GetCopperLayerCount();
902
903 // layers IDs are F_Cu, B_Cu, and even IDs values (imax values)
904 if( imax <= 2 ) // at least 2 layers are expected
905 return B_Cu;
906
907 // For a 4 layer, last ID is In2_Cu = 6 (IDs are 0, 2, 4, 6)
908 return static_cast<PCB_LAYER_ID>( (imax-1) * 2 );
909}
910
911
912int BOARD::LayerDepth( PCB_LAYER_ID aStartLayer, PCB_LAYER_ID aEndLayer ) const
913{
914 if( aStartLayer > aEndLayer )
915 std::swap( aStartLayer, aEndLayer );
916
917 if( aEndLayer == B_Cu )
918 aEndLayer = ToLAYER_ID( F_Cu + GetCopperLayerCount() - 1 );
919
920 return aEndLayer - aStartLayer;
921}
922
923
925{
927}
928
929
931{
932 // If there is no project, assume layer is visible always
933 return GetDesignSettings().IsLayerEnabled( aLayer )
934 && ( !m_project || m_project->GetLocalSettings().m_VisibleLayers[aLayer] );
935}
936
937
939{
940 return m_project ? m_project->GetLocalSettings().m_VisibleLayers : LSET::AllLayersMask();
941}
942
943
944void BOARD::SetEnabledLayers( const LSET& aLayerSet )
945{
946 GetDesignSettings().SetEnabledLayers( aLayerSet );
947}
948
949
951{
952 return GetDesignSettings().IsLayerEnabled( aLayer );
953}
954
955
956void BOARD::SetVisibleLayers( const LSET& aLayerSet )
957{
958 if( m_project )
959 m_project->GetLocalSettings().m_VisibleLayers = aLayerSet;
960}
961
962
964{
965 // Call SetElementVisibility for each item
966 // to ensure specific calculations that can be needed by some items,
967 // just changing the visibility flags could be not sufficient.
968 for( size_t i = 0; i < aSet.size(); i++ )
969 SetElementVisibility( GAL_LAYER_ID_START + static_cast<int>( i ), aSet[i] );
970}
971
972
974{
975 SetVisibleLayers( LSET().set() );
976
977 // Call SetElementVisibility for each item,
978 // to ensure specific calculations that can be needed by some items
980 SetElementVisibility( ii, true );
981}
982
983
985{
986 return m_project ? m_project->GetLocalSettings().m_VisibleItems : GAL_SET::DefaultVisible();
987}
988
989
991{
992 return !m_project || m_project->GetLocalSettings().m_VisibleItems[aLayer - GAL_LAYER_ID_START];
993}
994
995
996void BOARD::SetElementVisibility( GAL_LAYER_ID aLayer, bool isEnabled )
997{
998 if( m_project )
999 m_project->GetLocalSettings().m_VisibleItems.set( aLayer - GAL_LAYER_ID_START, isEnabled );
1000
1001 switch( aLayer )
1002 {
1003 case LAYER_RATSNEST:
1004 {
1005 // because we have a tool to show/hide ratsnest relative to a pad or a footprint
1006 // so the hide/show option is a per item selection
1007
1008 for( PCB_TRACK* track : Tracks() )
1009 track->SetLocalRatsnestVisible( isEnabled );
1010
1011 for( FOOTPRINT* footprint : Footprints() )
1012 {
1013 for( PAD* pad : footprint->Pads() )
1014 pad->SetLocalRatsnestVisible( isEnabled );
1015 }
1016
1017 for( ZONE* zone : Zones() )
1018 zone->SetLocalRatsnestVisible( isEnabled );
1019
1020 break;
1021 }
1022
1023 default:
1024 ;
1025 }
1026}
1027
1028
1030{
1031 switch( aLayer )
1032 {
1035 default: wxFAIL_MSG( wxT( "BOARD::IsModuleLayerVisible(): bad layer" ) ); return true;
1036 }
1037}
1038
1039
1040
1045
1046
1048{
1049 *m_designSettings = aSettings;
1050}
1051
1052
1054{
1055 if( !m_maxClearanceValue.has_value() )
1056 {
1057 std::unique_lock<std::shared_mutex> writeLock( m_CachesMutex );
1058
1059 int worstClearance = m_designSettings->GetBiggestClearanceValue();
1060
1061 for( ZONE* zone : m_zones )
1062 worstClearance = std::max( worstClearance, zone->GetLocalClearance().value() );
1063
1064 for( FOOTPRINT* footprint : m_footprints )
1065 {
1066 for( PAD* pad : footprint->Pads() )
1067 {
1068 std::optional<int> override = pad->GetClearanceOverrides( nullptr );
1069
1070 if( override.has_value() )
1071 worstClearance = std::max( worstClearance, override.value() );
1072 }
1073
1074 for( ZONE* zone : footprint->Zones() )
1075 worstClearance = std::max( worstClearance, zone->GetLocalClearance().value() );
1076 }
1077
1078 m_maxClearanceValue = worstClearance;
1079 }
1080
1081 return m_maxClearanceValue.value_or( 0 );
1082};
1083
1084
1085void BOARD::CacheTriangulation( PROGRESS_REPORTER* aReporter, const std::vector<ZONE*>& aZones )
1086{
1087 std::vector<ZONE*> zones = aZones;
1088
1089 if( zones.empty() )
1090 zones = m_zones;
1091
1092 if( zones.empty() )
1093 return;
1094
1095 if( aReporter )
1096 aReporter->Report( _( "Tessellating copper zones..." ) );
1097
1099 std::vector<std::future<size_t>> returns;
1100
1101 returns.reserve( zones.size() );
1102
1103 auto cache_zones =
1104 [aReporter]( ZONE* aZone ) -> size_t
1105 {
1106 if( aReporter && aReporter->IsCancelled() )
1107 return 0;
1108
1109 aZone->CacheTriangulation();
1110
1111 if( aReporter )
1112 aReporter->AdvanceProgress();
1113
1114 return 1;
1115 };
1116
1117 for( ZONE* zone : zones )
1118 returns.emplace_back( tp.submit_task( [cache_zones, zone] { return cache_zones( zone ); } ) );
1119
1120 // Finalize the triangulation threads
1121 for( const std::future<size_t>& ret : returns )
1122 {
1123 std::future_status status = ret.wait_for( std::chrono::milliseconds( 250 ) );
1124
1125 while( status != std::future_status::ready )
1126 {
1127 if( aReporter )
1128 aReporter->KeepRefreshing();
1129
1130 status = ret.wait_for( std::chrono::milliseconds( 250 ) );
1131 }
1132 }
1133}
1134
1135
1136void BOARD::RunOnNestedEmbeddedFiles( const std::function<void( EMBEDDED_FILES* )>& aFunction )
1137{
1138 for( FOOTPRINT* footprint : m_footprints )
1139 aFunction( footprint->GetEmbeddedFiles() );
1140}
1141
1142
1144{
1146 [&]( EMBEDDED_FILES* nested )
1147 {
1148 for( auto& [filename, embeddedFile] : nested->EmbeddedFileMap() )
1149 {
1151
1152 if( file )
1153 {
1154 embeddedFile->compressedEncodedData = file->compressedEncodedData;
1155 embeddedFile->decompressedData = file->decompressedData;
1156 embeddedFile->data_hash = file->data_hash;
1157 embeddedFile->is_valid = file->is_valid;
1158 }
1159 }
1160 } );
1161}
1162
1163
1164void BOARD::Add( BOARD_ITEM* aBoardItem, ADD_MODE aMode, bool aSkipConnectivity )
1165{
1166 if( aBoardItem == nullptr )
1167 {
1168 wxFAIL_MSG( wxT( "BOARD::Add() param error: aBoardItem nullptr" ) );
1169 return;
1170 }
1171
1172 m_itemByIdCache.insert( { aBoardItem->m_Uuid, aBoardItem } );
1173
1174 switch( aBoardItem->Type() )
1175 {
1176 case PCB_NETINFO_T:
1177 m_NetInfo.AppendNet( (NETINFO_ITEM*) aBoardItem );
1178 break;
1179
1180 // this one uses a vector
1181 case PCB_MARKER_T:
1182 m_markers.push_back( (PCB_MARKER*) aBoardItem );
1183 break;
1184
1185 // this one uses a vector
1186 case PCB_GROUP_T:
1187 m_groups.push_back( (PCB_GROUP*) aBoardItem );
1188 break;
1189
1190 // this one uses a vector
1191 case PCB_GENERATOR_T:
1192 m_generators.push_back( (PCB_GENERATOR*) aBoardItem );
1193 break;
1194
1195 // this one uses a vector
1196 case PCB_ZONE_T:
1197 m_zones.push_back( (ZONE*) aBoardItem );
1198 break;
1199
1200 case PCB_VIA_T:
1201 if( aMode == ADD_MODE::APPEND || aMode == ADD_MODE::BULK_APPEND )
1202 m_tracks.push_back( static_cast<PCB_VIA*>( aBoardItem ) );
1203 else
1204 m_tracks.push_front( static_cast<PCB_VIA*>( aBoardItem ) );
1205
1206 break;
1207
1208 case PCB_TRACE_T:
1209 case PCB_ARC_T:
1210 if( !IsCopperLayer( aBoardItem->GetLayer() ) )
1211 {
1212 // The only current known source of these is SWIG (KICAD-BY7, et al).
1213 // N.B. This inserts a small memory leak as we lose the track/via/arc.
1214 wxFAIL_MSG( wxString::Format( "BOARD::Add() Cannot place Track on non-copper layer: %d = %s",
1215 static_cast<int>( aBoardItem->GetLayer() ),
1216 GetLayerName( aBoardItem->GetLayer() ) ) );
1217 return;
1218 }
1219
1220 if( aMode == ADD_MODE::APPEND || aMode == ADD_MODE::BULK_APPEND )
1221 m_tracks.push_back( static_cast<PCB_TRACK*>( aBoardItem ) );
1222 else
1223 m_tracks.push_front( static_cast<PCB_TRACK*>( aBoardItem ) );
1224
1225 break;
1226
1227 case PCB_FOOTPRINT_T:
1228 {
1229 FOOTPRINT* footprint = static_cast<FOOTPRINT*>( aBoardItem );
1230
1231 if( aMode == ADD_MODE::APPEND || aMode == ADD_MODE::BULK_APPEND )
1232 m_footprints.push_back( footprint );
1233 else
1234 m_footprints.push_front( footprint );
1235
1236 footprint->RunOnChildren( [&]( BOARD_ITEM* aChild )
1237 {
1238 m_itemByIdCache.insert( { aChild->m_Uuid, aChild } );
1239 },
1241 break;
1242 }
1243
1244 case PCB_BARCODE_T:
1245 case PCB_DIM_ALIGNED_T:
1246 case PCB_DIM_CENTER_T:
1247 case PCB_DIM_RADIAL_T:
1249 case PCB_DIM_LEADER_T:
1250 case PCB_SHAPE_T:
1252 case PCB_FIELD_T:
1253 case PCB_TEXT_T:
1254 case PCB_TEXTBOX_T:
1255 case PCB_TABLE_T:
1256 case PCB_TARGET_T:
1257 {
1258 if( aMode == ADD_MODE::APPEND || aMode == ADD_MODE::BULK_APPEND )
1259 m_drawings.push_back( aBoardItem );
1260 else
1261 m_drawings.push_front( aBoardItem );
1262
1263 if( aBoardItem->Type() == PCB_TABLE_T )
1264 {
1265 PCB_TABLE* table = static_cast<PCB_TABLE*>( aBoardItem );
1266
1267 table->RunOnChildren( [&]( BOARD_ITEM* aChild )
1268 {
1269 m_itemByIdCache.insert( { aChild->m_Uuid, aChild } );
1270 },
1272 }
1273
1274 break;
1275 }
1276
1277 case PCB_POINT_T:
1278 // These aren't graphics as they have no physical presence
1279 m_points.push_back( static_cast<PCB_POINT*>( aBoardItem ) );
1280 break;
1281
1282 case PCB_TABLECELL_T:
1283 // Handled by parent table
1284 break;
1285
1286 default:
1287 wxFAIL_MSG( wxString::Format( wxT( "BOARD::Add() item type %s not handled" ),
1288 aBoardItem->GetClass() ) );
1289 return;
1290 }
1291
1292 aBoardItem->SetParent( this );
1293 aBoardItem->ClearEditFlags();
1294
1295 if( !aSkipConnectivity )
1296 m_connectivity->Add( aBoardItem );
1297
1298 if( aMode != ADD_MODE::BULK_INSERT && aMode != ADD_MODE::BULK_APPEND )
1300}
1301
1302
1303void BOARD::FinalizeBulkAdd( std::vector<BOARD_ITEM*>& aNewItems )
1304{
1306}
1307
1308
1309void BOARD::FinalizeBulkRemove( std::vector<BOARD_ITEM*>& aRemovedItems )
1310{
1311 InvokeListeners( &BOARD_LISTENER::OnBoardItemsRemoved, *this, aRemovedItems );
1312}
1313
1314
1316{
1317 for( int ii = (int) m_zones.size() - 1; ii >= 0; --ii )
1318 {
1319 ZONE* zone = m_zones[ii];
1320
1321 if( zone->IsTeardropArea() && zone->HasFlag( STRUCT_DELETED ) )
1322 {
1323 m_itemByIdCache.erase( zone->m_Uuid );
1324 m_zones.erase( m_zones.begin() + ii );
1325 m_connectivity->Remove( zone );
1326 aCommit.Removed( zone );
1327 }
1328 }
1329}
1330
1331
1332void BOARD::Remove( BOARD_ITEM* aBoardItem, REMOVE_MODE aRemoveMode )
1333{
1334 // find these calls and fix them! Don't send me no stinking' nullptr.
1335 wxASSERT( aBoardItem );
1336
1337 m_itemByIdCache.erase( aBoardItem->m_Uuid );
1338
1339 switch( aBoardItem->Type() )
1340 {
1341 case PCB_NETINFO_T:
1342 {
1343 NETINFO_ITEM* netItem = static_cast<NETINFO_ITEM*>( aBoardItem );
1344 NETINFO_ITEM* unconnected = m_NetInfo.GetNetItem( NETINFO_LIST::UNCONNECTED );
1345
1346 for( BOARD_CONNECTED_ITEM* boardItem : AllConnectedItems() )
1347 {
1348 if( boardItem->GetNet() == netItem )
1349 boardItem->SetNet( unconnected );
1350 }
1351
1352 m_NetInfo.RemoveNet( netItem );
1353 break;
1354 }
1355
1356 case PCB_MARKER_T:
1357 std::erase( m_markers, aBoardItem );
1358 break;
1359
1360 case PCB_GROUP_T:
1361 std::erase( m_groups, aBoardItem );
1362 break;
1363
1364 case PCB_ZONE_T:
1365 std::erase( m_zones, aBoardItem );
1366 break;
1367
1368 case PCB_POINT_T:
1369 std::erase( m_points, aBoardItem );
1370 break;
1371
1372 case PCB_GENERATOR_T:
1373 std::erase( m_generators, aBoardItem );
1374 break;
1375
1376 case PCB_FOOTPRINT_T:
1377 {
1378 std::erase( m_footprints, aBoardItem );
1379 FOOTPRINT* footprint = static_cast<FOOTPRINT*>( aBoardItem );
1380
1381 footprint->RunOnChildren( [&]( BOARD_ITEM* aChild )
1382 {
1383 m_itemByIdCache.erase( aChild->m_Uuid );
1384 },
1386
1387 break;
1388 }
1389
1390 case PCB_TRACE_T:
1391 case PCB_ARC_T:
1392 case PCB_VIA_T:
1393 std::erase( m_tracks, aBoardItem );
1394 break;
1395
1396 case PCB_BARCODE_T:
1397 case PCB_DIM_ALIGNED_T:
1398 case PCB_DIM_CENTER_T:
1399 case PCB_DIM_RADIAL_T:
1401 case PCB_DIM_LEADER_T:
1402 case PCB_SHAPE_T:
1404 case PCB_FIELD_T:
1405 case PCB_TEXT_T:
1406 case PCB_TEXTBOX_T:
1407 case PCB_TABLE_T:
1408 case PCB_TARGET_T:
1409 {
1410 std::erase( m_drawings, aBoardItem );
1411
1412 if( aBoardItem->Type() == PCB_TABLE_T )
1413 {
1414 PCB_TABLE* table = static_cast<PCB_TABLE*>( aBoardItem );
1415
1416 table->RunOnChildren( [&]( BOARD_ITEM* aChild )
1417 {
1418 m_itemByIdCache.erase( aChild->m_Uuid );
1419 },
1421 }
1422
1423 break;
1424 }
1425
1426 case PCB_TABLECELL_T:
1427 // Handled by parent table
1428 break;
1429
1430 // other types may use linked list
1431 default:
1432 wxFAIL_MSG( wxString::Format( wxT( "BOARD::Remove() item type %s not handled" ),
1433 aBoardItem->GetClass() ) );
1434 }
1435
1436 aBoardItem->SetFlags( STRUCT_DELETED );
1437
1438 m_connectivity->Remove( aBoardItem );
1439
1440 if( aRemoveMode != REMOVE_MODE::BULK )
1442}
1443
1444
1445void BOARD::RemoveAll( std::initializer_list<KICAD_T> aTypes )
1446{
1447 std::vector<BOARD_ITEM*> removed;
1448
1449 for( const KICAD_T& type : aTypes )
1450 {
1451 switch( type )
1452 {
1453 case PCB_NETINFO_T:
1454 for( NETINFO_ITEM* item : m_NetInfo )
1455 removed.emplace_back( item );
1456
1457 m_NetInfo.clear();
1458 break;
1459
1460 case PCB_MARKER_T:
1461 std::copy( m_markers.begin(), m_markers.end(), std::back_inserter( removed ) );
1462 m_markers.clear();
1463 break;
1464
1465 case PCB_GROUP_T:
1466 std::copy( m_groups.begin(), m_groups.end(), std::back_inserter( removed ) );
1467 m_groups.clear();
1468 break;
1469
1470 case PCB_POINT_T:
1471 std::copy( m_points.begin(), m_points.end(), std::back_inserter( removed ) );
1472 m_points.clear();
1473 break;
1474
1475 case PCB_ZONE_T:
1476 std::copy( m_zones.begin(), m_zones.end(), std::back_inserter( removed ) );
1477 m_zones.clear();
1478 break;
1479
1480 case PCB_GENERATOR_T:
1481 std::copy( m_generators.begin(), m_generators.end(), std::back_inserter( removed ) );
1482 m_generators.clear();
1483 break;
1484
1485 case PCB_FOOTPRINT_T:
1486 std::copy( m_footprints.begin(), m_footprints.end(), std::back_inserter( removed ) );
1487 m_footprints.clear();
1488 break;
1489
1490 case PCB_TRACE_T:
1491 std::copy( m_tracks.begin(), m_tracks.end(), std::back_inserter( removed ) );
1492 m_tracks.clear();
1493 break;
1494
1495 case PCB_ARC_T:
1496 case PCB_VIA_T:
1497 wxFAIL_MSG( wxT( "Use PCB_TRACE_T to remove all tracks, arcs, and vias" ) );
1498 break;
1499
1500 case PCB_SHAPE_T:
1501 std::copy( m_drawings.begin(), m_drawings.end(), std::back_inserter( removed ) );
1502 m_drawings.clear();
1503 break;
1504
1505 case PCB_DIM_ALIGNED_T:
1506 case PCB_DIM_CENTER_T:
1507 case PCB_DIM_RADIAL_T:
1509 case PCB_DIM_LEADER_T:
1511 case PCB_FIELD_T:
1512 case PCB_TEXT_T:
1513 case PCB_TEXTBOX_T:
1514 case PCB_TABLE_T:
1515 case PCB_TARGET_T:
1516 case PCB_BARCODE_T:
1517 wxFAIL_MSG( wxT( "Use PCB_SHAPE_T to remove all graphics and text" ) );
1518 break;
1519
1520 default:
1521 wxFAIL_MSG( wxT( "BOARD::RemoveAll() needs more ::Type() support" ) );
1522 }
1523 }
1524
1526
1527 FinalizeBulkRemove( removed );
1528}
1529
1530
1532{
1533 PCB_LAYER_COLLECTOR collector;
1534
1535 collector.SetLayerId( aLayer );
1537
1538 if( collector.GetCount() != 0 )
1539 {
1540 // Skip items owned by footprints and footprints when building
1541 // the actual list of removed layers: these items are not removed
1542 for( int i = 0; i < collector.GetCount(); i++ )
1543 {
1544 BOARD_ITEM* item = collector[i];
1545
1546 if( item->Type() == PCB_FOOTPRINT_T || item->GetParentFootprint() )
1547 continue;
1548
1549 // Vias are on multiple adjacent layers, but only the top and
1550 // the bottom layers are stored. So there are issues only if one
1551 // is on a removed layer
1552 if( item->Type() == PCB_VIA_T )
1553 {
1554 PCB_VIA* via = static_cast<PCB_VIA*>( item );
1555
1556 if( via->GetViaType() == VIATYPE::THROUGH )
1557 continue;
1558 else
1559 {
1560 PCB_LAYER_ID top_layer;
1561 PCB_LAYER_ID bottom_layer;
1562 via->LayerPair( &top_layer, &bottom_layer );
1563
1564 if( top_layer != aLayer && bottom_layer != aLayer )
1565 continue;
1566 }
1567 }
1568
1569 return true;
1570 }
1571 }
1572
1573 return false;
1574}
1575
1576
1578{
1579 bool modified = false;
1580 bool removedItemLayers = false;
1581 PCB_LAYER_COLLECTOR collector;
1582
1583 collector.SetLayerId( aLayer );
1585
1586 for( int i = 0; i < collector.GetCount(); i++ )
1587 {
1588 BOARD_ITEM* item = collector[i];
1589
1590 // Do not remove/change an item owned by a footprint
1591 if( item->GetParentFootprint() )
1592 continue;
1593
1594 // Do not remove footprints
1595 if( item->Type() == PCB_FOOTPRINT_T )
1596 continue;
1597
1598 // Note: vias are specific. They are only on copper layers, and
1599 // do not use a layer set, only store the copper top and the copper bottom.
1600 // So reinit the layer set does not work with vias
1601 if( item->Type() == PCB_VIA_T )
1602 {
1603 PCB_VIA* via = static_cast<PCB_VIA*>( item );
1604
1605 if( via->GetViaType() == VIATYPE::THROUGH )
1606 {
1607 removedItemLayers = true;
1608 continue;
1609 }
1610 else if( via->IsOnLayer( aLayer ) )
1611 {
1612 PCB_LAYER_ID top_layer;
1613 PCB_LAYER_ID bottom_layer;
1614 via->LayerPair( &top_layer, &bottom_layer );
1615
1616 if( top_layer == aLayer || bottom_layer == aLayer )
1617 {
1618 // blind/buried vias with a top or bottom layer on a removed layer
1619 // are removed. Perhaps one could just modify the top/bottom layer,
1620 // but I am not sure this is better.
1621 Remove( item );
1622 delete item;
1623 modified = true;
1624 }
1625
1626 removedItemLayers = true;
1627 }
1628 }
1629 else if( item->IsOnLayer( aLayer ) )
1630 {
1631 LSET layers = item->GetLayerSet();
1632
1633 layers.reset( aLayer );
1634
1635 if( layers.any() )
1636 {
1637 item->SetLayerSet( layers );
1638 }
1639 else
1640 {
1641 Remove( item );
1642 delete item;
1643 modified = true;
1644 }
1645
1646 removedItemLayers = true;
1647 }
1648 }
1649
1650 if( removedItemLayers )
1652
1653 return modified;
1654}
1655
1656
1657wxString BOARD::GetItemDescription( UNITS_PROVIDER* aUnitsProvider, bool aFull ) const
1658{
1659 return wxString::Format( _( "PCB" ) );
1660}
1661
1662
1664{
1665 INSPECTOR_FUNC inspector =
1666 [&]( EDA_ITEM* descendant, void* aTestData )
1667 {
1668 PCB_DIMENSION_BASE* dimension = static_cast<PCB_DIMENSION_BASE*>( descendant );
1669
1670 if( dimension->GetUnitsMode() == DIM_UNITS_MODE::AUTOMATIC )
1671 {
1672 dimension->UpdateUnits();
1673
1674 if( aView )
1675 aView->Update( dimension );
1676 }
1677
1679 };
1680
1681 aItem->Visit( inspector, nullptr, { PCB_DIM_ALIGNED_T,
1685 PCB_DIM_RADIAL_T } );
1686}
1687
1688
1690{
1691 for( PCB_MARKER* marker : m_markers )
1692 delete marker;
1693
1694 m_markers.clear();
1696}
1697
1698
1699void BOARD::DeleteMARKERs( bool aWarningsAndErrors, bool aExclusions )
1700{
1701 // Deleting lots of items from a vector can be very slow. Copy remaining items instead.
1702 std::vector<PCB_MARKER*> remaining;
1703
1704 for( PCB_MARKER* marker : m_markers )
1705 {
1706 if( ( marker->GetSeverity() == RPT_SEVERITY_EXCLUSION && aExclusions )
1707 || ( marker->GetSeverity() != RPT_SEVERITY_EXCLUSION && aWarningsAndErrors ) )
1708 {
1709 delete marker;
1710 }
1711 else
1712 {
1713 remaining.push_back( marker );
1714 }
1715 }
1716
1717 m_markers = std::move( remaining );
1719}
1720
1721
1723{
1724 for( FOOTPRINT* footprint : m_footprints )
1725 delete footprint;
1726
1727 m_footprints.clear();
1729}
1730
1731
1733{
1734 for( FOOTPRINT* footprint : m_footprints )
1735 footprint->SetParent( nullptr );
1736
1737 m_footprints.clear();
1739}
1740
1741
1742BOARD_ITEM* BOARD::ResolveItem( const KIID& aID, bool aAllowNullptrReturn ) const
1743{
1744 if( aID == niluuid )
1745 return nullptr;
1746
1747 if( m_itemByIdCache.count( aID ) )
1748 return m_itemByIdCache.at( aID );
1749
1750 // Main clients include highlighting, group undo/redo and DRC items. Since
1751 // everything but group undo/redo will be spread over all object types, we
1752 // might as well prioritize group undo/redo and search them first.
1753
1754 for( PCB_GROUP* group : m_groups )
1755 {
1756 if( group->m_Uuid == aID )
1757 return group;
1758 }
1759
1760 for( PCB_GENERATOR* generator : m_generators )
1761 {
1762 if( generator->m_Uuid == aID )
1763 return generator;
1764 }
1765
1766 for( PCB_TRACK* track : Tracks() )
1767 {
1768 if( track->m_Uuid == aID )
1769 return track;
1770 }
1771
1772 for( FOOTPRINT* footprint : Footprints() )
1773 {
1774 if( footprint->m_Uuid == aID )
1775 return footprint;
1776
1777 for( PAD* pad : footprint->Pads() )
1778 {
1779 if( pad->m_Uuid == aID )
1780 return pad;
1781 }
1782
1783 for( PCB_FIELD* field : footprint->GetFields() )
1784 {
1785 if( field && field->m_Uuid == aID )
1786 return field;
1787 }
1788
1789 for( BOARD_ITEM* drawing : footprint->GraphicalItems() )
1790 {
1791 if( drawing->m_Uuid == aID )
1792 return drawing;
1793 }
1794
1795 for( BOARD_ITEM* zone : footprint->Zones() )
1796 {
1797 if( zone->m_Uuid == aID )
1798 return zone;
1799 }
1800
1801 for( PCB_GROUP* group : footprint->Groups() )
1802 {
1803 if( group->m_Uuid == aID )
1804 return group;
1805 }
1806 }
1807
1808 for( ZONE* zone : Zones() )
1809 {
1810 if( zone->m_Uuid == aID )
1811 return zone;
1812 }
1813
1814 for( BOARD_ITEM* drawing : Drawings() )
1815 {
1816 if( drawing->Type() == PCB_TABLE_T )
1817 {
1818 for( PCB_TABLECELL* cell : static_cast<PCB_TABLE*>( drawing )->GetCells() )
1819 {
1820 if( cell->m_Uuid == aID )
1821 return drawing;
1822 }
1823 }
1824
1825 if( drawing->m_Uuid == aID )
1826 return drawing;
1827 }
1828
1829 for( PCB_MARKER* marker : m_markers )
1830 {
1831 if( marker->m_Uuid == aID )
1832 return marker;
1833 }
1834
1835 for( PCB_POINT* point : m_points )
1836 {
1837 if( point->m_Uuid == aID )
1838 return point;
1839 }
1840
1841 for( NETINFO_ITEM* netInfo : m_NetInfo )
1842 {
1843 if( netInfo->m_Uuid == aID )
1844 return netInfo;
1845 }
1846
1847 if( m_Uuid == aID )
1848 return const_cast<BOARD*>( this );
1849
1850 // Not found; weak reference has been deleted.
1851 if( aAllowNullptrReturn )
1852 return nullptr;
1853
1855}
1856
1857
1858void BOARD::FillItemMap( std::map<KIID, EDA_ITEM*>& aMap )
1859{
1860 // the board itself
1861 aMap[ m_Uuid ] = this;
1862
1863 for( PCB_TRACK* track : Tracks() )
1864 aMap[ track->m_Uuid ] = track;
1865
1866 for( FOOTPRINT* footprint : Footprints() )
1867 {
1868 aMap[ footprint->m_Uuid ] = footprint;
1869
1870 for( PAD* pad : footprint->Pads() )
1871 aMap[ pad->m_Uuid ] = pad;
1872
1873 aMap[ footprint->Reference().m_Uuid ] = &footprint->Reference();
1874 aMap[ footprint->Value().m_Uuid ] = &footprint->Value();
1875
1876 for( BOARD_ITEM* drawing : footprint->GraphicalItems() )
1877 aMap[ drawing->m_Uuid ] = drawing;
1878 }
1879
1880 for( ZONE* zone : Zones() )
1881 aMap[ zone->m_Uuid ] = zone;
1882
1883 for( BOARD_ITEM* drawing : Drawings() )
1884 aMap[ drawing->m_Uuid ] = drawing;
1885
1886 for( PCB_MARKER* marker : m_markers )
1887 aMap[ marker->m_Uuid ] = marker;
1888
1889 for( PCB_GROUP* group : m_groups )
1890 aMap[ group->m_Uuid ] = group;
1891
1892 for( PCB_POINT* point : m_points )
1893 aMap[ point->m_Uuid ] = point;
1894
1895 for( PCB_GENERATOR* generator : m_generators )
1896 aMap[ generator->m_Uuid ] = generator;
1897}
1898
1899
1900wxString BOARD::ConvertCrossReferencesToKIIDs( const wxString& aSource ) const
1901{
1902 wxString newbuf;
1903 size_t sourceLen = aSource.length();
1904
1905 for( size_t i = 0; i < sourceLen; ++i )
1906 {
1907 if( aSource[i] == '$' && i + 1 < sourceLen && aSource[i+1] == '{' )
1908 {
1909 wxString token;
1910 bool isCrossRef = false;
1911
1912 for( i = i + 2; i < sourceLen; ++i )
1913 {
1914 if( aSource[i] == '}' )
1915 break;
1916
1917 if( aSource[i] == ':' )
1918 isCrossRef = true;
1919
1920 token.append( aSource[i] );
1921 }
1922
1923 if( isCrossRef )
1924 {
1925 wxString remainder;
1926 wxString ref = token.BeforeFirst( ':', &remainder );
1927
1928 for( const FOOTPRINT* footprint : Footprints() )
1929 {
1930 if( footprint->GetReference().CmpNoCase( ref ) == 0 )
1931 {
1932 wxString test( remainder );
1933
1934 if( footprint->ResolveTextVar( &test ) )
1935 token = footprint->m_Uuid.AsString() + wxT( ":" ) + remainder;
1936
1937 break;
1938 }
1939 }
1940 }
1941
1942 newbuf.append( wxT( "${" ) + token + wxT( "}" ) );
1943 }
1944 else
1945 {
1946 newbuf.append( aSource[i] );
1947 }
1948 }
1949
1950 return newbuf;
1951}
1952
1953
1954wxString BOARD::ConvertKIIDsToCrossReferences( const wxString& aSource ) const
1955{
1956 wxString newbuf;
1957 size_t sourceLen = aSource.length();
1958
1959 for( size_t i = 0; i < sourceLen; ++i )
1960 {
1961 if( aSource[i] == '$' && i + 1 < sourceLen && aSource[i+1] == '{' )
1962 {
1963 wxString token;
1964 bool isCrossRef = false;
1965
1966 for( i = i + 2; i < sourceLen; ++i )
1967 {
1968 if( aSource[i] == '}' )
1969 break;
1970
1971 if( aSource[i] == ':' )
1972 isCrossRef = true;
1973
1974 token.append( aSource[i] );
1975 }
1976
1977 if( isCrossRef )
1978 {
1979 wxString remainder;
1980 wxString ref = token.BeforeFirst( ':', &remainder );
1981 BOARD_ITEM* refItem = ResolveItem( KIID( ref ), true );
1982
1983 if( refItem && refItem->Type() == PCB_FOOTPRINT_T )
1984 {
1985 token = static_cast<FOOTPRINT*>( refItem )->GetReference() + wxT( ":" )
1986 + remainder;
1987 }
1988 }
1989
1990 newbuf.append( wxT( "${" ) + token + wxT( "}" ) );
1991 }
1992 else
1993 {
1994 newbuf.append( aSource[i] );
1995 }
1996 }
1997
1998 return newbuf;
1999}
2000
2001
2002unsigned BOARD::GetNodesCount( int aNet ) const
2003{
2004 unsigned retval = 0;
2005
2006 for( FOOTPRINT* footprint : Footprints() )
2007 {
2008 for( PAD* pad : footprint->Pads() )
2009 {
2010 if( ( aNet == -1 && pad->GetNetCode() > 0 ) || aNet == pad->GetNetCode() )
2011 retval++;
2012 }
2013 }
2014
2015 return retval;
2016}
2017
2018
2019BOX2I BOARD::ComputeBoundingBox( bool aBoardEdgesOnly ) const
2020{
2021 BOX2I bbox;
2022 LSET visible = GetVisibleLayers();
2023
2024 // If the board is just showing a footprint, we want all footprint layers included in the
2025 // bounding box
2026 if( IsFootprintHolder() )
2027 visible.set();
2028
2029 if( aBoardEdgesOnly )
2030 visible.set( Edge_Cuts );
2031
2032 // Check shapes, dimensions, texts, and fiducials
2033 for( BOARD_ITEM* item : m_drawings )
2034 {
2035 if( aBoardEdgesOnly && ( item->GetLayer() != Edge_Cuts || item->Type() != PCB_SHAPE_T ) )
2036 continue;
2037
2038 if( ( item->GetLayerSet() & visible ).any() )
2039 bbox.Merge( item->GetBoundingBox() );
2040 }
2041
2042 // Check footprints
2043 for( FOOTPRINT* footprint : m_footprints )
2044 {
2045 if( aBoardEdgesOnly )
2046 {
2047 for( const BOARD_ITEM* edge : footprint->GraphicalItems() )
2048 {
2049 if( edge->GetLayer() == Edge_Cuts && edge->Type() == PCB_SHAPE_T )
2050 bbox.Merge( edge->GetBoundingBox() );
2051 }
2052 }
2053 else if( ( footprint->GetLayerSet() & visible ).any() )
2054 {
2055 bbox.Merge( footprint->GetBoundingBox( true ) );
2056 }
2057 }
2058
2059 if( !aBoardEdgesOnly )
2060 {
2061 // Check tracks
2062 for( PCB_TRACK* track : m_tracks )
2063 {
2064 if( ( track->GetLayerSet() & visible ).any() )
2065 bbox.Merge( track->GetBoundingBox() );
2066 }
2067
2068 // Check zones
2069 for( ZONE* aZone : m_zones )
2070 {
2071 if( ( aZone->GetLayerSet() & visible ).any() )
2072 bbox.Merge( aZone->GetBoundingBox() );
2073 }
2074
2075 for( PCB_POINT* point : m_points )
2076 {
2077 bbox.Merge( point->GetBoundingBox() );
2078 }
2079 }
2080
2081 return bbox;
2082}
2083
2084
2085void BOARD::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
2086{
2087 int padCount = 0;
2088 int viaCount = 0;
2089 int trackSegmentCount = 0;
2090 std::set<int> netCodes;
2091 int unconnected = GetConnectivity()->GetUnconnectedCount( true );
2092
2093 for( PCB_TRACK* item : m_tracks )
2094 {
2095 if( item->Type() == PCB_VIA_T )
2096 viaCount++;
2097 else
2098 trackSegmentCount++;
2099
2100 if( item->GetNetCode() > 0 )
2101 netCodes.insert( item->GetNetCode() );
2102 }
2103
2104 for( FOOTPRINT* footprint : Footprints() )
2105 {
2106 for( PAD* pad : footprint->Pads() )
2107 {
2108 padCount++;
2109
2110 if( pad->GetNetCode() > 0 )
2111 netCodes.insert( pad->GetNetCode() );
2112 }
2113 }
2114
2115 aList.emplace_back( _( "Pads" ), wxString::Format( wxT( "%d" ), padCount ) );
2116 aList.emplace_back( _( "Vias" ), wxString::Format( wxT( "%d" ), viaCount ) );
2117 aList.emplace_back( _( "Track Segments" ), wxString::Format( wxT( "%d" ), trackSegmentCount ) );
2118 aList.emplace_back( _( "Nets" ), wxString::Format( wxT( "%d" ), (int) netCodes.size() ) );
2119 aList.emplace_back( _( "Unrouted" ), wxString::Format( wxT( "%d" ), unconnected ) );
2120}
2121
2122
2123INSPECT_RESULT BOARD::Visit( INSPECTOR inspector, void* testData,
2124 const std::vector<KICAD_T>& scanTypes )
2125{
2126#if 0 && defined(DEBUG)
2127 std::cout << GetClass().mb_str() << ' ';
2128#endif
2129
2130 bool footprintsScanned = false;
2131 bool drawingsScanned = false;
2132 bool tracksScanned = false;
2133
2134 for( KICAD_T scanType : scanTypes )
2135 {
2136 switch( scanType )
2137 {
2138 case PCB_T:
2139 if( inspector( this, testData ) == INSPECT_RESULT::QUIT )
2140 return INSPECT_RESULT::QUIT;
2141
2142 break;
2143
2144 /*
2145 * Instances of the requested KICAD_T live in a list, either one that I manage, or one
2146 * that my footprints manage. If it's a type managed by class FOOTPRINT, then simply
2147 * pass it on to each footprint's Visit() function via IterateForward( m_footprints, ... ).
2148 */
2149
2150 case PCB_FOOTPRINT_T:
2151 case PCB_PAD_T:
2152 case PCB_SHAPE_T:
2154 case PCB_FIELD_T:
2155 case PCB_TEXT_T:
2156 case PCB_TEXTBOX_T:
2157 case PCB_TABLE_T:
2158 case PCB_TABLECELL_T:
2159 case PCB_DIM_ALIGNED_T:
2160 case PCB_DIM_CENTER_T:
2161 case PCB_DIM_RADIAL_T:
2163 case PCB_DIM_LEADER_T:
2164 case PCB_TARGET_T:
2165 case PCB_BARCODE_T:
2166 if( !footprintsScanned )
2167 {
2168 if( IterateForward<FOOTPRINT*>( m_footprints, inspector, testData, scanTypes )
2170 {
2171 return INSPECT_RESULT::QUIT;
2172 }
2173
2174 footprintsScanned = true;
2175 }
2176
2177 if( !drawingsScanned )
2178 {
2179 if( IterateForward<BOARD_ITEM*>( m_drawings, inspector, testData, scanTypes )
2181 {
2182 return INSPECT_RESULT::QUIT;
2183 }
2184
2185 drawingsScanned = true;
2186 }
2187
2188 break;
2189
2190 case PCB_VIA_T:
2191 case PCB_TRACE_T:
2192 case PCB_ARC_T:
2193 if( !tracksScanned )
2194 {
2195 if( IterateForward<PCB_TRACK*>( m_tracks, inspector, testData, scanTypes )
2197 {
2198 return INSPECT_RESULT::QUIT;
2199 }
2200
2201 tracksScanned = true;
2202 }
2203
2204 break;
2205
2206 case PCB_MARKER_T:
2207 for( PCB_MARKER* marker : m_markers )
2208 {
2209 if( marker->Visit( inspector, testData, { scanType } ) == INSPECT_RESULT::QUIT )
2210 return INSPECT_RESULT::QUIT;
2211 }
2212
2213 break;
2214
2215 case PCB_POINT_T:
2216 for( PCB_POINT* point : m_points )
2217 {
2218 if( point->Visit( inspector, testData, { scanType } ) == INSPECT_RESULT::QUIT )
2219 return INSPECT_RESULT::QUIT;
2220 }
2221
2222 break;
2223
2224 case PCB_ZONE_T:
2225 if( !footprintsScanned )
2226 {
2227 if( IterateForward<FOOTPRINT*>( m_footprints, inspector, testData, scanTypes )
2229 {
2230 return INSPECT_RESULT::QUIT;
2231 }
2232
2233 footprintsScanned = true;
2234 }
2235
2236 for( ZONE* zone : m_zones)
2237 {
2238 if( zone->Visit( inspector, testData, { scanType } ) == INSPECT_RESULT::QUIT )
2239 return INSPECT_RESULT::QUIT;
2240 }
2241
2242 break;
2243
2244 case PCB_GENERATOR_T:
2245 if( !footprintsScanned )
2246 {
2247 if( IterateForward<FOOTPRINT*>( m_footprints, inspector, testData, scanTypes )
2249 {
2250 return INSPECT_RESULT::QUIT;
2251 }
2252
2253 footprintsScanned = true;
2254 }
2255
2256 if( IterateForward<PCB_GENERATOR*>( m_generators, inspector, testData, { scanType } )
2258 {
2259 return INSPECT_RESULT::QUIT;
2260 }
2261
2262 break;
2263
2264 case PCB_GROUP_T:
2265 if( IterateForward<PCB_GROUP*>( m_groups, inspector, testData, { scanType } )
2267 {
2268 return INSPECT_RESULT::QUIT;
2269 }
2270
2271 break;
2272
2273 default:
2274 break;
2275 }
2276 }
2277
2279}
2280
2281
2282NETINFO_ITEM* BOARD::FindNet( int aNetcode ) const
2283{
2284 // the first valid netcode is 1 and the last is m_NetInfo.GetCount()-1.
2285 // zero is reserved for "no connection" and is not actually a net.
2286 // nullptr is returned for non valid netcodes
2287
2288 if( aNetcode == NETINFO_LIST::UNCONNECTED && m_NetInfo.GetNetCount() == 0 )
2290 else
2291 return m_NetInfo.GetNetItem( aNetcode );
2292}
2293
2294
2295NETINFO_ITEM* BOARD::FindNet( const wxString& aNetname ) const
2296{
2297 return m_NetInfo.GetNetItem( aNetname );
2298}
2299
2300
2301int BOARD::MatchDpSuffix( const wxString& aNetName, wxString& aComplementNet )
2302{
2303 int rv = 0;
2304 int count = 0;
2305
2306 for( auto it = aNetName.rbegin(); it != aNetName.rend() && rv == 0; ++it, ++count )
2307 {
2308 int ch = *it;
2309
2310 if( ( ch >= '0' && ch <= '9' ) || ch == '_' )
2311 {
2312 continue;
2313 }
2314 else if( ch == '+' )
2315 {
2316 aComplementNet = wxT( "-" );
2317 rv = 1;
2318 }
2319 else if( ch == '-' )
2320 {
2321 aComplementNet = wxT( "+" );
2322 rv = -1;
2323 }
2324 else if( ch == 'N' )
2325 {
2326 aComplementNet = wxT( "P" );
2327 rv = -1;
2328 }
2329 else if ( ch == 'P' )
2330 {
2331 aComplementNet = wxT( "N" );
2332 rv = 1;
2333 }
2334 else
2335 {
2336 break;
2337 }
2338 }
2339
2340 if( rv != 0 && count >= 1 )
2341 {
2342 aComplementNet = aNetName.Left( aNetName.length() - count )
2343 + aComplementNet
2344 + aNetName.Right( count - 1 );
2345 }
2346
2347 return rv;
2348}
2349
2350
2352{
2353 if( aNet )
2354 {
2355 wxString refName = aNet->GetNetname();
2356 wxString coupledNetName;
2357
2358 if( MatchDpSuffix( refName, coupledNetName ) )
2359 return FindNet( coupledNetName );
2360 }
2361
2362 return nullptr;
2363}
2364
2365
2366FOOTPRINT* BOARD::FindFootprintByReference( const wxString& aReference ) const
2367{
2368 for( FOOTPRINT* footprint : m_footprints )
2369 {
2370 if( aReference == footprint->GetReference() )
2371 return footprint;
2372 }
2373
2374 return nullptr;
2375}
2376
2377
2379{
2380 for( FOOTPRINT* footprint : m_footprints )
2381 {
2382 if( footprint->GetPath() == aPath )
2383 return footprint;
2384 }
2385
2386 return nullptr;
2387}
2388
2389
2391{
2392 std::set<wxString> names;
2393
2394 for( const NETINFO_ITEM* net : m_NetInfo )
2395 {
2396 if( !net->GetNetname().IsEmpty() )
2397 names.insert( net->GetNetname() );
2398 }
2399
2400 return names;
2401}
2402
2403
2405{
2406 if( m_project && !m_project->IsNullProject() )
2407 SetProperties( m_project->GetTextVars() );
2408}
2409
2410
2412{
2413 m_lengthDelayCalc->SynchronizeTimeDomainProperties();
2414}
2415
2416
2417void BOARD::SynchronizeNetsAndNetClasses( bool aResetTrackAndViaSizes )
2418{
2419 if( !m_project )
2420 return;
2421
2423 const std::shared_ptr<NETCLASS>& defaultNetClass = bds.m_NetSettings->GetDefaultNetclass();
2424
2426
2427 for( NETINFO_ITEM* net : m_NetInfo )
2428 net->SetNetClass( bds.m_NetSettings->GetEffectiveNetClass( net->GetNetname() ) );
2429
2430 if( aResetTrackAndViaSizes )
2431 {
2432 // Set initial values for custom track width & via size to match the default
2433 // netclass settings
2434 bds.UseCustomTrackViaSize( false );
2435 bds.SetCustomTrackWidth( defaultNetClass->GetTrackWidth() );
2436 bds.SetCustomViaSize( defaultNetClass->GetViaDiameter() );
2437 bds.SetCustomViaDrill( defaultNetClass->GetViaDrill() );
2438 bds.SetCustomDiffPairWidth( defaultNetClass->GetDiffPairWidth() );
2439 bds.SetCustomDiffPairGap( defaultNetClass->GetDiffPairGap() );
2440 bds.SetCustomDiffPairViaGap( defaultNetClass->GetDiffPairViaGap() );
2441 }
2442
2444}
2445
2446
2447bool BOARD::SynchronizeComponentClasses( const std::unordered_set<wxString>& aNewSheetPaths ) const
2448{
2449 std::shared_ptr<COMPONENT_CLASS_SETTINGS> settings =
2451
2452 return m_componentClassManager->SyncDynamicComponentClassAssignments(
2453 settings->GetComponentClassAssignments(), settings->GetEnableSheetComponentClasses(),
2454 aNewSheetPaths );
2455}
2456
2457
2459{
2460 int error_count = 0;
2461
2462 for( ZONE* zone : Zones() )
2463 {
2464 if( !zone->IsOnCopperLayer() )
2465 {
2466 zone->SetNetCode( NETINFO_LIST::UNCONNECTED );
2467 continue;
2468 }
2469
2470 if( zone->GetNetCode() != 0 ) // i.e. if this zone is connected to a net
2471 {
2472 const NETINFO_ITEM* net = zone->GetNet();
2473
2474 if( net )
2475 {
2476 zone->SetNetCode( net->GetNetCode() );
2477 }
2478 else
2479 {
2480 error_count++;
2481
2482 // keep Net Name and set m_NetCode to -1 : error flag.
2483 zone->SetNetCode( -1 );
2484 }
2485 }
2486 }
2487
2488 return error_count;
2489}
2490
2491
2492PAD* BOARD::GetPad( const VECTOR2I& aPosition, const LSET& aLayerSet ) const
2493{
2494 for( FOOTPRINT* footprint : m_footprints )
2495 {
2496 PAD* pad = nullptr;
2497
2498 if( footprint->HitTest( aPosition ) )
2499 pad = footprint->GetPad( aPosition, aLayerSet.any() ? aLayerSet : LSET::AllCuMask() );
2500
2501 if( pad )
2502 return pad;
2503 }
2504
2505 return nullptr;
2506}
2507
2508
2509PAD* BOARD::GetPad( const PCB_TRACK* aTrace, ENDPOINT_T aEndPoint ) const
2510{
2511 const VECTOR2I& aPosition = aTrace->GetEndPoint( aEndPoint );
2512
2513 LSET lset( { aTrace->GetLayer() } );
2514
2515 return GetPad( aPosition, lset );
2516}
2517
2518
2519PAD* BOARD::GetPad( std::vector<PAD*>& aPadList, const VECTOR2I& aPosition, const LSET& aLayerSet ) const
2520{
2521 // Search aPadList for aPosition
2522 // aPadList is sorted by X then Y values, and a fast binary search is used
2523 int idxmax = aPadList.size() - 1;
2524
2525 int delta = aPadList.size();
2526
2527 int idx = 0; // Starting index is the beginning of list
2528
2529 while( delta )
2530 {
2531 // Calculate half size of remaining interval to test.
2532 // Ensure the computed value is not truncated (too small)
2533 if( (delta & 1) && ( delta > 1 ) )
2534 delta++;
2535
2536 delta /= 2;
2537
2538 PAD* pad = aPadList[idx];
2539
2540 if( pad->GetPosition() == aPosition ) // candidate found
2541 {
2542 // The pad must match the layer mask:
2543 if( ( aLayerSet & pad->GetLayerSet() ).any() )
2544 return pad;
2545
2546 // More than one pad can be at aPosition
2547 // search for a pad at aPosition that matched this mask
2548
2549 // search next
2550 for( int ii = idx+1; ii <= idxmax; ii++ )
2551 {
2552 pad = aPadList[ii];
2553
2554 if( pad->GetPosition() != aPosition )
2555 break;
2556
2557 if( ( aLayerSet & pad->GetLayerSet() ).any() )
2558 return pad;
2559 }
2560 // search previous
2561 for( int ii = idx - 1 ;ii >=0; ii-- )
2562 {
2563 pad = aPadList[ii];
2564
2565 if( pad->GetPosition() != aPosition )
2566 break;
2567
2568 if( ( aLayerSet & pad->GetLayerSet() ).any() )
2569 return pad;
2570 }
2571
2572 // Not found:
2573 return nullptr;
2574 }
2575
2576 if( pad->GetPosition().x == aPosition.x ) // Must search considering Y coordinate
2577 {
2578 if( pad->GetPosition().y < aPosition.y ) // Must search after this item
2579 {
2580 idx += delta;
2581
2582 if( idx > idxmax )
2583 idx = idxmax;
2584 }
2585 else // Must search before this item
2586 {
2587 idx -= delta;
2588
2589 if( idx < 0 )
2590 idx = 0;
2591 }
2592 }
2593 else if( pad->GetPosition().x < aPosition.x ) // Must search after this item
2594 {
2595 idx += delta;
2596
2597 if( idx > idxmax )
2598 idx = idxmax;
2599 }
2600 else // Must search before this item
2601 {
2602 idx -= delta;
2603
2604 if( idx < 0 )
2605 idx = 0;
2606 }
2607 }
2608
2609 return nullptr;
2610}
2611
2612
2618bool sortPadsByXthenYCoord( PAD* const & aLH, PAD* const & aRH )
2619{
2620 if( aLH->GetPosition().x == aRH->GetPosition().x )
2621 return aLH->GetPosition().y < aRH->GetPosition().y;
2622
2623 return aLH->GetPosition().x < aRH->GetPosition().x;
2624}
2625
2626
2627void BOARD::GetSortedPadListByXthenYCoord( std::vector<PAD*>& aVector, int aNetCode ) const
2628{
2629 for( FOOTPRINT* footprint : Footprints() )
2630 {
2631 for( PAD* pad : footprint->Pads( ) )
2632 {
2633 if( aNetCode < 0 || pad->GetNetCode() == aNetCode )
2634 aVector.push_back( pad );
2635 }
2636 }
2637
2638 std::sort( aVector.begin(), aVector.end(), sortPadsByXthenYCoord );
2639}
2640
2641
2643{
2644 if( GetDesignSettings().m_HasStackup )
2646
2647 BOARD_STACKUP stackup;
2649 return stackup;
2650}
2651
2652
2653std::tuple<int, double, double, double, double> BOARD::GetTrackLength( const PCB_TRACK& aTrack ) const
2654{
2655 std::shared_ptr<CONNECTIVITY_DATA> connectivity = GetBoard()->GetConnectivity();
2656 std::vector<LENGTH_DELAY_CALCULATION_ITEM> items;
2657
2658 for( BOARD_CONNECTED_ITEM* boardItem : connectivity->GetConnectedItems( &aTrack, EXCLUDE_ZONES ) )
2659 {
2661
2662 if( item.Type() != LENGTH_DELAY_CALCULATION_ITEM::TYPE::UNKNOWN )
2663 items.push_back( std::move( item ) );
2664 }
2665
2666 constexpr PATH_OPTIMISATIONS opts = {
2667 .OptimiseViaLayers = true, .MergeTracks = true, .OptimiseTracesInPads = true, .InferViaInPad = false
2668 };
2670 items, opts, nullptr, nullptr, LENGTH_DELAY_LAYER_OPT::NO_LAYER_DETAIL,
2672
2673 return std::make_tuple( items.size(), details.TrackLength + details.ViaLength, details.PadToDieLength,
2674 details.TrackDelay + details.ViaDelay, details.PadToDieDelay );
2675}
2676
2677
2678FOOTPRINT* BOARD::GetFootprint( const VECTOR2I& aPosition, PCB_LAYER_ID aActiveLayer,
2679 bool aVisibleOnly, bool aIgnoreLocked ) const
2680{
2681 FOOTPRINT* footprint = nullptr;
2682 FOOTPRINT* alt_footprint = nullptr;
2683 int min_dim = 0x7FFFFFFF;
2684 int alt_min_dim = 0x7FFFFFFF;
2685 bool current_layer_back = IsBackLayer( aActiveLayer );
2686
2687 for( FOOTPRINT* candidate : m_footprints )
2688 {
2689 // is the ref point within the footprint's bounds?
2690 if( !candidate->HitTest( aPosition ) )
2691 continue;
2692
2693 // if caller wants to ignore locked footprints, and this one is locked, skip it.
2694 if( aIgnoreLocked && candidate->IsLocked() )
2695 continue;
2696
2697 PCB_LAYER_ID layer = candidate->GetLayer();
2698
2699 // Filter non visible footprints if requested
2700 if( !aVisibleOnly || IsFootprintLayerVisible( layer ) )
2701 {
2702 BOX2I bb = candidate->GetBoundingBox( false );
2703
2704 int offx = bb.GetX() + bb.GetWidth() / 2;
2705 int offy = bb.GetY() + bb.GetHeight() / 2;
2706
2707 // off x & offy point to the middle of the box.
2708 int dist = ( aPosition.x - offx ) * ( aPosition.x - offx ) +
2709 ( aPosition.y - offy ) * ( aPosition.y - offy );
2710
2711 if( current_layer_back == IsBackLayer( layer ) )
2712 {
2713 if( dist <= min_dim )
2714 {
2715 // better footprint shown on the active side
2716 footprint = candidate;
2717 min_dim = dist;
2718 }
2719 }
2720 else if( aVisibleOnly && IsFootprintLayerVisible( layer ) )
2721 {
2722 if( dist <= alt_min_dim )
2723 {
2724 // better footprint shown on the other side
2725 alt_footprint = candidate;
2726 alt_min_dim = dist;
2727 }
2728 }
2729 }
2730 }
2731
2732 if( footprint )
2733 return footprint;
2734
2735 if( alt_footprint)
2736 return alt_footprint;
2737
2738 return nullptr;
2739}
2740
2741
2742std::list<ZONE*> BOARD::GetZoneList( bool aIncludeZonesInFootprints ) const
2743{
2744 std::list<ZONE*> zones;
2745
2746 for( ZONE* zone : Zones() )
2747 zones.push_back( zone );
2748
2749 if( aIncludeZonesInFootprints )
2750 {
2751 for( FOOTPRINT* footprint : m_footprints )
2752 {
2753 for( ZONE* zone : footprint->Zones() )
2754 zones.push_back( zone );
2755 }
2756 }
2757
2758 return zones;
2759}
2760
2761
2762ZONE* BOARD::AddArea( PICKED_ITEMS_LIST* aNewZonesList, int aNetcode, PCB_LAYER_ID aLayer,
2763 VECTOR2I aStartPointPosition, ZONE_BORDER_DISPLAY_STYLE aHatch )
2764{
2765 ZONE* new_area = new ZONE( this );
2766
2767 new_area->SetNetCode( aNetcode );
2768 new_area->SetLayer( aLayer );
2769
2770 m_zones.push_back( new_area );
2771
2772 new_area->SetHatchStyle( (ZONE_BORDER_DISPLAY_STYLE) aHatch );
2773
2774 // Add the first corner to the new zone
2775 new_area->AppendCorner( aStartPointPosition, -1 );
2776
2777 if( aNewZonesList )
2778 {
2779 ITEM_PICKER picker( nullptr, new_area, UNDO_REDO::NEWITEM );
2780 aNewZonesList->PushItem( picker );
2781 }
2782
2783 return new_area;
2784}
2785
2786
2788 OUTLINE_ERROR_HANDLER* aErrorHandler,
2789 bool aAllowUseArcsInPolygons,
2790 bool aIncludeNPTHAsOutlines )
2791{
2792 // max dist from one endPt to next startPt: use the current value
2793 int chainingEpsilon = GetOutlinesChainingEpsilon();
2794
2795 bool success = BuildBoardPolygonOutlines( this, aOutlines, GetDesignSettings().m_MaxError,
2796 chainingEpsilon, aErrorHandler,
2797 aAllowUseArcsInPolygons );
2798
2799 // Now add NPTH oval holes as holes in outlines if required
2800 if( aIncludeNPTHAsOutlines )
2801 {
2802 for( FOOTPRINT* fp : Footprints() )
2803 {
2804 for( PAD* pad : fp->Pads() )
2805 {
2806 if( pad->GetAttribute () != PAD_ATTRIB::NPTH )
2807 continue;
2808
2809 SHAPE_POLY_SET hole;
2810 pad->TransformHoleToPolygon( hole, 0, pad->GetMaxError(), ERROR_INSIDE );
2811
2812 if( hole.OutlineCount() > 0 ) // can be not the case for malformed NPTH holes
2813 {
2814 // Add this pad hole to the main outline
2815 // But we can have more than one main outline (i.e. more than one board), so
2816 // search the right main outline i.e. the outline that contains the pad hole
2817 SHAPE_LINE_CHAIN& pad_hole = hole.Outline( 0 );
2818 const VECTOR2I holePt = pad_hole.CPoint( 0 );
2819
2820 for( int jj = 0; jj < aOutlines.OutlineCount(); ++jj )
2821 {
2822 if( aOutlines.Outline( jj ).PointInside( holePt ) )
2823 {
2824 aOutlines.AddHole( pad_hole, jj );
2825 break;
2826 }
2827 }
2828 }
2829 }
2830 }
2831 }
2832
2833 // Make polygon strictly simple to avoid issues (especially in 3D viewer)
2834 aOutlines.Simplify();
2835
2836 return success;
2837}
2838
2839
2841{
2843 return static_cast<EMBEDDED_FILES*>( m_embeddedFilesDelegate );
2844
2845 return static_cast<EMBEDDED_FILES*>( this );
2846}
2847
2848
2850{
2852 return static_cast<const EMBEDDED_FILES*>( m_embeddedFilesDelegate );
2853
2854 return static_cast<const EMBEDDED_FILES*>( this );
2855}
2856
2857
2858std::set<KIFONT::OUTLINE_FONT*> BOARD::GetFonts() const
2859{
2861
2862 std::set<KIFONT::OUTLINE_FONT*> fonts;
2863
2864 for( BOARD_ITEM* item : Drawings() )
2865 {
2866 if( EDA_TEXT* text = dynamic_cast<EDA_TEXT*>( item ) )
2867 {
2868 KIFONT::FONT* font = text->GetFont();
2869
2870 if( font && font->IsOutline() )
2871 {
2872 KIFONT::OUTLINE_FONT* outlineFont = static_cast<KIFONT::OUTLINE_FONT*>( font );
2873 PERMISSION permission = outlineFont->GetEmbeddingPermission();
2874
2875 if( permission == PERMISSION::EDITABLE || permission == PERMISSION::INSTALLABLE )
2876 fonts.insert( outlineFont );
2877 }
2878 }
2879 }
2880
2881 return fonts;
2882}
2883
2884
2886{
2887 for( KIFONT::OUTLINE_FONT* font : GetFonts() )
2888 {
2889 EMBEDDED_FILES::EMBEDDED_FILE* file = GetEmbeddedFiles()->AddFile( font->GetFileName(), false );
2891 }
2892}
2893
2894
2895const std::vector<PAD*> BOARD::GetPads() const
2896{
2897 std::vector<PAD*> allPads;
2898
2899 for( FOOTPRINT* footprint : Footprints() )
2900 {
2901 for( PAD* pad : footprint->Pads() )
2902 allPads.push_back( pad );
2903 }
2904
2905 return allPads;
2906}
2907
2908
2909const std::vector<BOARD_CONNECTED_ITEM*> BOARD::AllConnectedItems()
2910{
2911 std::vector<BOARD_CONNECTED_ITEM*> items;
2912
2913 for( PCB_TRACK* track : Tracks() )
2914 items.push_back( track );
2915
2916 for( FOOTPRINT* footprint : Footprints() )
2917 {
2918 for( PAD* pad : footprint->Pads() )
2919 items.push_back( pad );
2920 }
2921
2922 for( ZONE* zone : Zones() )
2923 items.push_back( zone );
2924
2925 for( BOARD_ITEM* item : Drawings() )
2926 {
2927 if( BOARD_CONNECTED_ITEM* bci = dynamic_cast<BOARD_CONNECTED_ITEM*>( item ) )
2928 items.push_back( bci );
2929 }
2930
2931 return items;
2932}
2933
2934
2935void BOARD::MapNets( BOARD* aDestBoard )
2936{
2938 {
2939 NETINFO_ITEM* netInfo = aDestBoard->FindNet( item->GetNetname() );
2940
2941 if( netInfo )
2942 item->SetNet( netInfo );
2943 else
2944 {
2945 NETINFO_ITEM* newNet = new NETINFO_ITEM( aDestBoard, item->GetNetname() );
2946 aDestBoard->Add( newNet );
2947 item->SetNet( newNet );
2948
2949 }
2950 }
2951}
2952
2953
2955{
2956 for ( BOARD_CONNECTED_ITEM* item : AllConnectedItems() )
2957 {
2958 if( FindNet( item->GetNetCode() ) == nullptr )
2959 item->SetNetCode( NETINFO_LIST::ORPHANED );
2960 }
2961}
2962
2963
2965{
2966 if( !alg::contains( m_listeners, aListener ) )
2967 m_listeners.push_back( aListener );
2968}
2969
2970
2972{
2973 auto i = std::find( m_listeners.begin(), m_listeners.end(), aListener );
2974
2975 if( i != m_listeners.end() )
2976 {
2977 std::iter_swap( i, m_listeners.end() - 1 );
2978 m_listeners.pop_back();
2979 }
2980}
2981
2982
2984{
2985 m_listeners.clear();
2986}
2987
2988
2993
2994
2995void BOARD::OnItemsChanged( std::vector<BOARD_ITEM*>& aItems )
2996{
2998}
2999
3000
3001void BOARD::OnItemsCompositeUpdate( std::vector<BOARD_ITEM*>& aAddedItems,
3002 std::vector<BOARD_ITEM*>& aRemovedItems,
3003 std::vector<BOARD_ITEM*>& aChangedItems )
3004{
3005 InvokeListeners( &BOARD_LISTENER::OnBoardCompositeUpdate, *this, aAddedItems, aRemovedItems,
3006 aChangedItems );
3007}
3008
3009
3014
3015
3023
3024
3025void BOARD::SetHighLightNet( int aNetCode, bool aMulti )
3026{
3027 if( !m_highLight.m_netCodes.count( aNetCode ) )
3028 {
3029 if( !aMulti )
3030 m_highLight.m_netCodes.clear();
3031
3032 m_highLight.m_netCodes.insert( aNetCode );
3034 }
3035}
3036
3037
3038void BOARD::HighLightON( bool aValue )
3039{
3040 if( m_highLight.m_highLightOn != aValue )
3041 {
3042 m_highLight.m_highLightOn = aValue;
3044 }
3045}
3046
3047
3048wxString BOARD::GroupsSanityCheck( bool repair )
3049{
3050 if( repair )
3051 {
3052 while( GroupsSanityCheckInternal( repair ) != wxEmptyString )
3053 {};
3054
3055 return wxEmptyString;
3056 }
3057 return GroupsSanityCheckInternal( repair );
3058}
3059
3060
3062{
3063 // Cycle detection
3064 //
3065 // Each group has at most one parent group.
3066 // So we start at group 0 and traverse the parent chain, marking groups seen along the way.
3067 // If we ever see a group that we've already marked, that's a cycle.
3068 // If we reach the end of the chain, we know all groups in that chain are not part of any cycle.
3069 //
3070 // Algorithm below is linear in the # of groups because each group is visited only once.
3071 // There may be extra time taken due to the container access calls and iterators.
3072 //
3073 // Groups we know are cycle free
3074 std::unordered_set<EDA_GROUP*> knownCycleFreeGroups;
3075 // Groups in the current chain we're exploring.
3076 std::unordered_set<EDA_GROUP*> currentChainGroups;
3077 // Groups we haven't checked yet.
3078 std::unordered_set<EDA_GROUP*> toCheckGroups;
3079
3080 // Initialize set of groups and generators to check that could participate in a cycle.
3081 for( PCB_GROUP* group : Groups() )
3082 toCheckGroups.insert( group );
3083
3084 for( PCB_GENERATOR* gen : Generators() )
3085 toCheckGroups.insert( gen );
3086
3087 while( !toCheckGroups.empty() )
3088 {
3089 currentChainGroups.clear();
3090 EDA_GROUP* group = *toCheckGroups.begin();
3091
3092 while( true )
3093 {
3094 if( currentChainGroups.find( group ) != currentChainGroups.end() )
3095 {
3096 if( repair )
3097 Remove( static_cast<BOARD_ITEM*>( group->AsEdaItem() ) );
3098
3099 return "Cycle detected in group membership";
3100 }
3101 else if( knownCycleFreeGroups.find( group ) != knownCycleFreeGroups.end() )
3102 {
3103 // Parent is a group we know does not lead to a cycle
3104 break;
3105 }
3106
3107 currentChainGroups.insert( group );
3108 // We haven't visited currIdx yet, so it must be in toCheckGroups
3109 toCheckGroups.erase( group );
3110
3111 group = group->AsEdaItem()->GetParentGroup();
3112
3113 if( !group )
3114 {
3115 // end of chain and no cycles found in this chain
3116 break;
3117 }
3118 }
3119
3120 // No cycles found in chain, so add it to set of groups we know don't participate
3121 // in a cycle.
3122 knownCycleFreeGroups.insert( currentChainGroups.begin(), currentChainGroups.end() );
3123 }
3124
3125 // Success
3126 return "";
3127}
3128
3129
3131{
3132 if( a->Type() != b->Type() )
3133 return a->Type() < b->Type();
3134
3135 if( a->GetLayer() != b->GetLayer() )
3136 return a->GetLayer() < b->GetLayer();
3137
3138 if( a->GetPosition().x != b->GetPosition().x )
3139 return a->GetPosition().x < b->GetPosition().x;
3140
3141 if( a->GetPosition().y != b->GetPosition().y )
3142 return a->GetPosition().y < b->GetPosition().y;
3143
3144 if( a->m_Uuid != b->m_Uuid ) // shopuld be always the case foer valid boards
3145 return a->m_Uuid < b->m_Uuid;
3146
3147 return a < b;
3148}
3149
3150
3152 const BOARD_ITEM* aSecond ) const
3153{
3154 if( aFirst->Type() != aSecond->Type() )
3155 return aFirst->Type() < aSecond->Type();
3156
3157 if( aFirst->GetLayer() != aSecond->GetLayer() )
3158 return aFirst->GetLayer() < aSecond->GetLayer();
3159
3160 if( aFirst->Type() == PCB_SHAPE_T )
3161 {
3162 const PCB_SHAPE* shape = static_cast<const PCB_SHAPE*>( aFirst );
3163 const PCB_SHAPE* other = static_cast<const PCB_SHAPE*>( aSecond );
3164 return shape->Compare( other );
3165 }
3166 else if( aFirst->Type() == PCB_TEXT_T || aFirst->Type() == PCB_FIELD_T )
3167 {
3168 const PCB_TEXT* text = static_cast<const PCB_TEXT*>( aFirst );
3169 const PCB_TEXT* other = static_cast<const PCB_TEXT*>( aSecond );
3170 return text->Compare( other );
3171 }
3172 else if( aFirst->Type() == PCB_TEXTBOX_T )
3173 {
3174 const PCB_TEXTBOX* textbox = static_cast<const PCB_TEXTBOX*>( aFirst );
3175 const PCB_TEXTBOX* other = static_cast<const PCB_TEXTBOX*>( aSecond );
3176
3177 return textbox->PCB_SHAPE::Compare( other ) && textbox->EDA_TEXT::Compare( other );
3178 }
3179 else if( aFirst->Type() == PCB_TABLE_T )
3180 {
3181 const PCB_TABLE* table = static_cast<const PCB_TABLE*>( aFirst );
3182 const PCB_TABLE* other = static_cast<const PCB_TABLE*>( aSecond );
3183
3184 return PCB_TABLE::Compare( table, other );
3185 }
3186 else if( aFirst->Type() == PCB_BARCODE_T )
3187 {
3188 const PCB_BARCODE* barcode = static_cast<const PCB_BARCODE*>( aFirst );
3189 const PCB_BARCODE* other = static_cast<const PCB_BARCODE*>( aSecond );
3190
3191 return PCB_BARCODE::Compare( barcode, other );
3192 }
3193
3194 return aFirst->m_Uuid < aSecond->m_Uuid;
3195}
3196
3197
3199 SHAPE_POLY_SET& aOutlines,
3200 KIGFX::RENDER_SETTINGS* aRenderSettings ) const
3201{
3202 int maxError = GetDesignSettings().m_MaxError;
3203
3204 // convert tracks and vias:
3205 for( const PCB_TRACK* track : m_tracks )
3206 {
3207 if( !track->IsOnLayer( aLayer ) )
3208 continue;
3209
3210 track->TransformShapeToPolygon( aOutlines, aLayer, 0, maxError, ERROR_INSIDE );
3211 }
3212
3213 // convert pads and other copper items in footprints
3214 for( const FOOTPRINT* footprint : m_footprints )
3215 {
3216 footprint->TransformPadsToPolySet( aOutlines, aLayer, 0, maxError, ERROR_INSIDE );
3217
3218 footprint->TransformFPShapesToPolySet( aOutlines, aLayer, 0, maxError, ERROR_INSIDE,
3219 true, /* include text */
3220 true, /* include shapes */
3221 false /* include private items */ );
3222
3223 for( const ZONE* zone : footprint->Zones() )
3224 {
3225 if( zone->GetLayerSet().test( aLayer ) )
3226 zone->TransformSolidAreasShapesToPolygon( aLayer, aOutlines );
3227 }
3228 }
3229
3230 // convert copper zones
3231 for( const ZONE* zone : Zones() )
3232 {
3233 if( zone->GetLayerSet().test( aLayer ) )
3234 zone->TransformSolidAreasShapesToPolygon( aLayer, aOutlines );
3235 }
3236
3237 // convert graphic items on copper layers (texts)
3238 for( const BOARD_ITEM* item : m_drawings )
3239 {
3240 if( !item->IsOnLayer( aLayer ) )
3241 continue;
3242
3243 switch( item->Type() )
3244 {
3245 case PCB_SHAPE_T:
3246 {
3247 const PCB_SHAPE* shape = static_cast<const PCB_SHAPE*>( item );
3248 shape->TransformShapeToPolygon( aOutlines, aLayer, 0, maxError, ERROR_INSIDE );
3249 break;
3250 }
3251
3252 case PCB_BARCODE_T:
3253 {
3254 const PCB_BARCODE* barcode = static_cast<const PCB_BARCODE*>( item );
3255 barcode->TransformShapeToPolygon( aOutlines, aLayer, 0, maxError, ERROR_INSIDE );
3256 break;
3257 }
3258
3259 case PCB_FIELD_T:
3260 case PCB_TEXT_T:
3261 {
3262 const PCB_TEXT* text = static_cast<const PCB_TEXT*>( item );
3263 text->TransformTextToPolySet( aOutlines, 0, maxError, ERROR_INSIDE );
3264 break;
3265 }
3266
3267 case PCB_TEXTBOX_T:
3268 {
3269 const PCB_TEXTBOX* textbox = static_cast<const PCB_TEXTBOX*>( item );
3270 // border
3271 textbox->PCB_SHAPE::TransformShapeToPolygon( aOutlines, aLayer, 0, maxError, ERROR_INSIDE );
3272 // text
3273 textbox->TransformTextToPolySet( aOutlines, 0, maxError, ERROR_INSIDE );
3274 break;
3275 }
3276
3277 case PCB_TABLE_T:
3278 {
3279 const PCB_TABLE* table = static_cast<const PCB_TABLE*>( item );
3280 table->TransformGraphicItemsToPolySet( aOutlines, maxError, ERROR_INSIDE, aRenderSettings );
3281 break;
3282 }
3283
3284 case PCB_DIM_ALIGNED_T:
3285 case PCB_DIM_CENTER_T:
3286 case PCB_DIM_RADIAL_T:
3288 case PCB_DIM_LEADER_T:
3289 {
3290 const PCB_DIMENSION_BASE* dim = static_cast<const PCB_DIMENSION_BASE*>( item );
3291 dim->TransformShapeToPolygon( aOutlines, aLayer, 0, maxError, ERROR_INSIDE );
3292 dim->TransformTextToPolySet( aOutlines, 0, maxError, ERROR_INSIDE );
3293 break;
3294 }
3295
3296 default:
3297 break;
3298 }
3299 }
3300}
3301
3302
3304{
3305 BOARD_ITEM_SET items;
3306
3307 std::copy( m_tracks.begin(), m_tracks.end(), std::inserter( items, items.end() ) );
3308 std::copy( m_zones.begin(), m_zones.end(), std::inserter( items, items.end() ) );
3309 std::copy( m_footprints.begin(), m_footprints.end(), std::inserter( items, items.end() ) );
3310 std::copy( m_drawings.begin(), m_drawings.end(), std::inserter( items, items.end() ) );
3311 std::copy( m_markers.begin(), m_markers.end(), std::inserter( items, items.end() ) );
3312 std::copy( m_groups.begin(), m_groups.end(), std::inserter( items, items.end() ) );
3313 std::copy( m_points.begin(), m_points.end(), std::inserter( items, items.end() ) );
3314
3315 return items;
3316}
3317
3318
3319bool BOARD::operator==( const BOARD_ITEM& aItem ) const
3320{
3321 if( aItem.Type() != Type() )
3322 return false;
3323
3324 const BOARD& other = static_cast<const BOARD&>( aItem );
3325
3326 if( *m_designSettings != *other.m_designSettings )
3327 return false;
3328
3329 if( m_NetInfo.GetNetCount() != other.m_NetInfo.GetNetCount() )
3330 return false;
3331
3332 const NETNAMES_MAP& thisNetNames = m_NetInfo.NetsByName();
3333 const NETNAMES_MAP& otherNetNames = other.m_NetInfo.NetsByName();
3334
3335 for( auto it1 = thisNetNames.begin(), it2 = otherNetNames.begin();
3336 it1 != thisNetNames.end() && it2 != otherNetNames.end(); ++it1, ++it2 )
3337 {
3338 // We only compare the names in order here, not the index values
3339 // as the index values are auto-generated and the names are not.
3340 if( it1->first != it2->first )
3341 return false;
3342 }
3343
3344 if( m_properties.size() != other.m_properties.size() )
3345 return false;
3346
3347 for( auto it1 = m_properties.begin(), it2 = other.m_properties.begin();
3348 it1 != m_properties.end() && it2 != other.m_properties.end(); ++it1, ++it2 )
3349 {
3350 if( *it1 != *it2 )
3351 return false;
3352 }
3353
3354 if( m_paper.GetCustomHeightMils() != other.m_paper.GetCustomHeightMils() )
3355 return false;
3356
3357 if( m_paper.GetCustomWidthMils() != other.m_paper.GetCustomWidthMils() )
3358 return false;
3359
3360 if( m_paper.GetSizeMils() != other.m_paper.GetSizeMils() )
3361 return false;
3362
3363 if( m_paper.GetPaperId() != other.m_paper.GetPaperId() )
3364 return false;
3365
3366 if( m_paper.GetWxOrientation() != other.m_paper.GetWxOrientation() )
3367 return false;
3368
3369 for( int ii = 0; !m_titles.GetComment( ii ).empty(); ++ii )
3370 {
3371 if( m_titles.GetComment( ii ) != other.m_titles.GetComment( ii ) )
3372 return false;
3373 }
3374
3375 wxArrayString ourVars;
3376 m_titles.GetContextualTextVars( &ourVars );
3377
3378 wxArrayString otherVars;
3379 other.m_titles.GetContextualTextVars( &otherVars );
3380
3381 if( ourVars != otherVars )
3382 return false;
3383
3384 return true;
3385}
3386
3388{
3389 m_boardOutline->GetOutline().RemoveAllContours();
3390
3391 bool has_outline = GetBoardPolygonOutlines( m_boardOutline->GetOutline() );
3392
3393 if( has_outline )
3394 m_boardOutline->GetOutline().Fracture();
3395}
3396
3397
3399{
3400 // return the number of PTH with Press-Fit fabr attribute
3401 int count = 0;
3402
3403 for( FOOTPRINT* footprint : Footprints() )
3404 {
3405 for( PAD* pad : footprint->Pads() )
3406 {
3407 if( pad->GetProperty() == PAD_PROP::PRESSFIT )
3408 count++;
3409 }
3410 }
3411
3412 return count;
3413}
3414
3415
3417{
3418 // @return the number of PTH with Castellated fabr attribute
3419 int count = 0;
3420
3421 for( FOOTPRINT* footprint : Footprints() )
3422 {
3423 for( PAD* pad : footprint->Pads() )
3424 {
3425 if( pad->GetProperty() == PAD_PROP::CASTELLATED )
3426 count++;
3427 }
3428 }
3429
3430 return count;
3431}
@ ERROR_INSIDE
constexpr EDA_IU_SCALE pcbIUScale
Definition base_units.h:112
bool sortPadsByXthenYCoord(PAD *const &aLH, PAD *const &aRH)
Used by #GetSortedPadListByXCoord to sort a pad list by X coordinate value.
Definition board.cpp:2618
std::set< wxString >::iterator FindByFirstNFields(std::set< wxString > &strSet, const wxString &searchStr, char delimiter, int n)
Definition board.cpp:360
#define DEFAULT_CHAINING_EPSILON_MM
Definition board.h:87
BOARD_USE
Flags to specify how the board is being used.
Definition board.h:312
@ NORMAL
Definition board.h:313
LAYER_T
The allowed types of layers, same as Specctra DSN spec.
Definition board.h:185
@ LT_POWER
Definition board.h:188
@ LT_FRONT
Definition board.h:192
@ LT_MIXED
Definition board.h:189
@ LT_BACK
Definition board.h:193
@ LT_UNDEFINED
Definition board.h:186
@ LT_JUMPER
Definition board.h:190
@ LT_AUX
Definition board.h:191
@ LT_SIGNAL
Definition board.h:187
std::set< BOARD_ITEM *, CompareByUuid > BOARD_ITEM_SET
Set of BOARD_ITEMs ordered by UUID.
Definition board.h:306
BOX2< VECTOR2I > BOX2I
Definition box2.h:922
BASE_SET & reset(size_t pos)
Definition base_set.h:143
BASE_SET & set(size_t pos)
Definition base_set.h:116
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.
void SetEnabledLayers(const LSET &aMask)
Change the bit-mask of enabled layers to aMask.
std::shared_ptr< NET_SETTINGS > m_NetSettings
void SetCustomTrackWidth(int aWidth)
Sets custom width for track (i.e.
void SetCustomViaSize(int aSize)
Set custom size for via diameter (i.e.
const LSET & GetEnabledLayers() const
Return a bit-mask of all the layers that are enabled.
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.
void SetUserDefinedLayerCount(int aNewLayerCount)
Set the number of user defined layers to aNewLayerCount.
BOARD_STACKUP & GetStackupDescriptor()
void SetCustomViaDrill(int aDrill)
Sets custom size for via drill (i.e.
void SetCopperLayerCount(int aNewLayerCount)
Set the copper layer count to aNewLayerCount.
void SetCustomDiffPairViaGap(int aGap)
Sets custom via gap for differential pairs (i.e.
BOARD_ITEM_CONTAINER(BOARD_ITEM *aParent, KICAD_T aType)
BOARD_ITEM(BOARD_ITEM *aParent, KICAD_T idtype, PCB_LAYER_ID aLayer=F_Cu)
Definition board_item.h:81
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition board_item.h:232
virtual void SetLayerSet(const LSET &aLayers)
Definition board_item.h:260
virtual void Move(const VECTOR2I &aMoveVector)
Move this object.
Definition board_item.h:339
virtual bool IsOnLayer(PCB_LAYER_ID aLayer) const
Test to see if this object is on the given layer.
Definition board_item.h:314
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
FOOTPRINT * GetParentFootprint() const
virtual LSET GetLayerSet() const
Return a std::bitset of all layers on which the item physically resides.
Definition board_item.h:252
static VECTOR2I ZeroOffset
A value of wxPoint(0,0) which can be passed to the Draw() functions.
Definition board_item.h:181
wxString GetLayerName() const
Return the name of the PCB layer on which the item resides.
virtual void OnBoardNetSettingsChanged(BOARD &aBoard)
Definition board.h:291
virtual void OnBoardItemsAdded(BOARD &aBoard, std::vector< BOARD_ITEM * > &aBoardItem)
Definition board.h:288
virtual void OnBoardRatsnestChanged(BOARD &aBoard)
Definition board.h:295
virtual void OnBoardItemsChanged(BOARD &aBoard, std::vector< BOARD_ITEM * > &aBoardItem)
Definition board.h:293
virtual void OnBoardItemChanged(BOARD &aBoard, BOARD_ITEM *aBoardItem)
Definition board.h:292
virtual void OnBoardItemRemoved(BOARD &aBoard, BOARD_ITEM *aBoardItem)
Definition board.h:289
virtual void OnBoardItemAdded(BOARD &aBoard, BOARD_ITEM *aBoardItem)
Definition board.h:287
virtual void OnBoardHighlightNetChanged(BOARD &aBoard)
Definition board.h:294
virtual void OnBoardCompositeUpdate(BOARD &aBoard, std::vector< BOARD_ITEM * > &aAddedItems, std::vector< BOARD_ITEM * > &aRemovedItems, std::vector< BOARD_ITEM * > &aChangedItems)
Definition board.h:296
virtual void OnBoardItemsRemoved(BOARD &aBoard, std::vector< BOARD_ITEM * > &aBoardItem)
Definition board.h:290
Manage layers needed to make a physical board.
void BuildDefaultStackupList(const BOARD_DESIGN_SETTINGS *aSettings, int aActiveCopperLayersCount=0)
Create a default stackup, according to the current BOARD_DESIGN_SETTINGS settings.
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:2123
ZONE * m_SolderMaskBridges
Definition board.h:1404
void GetContextualTextVars(wxArrayString *aVars) const
Definition board.cpp:477
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:1029
BOARD_STACKUP GetStackupOrDefault() const
Definition board.cpp:2642
std::unordered_map< PTR_PTR_LAYER_CACHE_KEY, bool > m_EnclosedByAreaCache
Definition board.h:1392
std::map< ZONE *, std::map< PCB_LAYER_ID, ISOLATED_ISLANDS > > m_ZoneIsolatedIslandsMap
Definition board.h:1405
PCB_LAYER_ID GetCopperLayerStackMaxId() const
Definition board.cpp:899
GENERATORS m_generators
Definition board.h:1443
bool GetBoardPolygonOutlines(SHAPE_POLY_SET &aOutlines, OUTLINE_ERROR_HANDLER *aErrorHandler=nullptr, bool aAllowUseArcsInPolygons=false, bool aIncludeNPTHAsOutlines=false)
Extract the board outlines and build a closed polygon from lines, arcs and circle items on edge cut l...
Definition board.cpp:2787
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:2989
bool m_LegacyDesignSettingsLoaded
True if the legacy board design settings were loaded from a file.
Definition board.h:411
bool IsFootprintHolder() const
Find out if the board is being used to hold a single footprint for editing/viewing.
Definition board.h:352
PAD * GetPad(const VECTOR2I &aPosition, const LSET &aLayerMask) const
Find a pad aPosition on aLayer.
Definition board.cpp:2492
int GetUserDefinedLayerCount() const
Definition board.cpp:888
void recalcOpposites()
Definition board.cpp:808
void SetPosition(const VECTOR2I &aPos) override
Definition board.cpp:572
std::map< wxString, wxString > m_properties
Definition board.h:1458
EMBEDDED_FILES * GetEmbeddedFiles() override
Definition board.cpp:2840
int m_fileFormatVersionAtLoad
Definition board.h:1455
NETINFO_ITEM * DpCoupledNet(const NETINFO_ITEM *aNet)
Definition board.cpp:2351
std::vector< ZONE * > m_DRCCopperZones
Definition board.h:1401
void SetVisibleLayers(const LSET &aLayerMask)
A proxy function that calls the correspondent function in m_BoardSettings changes the bit-mask of vis...
Definition board.cpp:956
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
Definition board.cpp:1164
void MapNets(BOARD *aDestBoard)
Map all nets in the given board to nets with the same name (if any) in the destination board.
Definition board.cpp:2935
TITLE_BLOCK m_titles
Definition board.h:1462
GAL_SET m_LegacyVisibleItems
Definition board.h:408
LENGTH_DELAY_CALCULATION * GetLengthCalculation() const
Returns the track length calculator.
Definition board.h:1359
void RunOnNestedEmbeddedFiles(const std::function< void(EMBEDDED_FILES *)> &aFunction) override
Provide access to nested embedded files, such as symbols in schematics and footprints in boards.
Definition board.cpp:1136
const GENERATORS & Generators() const
Definition board.h:369
static wxString GetStandardLayerName(PCB_LAYER_ID aLayerId)
Return an "English Standard" name of a PCB layer when given aLayerNumber.
Definition board.h:858
const std::vector< BOARD_CONNECTED_ITEM * > AllConnectedItems()
Definition board.cpp:2909
bool IsElementVisible(GAL_LAYER_ID aLayer) const
Test whether a given element category is visible.
Definition board.cpp:990
int m_outlinesChainingEpsilon
the max distance between 2 end point to see them connected when building the board outlines
Definition board.h:1428
std::tuple< int, double, double, 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:2653
std::set< wxString > GetNetClassAssignmentCandidates() const
Return the set of netname candidates for netclass assignment.
Definition board.cpp:2390
BOARD_USE m_boardUse
What is this board being used for.
Definition board.h:1431
PAGE_INFO m_paper
Definition board.h:1461
void RemoveAllListeners()
Remove all listeners.
Definition board.cpp:2983
FOOTPRINTS m_footprints
Definition board.h:1439
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:1477
void ConvertBrdLayerToPolygonalContours(PCB_LAYER_ID aLayer, SHAPE_POLY_SET &aOutlines, KIGFX::RENDER_SETTINGS *aRenderSettings=nullptr) const
Build a set of polygons which are the outlines of copper items (pads, tracks, vias,...
Definition board.cpp:3198
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:2964
void UpdateUserUnits(BOARD_ITEM *aItem, KIGFX::VIEW *aView)
Update any references within aItem (or its descendants) to the user units.
Definition board.cpp:1663
void SetProperties(const std::map< wxString, wxString > &aProps)
Definition board.h:401
bool IsBackLayer(PCB_LAYER_ID aLayer) const
Definition board.cpp:741
GAL_SET GetVisibleElements() const
Return a set of all the element categories that are visible.
Definition board.cpp:984
void SetHighLightNet(int aNetCode, bool aMulti=false)
Select the netcode to be highlighted.
Definition board.cpp:3025
HIGH_LIGHT_INFO m_highLight
Definition board.h:1452
bool SetLayerDescr(PCB_LAYER_ID aIndex, const LAYER &aLayer)
Return the type of the copper layer given by aLayer.
Definition board.cpp:664
NETINFO_ITEM * FindNet(int aNetcode) const
Search for a net with the given netcode.
Definition board.cpp:2282
EDA_UNITS m_userUnits
Definition board.h:1465
void UpdateBoardOutline()
Definition board.cpp:3387
const ZONES & Zones() const
Definition board.h:367
void BulkRemoveStaleTeardrops(BOARD_COMMIT &aCommit)
Remove all teardrop zones with the STRUCT_DELETED flag set.
Definition board.cpp:1315
void InvokeListeners(Func &&aFunc, Args &&... args)
Definition board.h:1415
void SetDesignSettings(const BOARD_DESIGN_SETTINGS &aSettings)
Definition board.cpp:1047
const LSET & GetVisibleLayers() const
A proxy function that calls the correspondent function in m_BoardSettings.
Definition board.cpp:938
void SanitizeNetcodes()
Definition board.cpp:2954
EMBEDDED_FILES * m_embeddedFilesDelegate
Definition board.h:1493
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:2762
bool IsFrontLayer(PCB_LAYER_ID aLayer) const
Definition board.cpp:735
const GROUPS & Groups() const
The groups must maintain the following invariants.
Definition board.h:396
~BOARD()
Definition board.cpp:154
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:189
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:950
LAYER_T GetLayerType(PCB_LAYER_ID aLayer) const
Return the type of the copper layer given by aLayer.
Definition board.cpp:747
void RecordDRCExclusions()
Scan existing markers and record data from any that are Excluded.
Definition board.cpp:332
DRAWINGS m_drawings
Definition board.h:1438
void OnItemsCompositeUpdate(std::vector< BOARD_ITEM * > &aAddedItems, std::vector< BOARD_ITEM * > &aRemovedItems, std::vector< BOARD_ITEM * > &aChangedItems)
Notify the board and its listeners that items on the board have been modified in a composite operatio...
Definition board.cpp:3001
int SetAreasNetCodesFromNetNames()
Set the .m_NetCode member of all copper areas, according to the area Net Name The SetNetCodesFromNetN...
Definition board.cpp:2458
void SynchronizeNetsAndNetClasses(bool aResetTrackAndViaSizes)
Copy NETCLASS info to each NET, based on NET membership in a NETCLASS.
Definition board.cpp:2417
void SynchronizeTimeDomainProperties()
Ensure that all time domain properties providers are in sync with current settings.
Definition board.cpp:2411
void ResetNetHighLight()
Reset all high light data to the init state.
Definition board.cpp:3016
bool SetLayerName(PCB_LAYER_ID aLayer, const wxString &aLayerName)
Changes the name of the layer given by aLayer.
Definition board.cpp:710
std::list< ZONE * > GetZoneList(bool aIncludeZonesInFootprints=false) const
Definition board.cpp:2742
bool ResolveTextVar(wxString *token, int aDepth) const
Definition board.cpp:503
const MARKERS & Markers() const
Definition board.h:375
PCB_LAYER_ID FlipLayer(PCB_LAYER_ID aLayer) const
Definition board.cpp:869
const std::vector< PAD * > GetPads() const
Return a reference to a list of all the pads.
Definition board.cpp:2895
void Move(const VECTOR2I &aMoveVector) override
Move this object.
Definition board.cpp:578
TITLE_BLOCK & GetTitleBlock()
Definition board.h:764
BOX2I ComputeBoundingBox(bool aBoardEdgesOnly=false) const
Calculate the bounding box containing all board items (or board edge segments).
Definition board.cpp:2019
void FixupEmbeddedData()
After loading a file from disk, the footprints do not yet contain the full data for their embedded fi...
Definition board.cpp:1143
int GetMaxClearanceValue() const
Returns the maximum clearance value for any object on the board.
Definition board.cpp:1053
ZONES m_zones
Definition board.h:1442
PCB_LAYER_ID GetLayerID(const wxString &aLayerName) const
Return the ID of a layer.
Definition board.cpp:672
HIGH_LIGHT_INFO m_highLightPrevious
Definition board.h:1453
NETINFO_LIST m_NetInfo
Definition board.h:1485
LSET m_LegacyVisibleLayers
Visibility settings stored in board prior to 6.0, only used for loading legacy files.
Definition board.h:407
void SetVisibleAlls()
Change the bit-mask of visible element categories and layers.
Definition board.cpp:973
int GetCopperLayerCount() const
Definition board.cpp:876
int m_timeStamp
Definition board.h:1432
std::vector< BOARD_LISTENER * > m_listeners
Definition board.h:1487
bool RemoveAllItemsOnLayer(PCB_LAYER_ID aLayer)
Removes all owned items other than footprints existing on the given board layer, and modifies the sta...
Definition board.cpp:1577
std::unordered_map< PTR_PTR_CACHE_KEY, bool > m_IntersectsCourtyardCache
Definition board.h:1388
void IncrementTimeStamp()
Definition board.cpp:257
int MatchDpSuffix(const wxString &aNetName, wxString &aComplementNet)
Fetch the coupled netname for a given net.
Definition board.cpp:2301
std::unordered_map< PTR_PTR_CACHE_KEY, bool > m_IntersectsFCourtyardCache
Definition board.h:1389
PCB_POINTS m_points
Definition board.h:1445
std::unique_ptr< LENGTH_DELAY_CALCULATION > m_lengthDelayCalc
Definition board.h:1496
const FOOTPRINTS & Footprints() const
Definition board.h:363
std::shared_ptr< CONNECTIVITY_DATA > m_connectivity
Definition board.h:1459
std::set< KIFONT::OUTLINE_FONT * > GetFonts() const override
Get the list of all outline fonts used in the board.
Definition board.cpp:2858
void RemoveAll(std::initializer_list< KICAD_T > aTypes={ PCB_NETINFO_T, PCB_MARKER_T, PCB_GROUP_T, PCB_ZONE_T, PCB_GENERATOR_T, PCB_FOOTPRINT_T, PCB_TRACE_T, PCB_SHAPE_T })
An efficient way to remove all items of a certain type from the board.
Definition board.cpp:1445
const BOARD_ITEM_SET GetItemSet()
Definition board.cpp:3303
const TRACKS & Tracks() const
Definition board.h:361
int m_DRCMaxPhysicalClearance
Definition board.h:1403
FOOTPRINT * FindFootprintByPath(const KIID_PATH &aPath) const
Search for a FOOTPRINT within this board with the given path.
Definition board.cpp:2378
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:1309
std::unordered_map< wxString, LSET > m_LayerExpressionCache
Definition board.h:1393
bool m_embedFonts
Definition board.h:1489
wxString GroupsSanityCheckInternal(bool repair)
Definition board.cpp:3061
void OnRatsnestChanged()
Notify the board and its listeners that the ratsnest has been recomputed.
Definition board.cpp:3010
wxString ConvertCrossReferencesToKIIDs(const wxString &aSource) const
Convert cross-references back and forth between ${refDes:field} and ${kiid:field}.
Definition board.cpp:1900
wxString GetClass() const override
Return the class name.
Definition board.h:1099
std::unique_ptr< COMPONENT_CLASS_MANAGER > m_componentClassManager
Definition board.h:1495
bool m_LegacyNetclassesLoaded
True if netclasses were loaded from the file.
Definition board.h:415
void SetCopperLayerCount(int aCount)
Definition board.cpp:882
std::unordered_map< const ZONE *, BOX2I > m_ZoneBBoxCache
Definition board.h:1396
std::unordered_map< PTR_PTR_CACHE_KEY, bool > m_IntersectsBCourtyardCache
Definition board.h:1390
TRACKS TracksInNet(int aNetCode)
Collect all the TRACKs and VIAs that are members of a net given by aNetCode.
Definition board.cpp:642
void SetProject(PROJECT *aProject, bool aReferenceOnly=false)
Link a board to a given project.
Definition board.cpp:199
PROJECT * m_project
Definition board.h:1464
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:2678
bool HasItemsOnLayer(PCB_LAYER_ID aLayer)
Definition board.cpp:1531
const wxString & GetFileName() const
Definition board.h:359
bool operator==(const BOARD_ITEM &aOther) const override
Definition board.cpp:3319
std::vector< PCB_MARKER * > ResolveDRCExclusions(bool aCreateMarkers)
Rebuild DRC markers from the serialized data in BOARD_DESIGN_SETTINGS.
Definition board.cpp:389
int GetPadWithCastellatedAttrCount()
Definition board.cpp:3416
FOOTPRINT * FindFootprintByReference(const wxString &aReference) const
Search for a FOOTPRINT within this board with the given reference designator.
Definition board.cpp:2366
unsigned GetNodesCount(int aNet=-1) const
Definition board.cpp:2002
void FillItemMap(std::map< KIID, EDA_ITEM * > &aMap)
Definition board.cpp:1858
void SetElementVisibility(GAL_LAYER_ID aLayer, bool aNewState)
Change the visibility of an element category.
Definition board.cpp:996
std::shared_ptr< DRC_RTREE > m_CopperItemRTreeCache
Definition board.h:1395
bool SetLayerType(PCB_LAYER_ID aLayer, LAYER_T aLayerType)
Change the type of the layer given by aLayer.
Definition board.cpp:766
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Return the name of a aLayer.
Definition board.cpp:692
void DetachAllFootprints()
Remove all footprints without deleting.
Definition board.cpp:1732
std::map< int, LAYER > m_layers
Definition board.h:1450
void RunOnChildren(const std::function< void(BOARD_ITEM *)> &aFunction, RECURSE_MODE aMode) const override
Invoke a function on all children.
Definition board.cpp:600
int GetOutlinesChainingEpsilon()
Definition board.h:808
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:2627
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:930
int m_DRCMaxClearance
Definition board.h:1402
void ClearProject()
Definition board.cpp:237
std::unordered_map< ZONE *, std::unique_ptr< DRC_RTREE > > m_CopperZoneRTreeCache
Definition board.h:1394
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:1303
int LayerDepth(PCB_LAYER_ID aStartLayer, PCB_LAYER_ID aEndLayer) const
Definition board.cpp:912
void DeleteAllFootprints()
Remove all footprints from the deque and free the memory associated with them.
Definition board.cpp:1722
PROJECT * GetProject() const
Definition board.h:554
bool IsEmpty() const
Definition board.cpp:560
int GetPadWithPressFitAttrCount()
Definition board.cpp:3398
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:2085
wxString GroupsSanityCheck(bool repair=false)
Consistency check of internal m_groups structure.
Definition board.cpp:3048
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition board.cpp:1041
std::vector< ZONE * > m_DRCZones
Definition board.h:1400
const LSET & GetEnabledLayers() const
A proxy function that calls the corresponding function in m_BoardSettings.
Definition board.cpp:924
BOARD()
Definition board.cpp:81
void UpdateRatsnestExclusions()
Update the visibility flags on the current unconnected ratsnest lines.
Definition board.cpp:301
wxString ConvertKIIDsToCrossReferences(const wxString &aSource) const
Definition board.cpp:1954
void SynchronizeProperties()
Copy the current project's text variables into the boards property cache.
Definition board.cpp:2404
std::unordered_map< KIID, BOARD_ITEM * > m_itemByIdCache
Definition board.h:1448
void RemoveListener(BOARD_LISTENER *aListener)
Remove the specified listener.
Definition board.cpp:2971
std::shared_mutex m_CachesMutex
Definition board.h:1387
bool SynchronizeComponentClasses(const std::unordered_set< wxString > &aNewSheetPaths) const
Copy component class / component class generator information from the project settings.
Definition board.cpp:2447
void DeleteMARKERs()
Delete all MARKERS from the board.
Definition board.cpp:1689
void Remove(BOARD_ITEM *aBoardItem, REMOVE_MODE aMode=REMOVE_MODE::NORMAL) override
Removes an item from the container.
Definition board.cpp:1332
GROUPS m_groups
Definition board.h:1441
MARKERS m_markers
Definition board.h:1437
std::unordered_map< PTR_PTR_LAYER_CACHE_KEY, bool > m_IntersectsAreaCache
Definition board.h:1391
std::optional< int > m_maxClearanceValue
Definition board.h:1397
void HighLightON(bool aValue=true)
Enable or disable net highlighting.
Definition board.cpp:3038
void SetEnabledLayers(const LSET &aLayerMask)
A proxy function that calls the correspondent function in m_BoardSettings.
Definition board.cpp:944
TRACKS m_tracks
Definition board.h:1440
BOARD_ITEM * ResolveItem(const KIID &aID, bool aAllowNullptrReturn=false) const
Definition board.cpp:1742
bool m_LegacyCopperEdgeClearanceLoaded
Definition board.h:412
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:2995
std::shared_ptr< CONNECTIVITY_DATA > GetConnectivity() const
Return a list of missing connections between components/tracks.
Definition board.h:538
VECTOR2I GetPosition() const override
Definition board.cpp:566
void CacheTriangulation(PROGRESS_REPORTER *aReporter=nullptr, const std::vector< ZONE * > &aZones={})
Definition board.cpp:1085
void SetVisibleElements(const GAL_SET &aMask)
A proxy function that calls the correspondent function in m_BoardSettings.
Definition board.cpp:963
void EmbedFonts() override
Finds all fonts used in the board and embeds them in the file if permissions allow.
Definition board.cpp:2885
PCB_BOARD_OUTLINE * m_boardOutline
Definition board.h:1444
void SetUserDefinedLayerCount(int aCount)
Definition board.cpp:894
const DRAWINGS & Drawings() const
Definition board.h:365
wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider, bool aFull) const override
Return a user-visible description string of this item.
Definition board.cpp:1657
constexpr coord_type GetY() const
Definition box2.h:208
constexpr size_type GetWidth() const
Definition box2.h:214
constexpr coord_type GetX() const
Definition box2.h:207
constexpr BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
Definition box2.h:658
constexpr size_type GetHeight() const
Definition box2.h:215
bool Dirty() const
BOARD_CONNECTED_ITEM * Parent() const
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
int GetCount() const
Return the number of objects in the list.
Definition collector.h:83
COMMIT & Removed(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Definition commit.h:96
A class to manage Component Classes in a board context.
void RunOnUnconnectedEdges(std::function< bool(CN_EDGE &)> aFunc)
unsigned int GetUnconnectedCount(bool aVisibileOnly) const
static DELETED_BOARD_ITEM * GetInstance()
Definition board_item.h:490
The base class for create windows for drawing purpose.
A set of EDA_ITEMs (i.e., without duplicates).
Definition eda_group.h:46
virtual VECTOR2I GetPosition() const
Definition eda_item.h:272
virtual void ClearEditFlags()
Definition eda_item.h:156
void SetFlags(EDA_ITEM_FLAGS aMask)
Definition eda_item.h:142
const KIID m_Uuid
Definition eda_item.h:516
virtual EDA_GROUP * GetParentGroup() const
Definition eda_item.h:116
KICAD_T Type() const
Returns the type of object.
Definition eda_item.h:110
static INSPECT_RESULT IterateForward(std::deque< T > &aList, INSPECTOR inspector, void *testData, const std::vector< KICAD_T > &scanTypes)
This changes first parameter to avoid the DList and use the main queue instead.
Definition eda_item.h:325
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:127
virtual void SetParent(EDA_ITEM *aParent)
Definition eda_item.h:113
bool HasFlag(EDA_ITEM_FLAGS aFlag) const
Definition eda_item.h:146
EDA_ITEM(EDA_ITEM *parent, KICAD_T idType, bool isSCH_ITEM=false, bool isBOARD_ITEM=false)
Definition eda_item.cpp:39
int Compare(const EDA_SHAPE *aOther) const
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition eda_text.h:80
EMBEDDED_FILE * GetEmbeddedFile(const wxString &aName) const
Returns the embedded file with the given name or nullptr if it does not exist.
EMBEDDED_FILE * AddFile(const wxFileName &aName, bool aOverwrite)
Load a file from disk and adds it to the collection.
EMBEDDED_FILES()=default
const std::map< wxString, EMBEDDED_FILE * > & EmbeddedFileMap() const
bool ResolveTextVar(wxString *token, int aDepth=0) const
Resolve any references to system tokens supported by the component.
void RunOnChildren(const std::function< void(BOARD_ITEM *)> &aFunction, RECURSE_MODE aMode) const override
Invoke a function on all children.
Helper for storing and iterating over GAL_LAYER_IDs.
Definition layer_ids.h:403
static GAL_SET DefaultVisible()
Definition lset.cpp:769
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:69
static const std::vector< KICAD_T > Tracks
A scan list for only TRACKs and ARCs.
Definition collectors.h:129
FONT is an abstract base class for both outline and stroke fonts.
Definition font.h:131
virtual bool IsOutline() const
Definition font.h:139
Class OUTLINE_FONT implements outline font drawing.
EMBEDDING_PERMISSION GetEmbeddingPermission() const
Container for all the knowledge about how graphical objects are drawn on any output surface/device.
bool IsBOARD_ITEM() const
Definition view_item.h:102
virtual wxString GetClass() const =0
Return the class name.
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
Definition view.h:66
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:1685
Definition kiid.h:49
Lightweight class which holds a pad, via, or a routed trace outline.
TYPE Type() const
Gets the routing item type.
Class which calculates lengths (and associated routing statistics) in a BOARD context.
LENGTH_DELAY_CALCULATION_ITEM GetLengthCalculationItem(const BOARD_CONNECTED_ITEM *aBoardItem) const
Return a LENGTH_CALCULATION_ITEM constructed from the given BOARD_CONNECTED_ITEM.
LENGTH_DELAY_STATS CalculateLengthDetails(std::vector< LENGTH_DELAY_CALCULATION_ITEM > &aItems, PATH_OPTIMISATIONS aOptimisations, const PAD *aStartPad=nullptr, const PAD *aEndPad=nullptr, LENGTH_DELAY_LAYER_OPT aLayerOpt=LENGTH_DELAY_LAYER_OPT::NO_LAYER_DETAIL, LENGTH_DELAY_DOMAIN_OPT aDomain=LENGTH_DELAY_DOMAIN_OPT::NO_DELAY_DETAIL) const
Calculates the electrical length of the given items.
LSET is a set of PCB_LAYER_IDs.
Definition lset.h:37
static LSET AllCuMask(int aCuLayerCount)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition lset.cpp:582
static const LSET & AllLayersMask()
Definition lset.cpp:624
std::shared_ptr< RC_ITEM > GetRCItem() const
void SetExcluded(bool aExcluded, const wxString &aComment=wxEmptyString)
Definition marker_base.h:94
void SetParent(JSON_SETTINGS *aParent, bool aLoadFromFile=true)
static const char Default[]
the name of the default NETCLASS
Definition netclass.h:47
void SetDescription(const wxString &aDesc)
Definition netclass.h:114
Handle the data for a net.
Definition netinfo.h:54
wxString GetClass() const override
Return the class name.
Definition netinfo.h:65
const wxString & GetNetname() const
Definition netinfo.h:112
int GetNetCode() const
Definition netinfo.h:106
static const int UNCONNECTED
Constant that holds the "unconnected net" number (typically 0) all items "connected" to this net are ...
Definition netinfo.h:365
static const int ORPHANED
Constant that forces initialization of a netinfo item to the NETINFO_ITEM ORPHANED (typically -1) whe...
Definition netinfo.h:369
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:373
unsigned GetNetCount() const
Definition netinfo.h:353
const NETNAMES_MAP & NetsByName() const
Return the name map, at least for python.
Definition netinfo.h:356
void ClearAllCaches()
Clears the effective netclass cache for all nets.
std::shared_ptr< NETCLASS > GetEffectiveNetClass(const wxString &aNetName)
Fetches the effective (may be aggregate) netclass for the given net name.
std::shared_ptr< NETCLASS > GetDefaultNetclass()
Gets the default netclass for the project.
void SetDefaultNetclass(std::shared_ptr< NETCLASS > netclass)
Sets the default netclass for the project Calling user is responsible for resetting the effective net...
Definition pad.h:54
VECTOR2I GetPosition() const override
Definition pad.h:208
const VECTOR2D & GetSizeMils() const
Definition page_info.h:150
wxPrintOrientation GetWxOrientation() const
Definition page_info.h:133
static double GetCustomHeightMils()
Definition page_info.h:202
wxPaperSize GetPaperId() const
Definition page_info.h:138
static double GetCustomWidthMils()
Definition page_info.h:197
static int Compare(const PCB_BARCODE *aBarcode, const PCB_BARCODE *aOther)
void TransformShapeToPolygon(SHAPE_POLY_SET &aBuffer, PCB_LAYER_ID aLayer, int aClearance, int aMaxError, ERROR_LOC aErrorLoc=ERROR_INSIDE, bool ignoreLineWidth=false) const override
Convert the barcode (text + symbol shapes) to polygonal geometry suitable for filling/collision tests...
Abstract dimension API.
void TransformShapeToPolygon(SHAPE_POLY_SET &aBuffer, PCB_LAYER_ID aLayer, int aClearance, int aError, ERROR_LOC aErrorLoc, bool aIgnoreLineWidth=false) const override
Convert the item shape to a closed polygon.
DIM_UNITS_MODE GetUnitsMode() const
A set of BOARD_ITEMs (i.e., without duplicates).
Definition pcb_group.h:53
Collect all BOARD_ITEM objects on a given layer.
Definition collectors.h:549
void Collect(BOARD_ITEM *aBoard, const std::vector< KICAD_T > &aTypes)
Test a BOARD_ITEM using this class's Inspector method, which does the collection.
void SetLayerId(PCB_LAYER_ID aLayerId)
Definition collectors.h:555
static PCB_MARKER * DeserializeFromString(const wxString &data)
A PCB_POINT is a 0-dimensional point that is used to mark a position on a PCB, or more usually a foot...
Definition pcb_point.h:43
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.
static int Compare(const PCB_TABLE *aTable, const PCB_TABLE *aOther)
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...
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...
Definition pcb_text.cpp:573
const VECTOR2I & GetEndPoint(ENDPOINT_T aEndPoint) const
Return the selected endpoint (start or end)
Definition pcb_track.h:169
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.
std::shared_ptr< COMPONENT_CLASS_SETTINGS > & ComponentClassSettings()
Container for project specific data.
Definition project.h:65
virtual const wxString GetProjectName() const
Return the short name of the project.
Definition project.cpp:174
virtual PROJECT_FILE & GetProjectFile() const
Definition project.h:204
std::vector< KIID > GetIDs() const
Definition rc_item.h:126
bool PointInside(const VECTOR2I &aPt, int aAccuracy=0, bool aUseBBoxCache=false) const override
Check if point aP lies inside a closed shape.
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
Represent a set of closed polygons.
void Simplify()
Simplify the polyset (merges overlapping polys, eliminates degeneracy/self-intersections)
int AddHole(const SHAPE_LINE_CHAIN &aHole, int aOutline=-1)
Adds a new hole to the given outline (default: last) and returns its index.
SHAPE_LINE_CHAIN & Outline(int aIndex)
Return the reference to aIndex-th outline in the set.
int OutlineCount() const
Return the number of outlines in the set.
const wxString & GetComment(int aIdx) const
static void GetContextualTextVars(wxArrayString *aVars)
Handle a list of polygons defining a copper zone.
Definition zone.h:74
virtual void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
Definition zone.cpp:505
void SetHatchStyle(ZONE_BORDER_DISPLAY_STYLE aStyle)
Definition zone.h:590
bool IsTeardropArea() const
Definition zone.h:679
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:1134
#define EXCLUDE_ZONES
bool BuildBoardPolygonOutlines(BOARD *aBoard, SHAPE_POLY_SET &aOutlines, int aErrorMax, int aChainingEpsilon, OUTLINE_ERROR_HANDLER *aErrorHandler, bool aAllowUseArcsInPolygons)
Extract the board outlines and build a closed polygon from lines, arcs and circle items on edge cut l...
const std::function< void(const wxString &msg, BOARD_ITEM *itemA, BOARD_ITEM *itemB, const VECTOR2I &pt)> OUTLINE_ERROR_HANDLER
static bool empty(const wxTextEntryBase *aCtrl)
#define _(s)
RECURSE_MODE
Definition eda_item.h:50
@ RECURSE
Definition eda_item.h:51
@ NO_RECURSE
Definition eda_item.h:52
INSPECT_RESULT
Definition eda_item.h:44
const INSPECTOR_FUNC & INSPECTOR
std::function passed to nested users by ref, avoids copying std::function.
Definition eda_item.h:91
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:88
#define STRUCT_DELETED
flag indication structures to be erased
EDA_UNITS
Definition eda_units.h:48
KIID niluuid(0)
bool IsCopperLayer(int aLayerId)
Test whether a layer is a copper layer.
Definition layer_ids.h:676
GAL_LAYER_ID
GAL layers are "virtual" layers, i.e.
Definition layer_ids.h:228
@ GAL_LAYER_ID_START
Definition layer_ids.h:229
@ LAYER_FOOTPRINTS_FR
Show footprints on front.
Definition layer_ids.h:259
@ 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:287
@ LAYER_RATSNEST
Definition layer_ids.h:253
@ LAYER_FOOTPRINTS_BK
Show footprints on back.
Definition layer_ids.h:260
PCB_LAYER_ID
A quick note on layer IDs:
Definition layer_ids.h:60
@ Edge_Cuts
Definition layer_ids.h:112
@ B_Mask
Definition layer_ids.h:98
@ B_Cu
Definition layer_ids.h:65
@ F_Mask
Definition layer_ids.h:97
@ UNDEFINED_LAYER
Definition layer_ids.h:61
@ Rescue
Definition layer_ids.h:121
@ User_1
Definition layer_ids.h:124
@ PCB_LAYER_ID_COUNT
Definition layer_ids.h:171
@ 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:364
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition lset.cpp:737
bool contains(const _Container &__container, _Value __value)
Returns true if the container contains the given value.
Definition kicad_algo.h:100
STL namespace.
@ NPTH
like PAD_PTH, but not plated mechanical use only, no connection allowed
Definition padstack.h:87
@ PRESSFIT
a PTH with a hole diameter with tight tolerances for press fit pin
Definition padstack.h:107
@ CASTELLATED
a pad with a castellated through hole
Definition padstack.h:105
PAGE_SIZE_TYPE
Definition page_info.h:50
BARCODE class definition.
Class to handle a set of BOARD_ITEMs.
@ THROUGH
Definition pcb_track.h:68
ENDPOINT_T
Definition pcb_track.h:60
see class PGM_BASE
CITER next(CITER it)
Definition ptree.cpp:124
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:3151
bool operator()(const BOARD_ITEM *aFirst, const BOARD_ITEM *aSecond) const
Definition board.cpp:3130
std::vector< char > decompressedData
Container to hold information pertinent to a layer of a BOARD.
Definition board.h:201
static LAYER_T ParseType(const char *aType)
Convert a string to a LAYER_T.
Definition board.cpp:795
static const char * ShowType(LAYER_T aType)
Convert a LAYER_T enum to a string representation of the layer type.
Definition board.cpp:779
Holds length measurement result details and statistics.
Struct to control which optimisations the length calculation code runs on the given path objects.
int delta
thread_pool & GetKiCadThreadPool()
Get a reference to the current thread pool.
static thread_pool * tp
BS::thread_pool< 0 > thread_pool
Definition thread_pool.h:31
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:106
@ PCB_DIM_LEADER_T
class PCB_DIM_LEADER, a leader dimension (graphic item)
Definition typeinfo.h:103
@ PCB_GENERATOR_T
class PCB_GENERATOR, generator on a layer
Definition typeinfo.h:91
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
Definition typeinfo.h:97
@ PCB_DIM_CENTER_T
class PCB_DIM_CENTER, a center point marking (graphic item)
Definition typeinfo.h:104
@ PCB_GROUP_T
class PCB_GROUP, a set of BOARD_ITEMs
Definition typeinfo.h:111
@ PCB_TEXTBOX_T
class PCB_TEXTBOX, wrapped text on a layer
Definition typeinfo.h:93
@ PCB_ZONE_T
class ZONE, a copper pour area
Definition typeinfo.h:108
@ PCB_TEXT_T
class PCB_TEXT, text on a layer
Definition typeinfo.h:92
@ PCB_REFERENCE_IMAGE_T
class PCB_REFERENCE_IMAGE, bitmap on a layer
Definition typeinfo.h:89
@ PCB_FIELD_T
class PCB_FIELD, text associated with a footprint property
Definition typeinfo.h:90
@ PCB_MARKER_T
class PCB_MARKER, a marker used to show something
Definition typeinfo.h:99
@ PCB_BARCODE_T
class PCB_BARCODE, a barcode (graphic item)
Definition typeinfo.h:101
@ PCB_TARGET_T
class PCB_TARGET, a target (graphic item)
Definition typeinfo.h:107
@ PCB_TABLECELL_T
class PCB_TABLECELL, PCB_TEXTBOX for use in tables
Definition typeinfo.h:95
@ 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:102
@ 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:98
@ PCB_TABLE_T
class PCB_TABLE, table of PCB_TABLECELLs
Definition typeinfo.h:94
@ PCB_NETINFO_T
class NETINFO_ITEM, a description of a net
Definition typeinfo.h:110
@ PCB_POINT_T
class PCB_POINT, a 0-dimensional point
Definition typeinfo.h:113
@ PCB_TRACE_T
class PCB_TRACK, a track segment (segment on a copper layer)
Definition typeinfo.h:96
@ PCB_DIM_RADIAL_T
class PCB_DIM_RADIAL, a radius or diameter dimension
Definition typeinfo.h:105
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:695
ZONE_BORDER_DISPLAY_STYLE
Zone border styles.