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