KiCad PCB EDA Suite
class_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 <dick@softplc.com>
6  * Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
7  *
8  * Copyright (C) 1992-2020 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 <algorithm>
29 #include <iterator>
30 #include <fctsys.h>
31 #include <pcb_base_frame.h>
32 #include <reporter.h>
33 #include <ws_proxy_view_item.h>
34 #include <class_board.h>
35 #include <class_module.h>
36 #include <class_track.h>
37 #include <class_zone.h>
38 #include <class_marker_pcb.h>
39 #include <class_drawsegment.h>
40 #include <class_pcb_target.h>
42 #include <pgm_base.h>
43 #include <pcbnew_settings.h>
44 #include <project.h>
45 #include <project/net_settings.h>
46 #include <project/project_file.h>
48 #include <ratsnest/ratsnest_data.h>
50 
51 /* This is an odd place for this, but CvPcb won't link if it is
52  * in class_board_item.cpp like I first tried it.
53  */
55 
56 
59  m_paper( PAGE_INFO::A4 ),
60  m_project( nullptr ),
61  m_designSettings( new BOARD_DESIGN_SETTINGS( nullptr, "board.design_settings" ) ),
62  m_NetInfo( this ),
63  m_LegacyDesignSettingsLoaded( false ),
64  m_LegacyNetclassesLoaded( false )
65 {
66  // we have not loaded a board yet, assume latest until then.
67  m_fileFormatVersionAtLoad = LEGACY_BOARD_FILE_VERSION;
68 
69  m_CurrentZoneContour = NULL; // This ZONE_CONTAINER handle the
70  // zone contour currently in progress
71 
72  for( LAYER_NUM layer = 0; layer < PCB_LAYER_ID_COUNT; ++layer )
73  {
74  m_Layer[layer].m_name = GetStandardLayerName( ToLAYER_ID( layer ) );
75 
76  if( IsCopperLayer( layer ) )
77  m_Layer[layer].m_type = LT_SIGNAL;
78  else
79  m_Layer[layer].m_type = LT_UNDEFINED;
80  }
81 
83 
84  // Initialize default netclass.
85  NETCLASS* defaultClass = bds.GetDefault();
86  defaultClass->SetDescription( _( "This is the default net class." ) );
87  bds.SetCurrentNetClass( defaultClass->GetName() );
88 
89  // Set sensible initial values for custom track width & via size
90  bds.UseCustomTrackViaSize( false );
94 
95  // Initialize ratsnest
96  m_connectivity.reset( new CONNECTIVITY_DATA() );
97 
98  // Set flag bits on these that will only be cleared if these are loaded from a legacy file
99  m_LegacyVisibleLayers.reset().set( Rescue );
101 }
102 
103 
105 {
106  while( m_ZoneDescriptorList.size() )
107  {
108  ZONE_CONTAINER* area_to_remove = m_ZoneDescriptorList[0];
109  Delete( area_to_remove );
110  }
111 
112  // Clean up the owned elements
113  DeleteMARKERs();
115 
116  // Delete the modules
117  for( auto m : m_modules )
118  delete m;
119 
120  m_modules.clear();
121 
122  // Delete the tracks
123  for( auto t : m_tracks )
124  delete t;
125 
126  m_tracks.clear();
127 
128  // Delete the drawings
129  for (auto d : m_drawings )
130  delete d;
131 
132  m_drawings.clear();
133 
134  delete m_CurrentZoneContour;
136 }
137 
138 
140 {
141  GetConnectivity()->Build( this );
142 }
143 
144 
145 void BOARD::SetProject( PROJECT* aProject )
146 {
147  m_project = aProject;
148 
149  if( aProject )
150  {
151  PROJECT_FILE& project = aProject->GetProjectFile();
152 
153  // Link the design settings object to the project file
154  project.m_BoardSettings = &GetDesignSettings();
155 
156  // Set parent, which also will load the values from JSON stored in the project
157  project.m_BoardSettings->SetParent( &project );
158 
159  // The DesignSettings' netclasses pointer will be pointing to its internal netclasses
160  // list at this point. If we loaded anything into it from a legacy board file then we
161  // want to transfer it over to the project netclasses list.
164 
165  // Now update the DesignSettings' netclass pointer ot point into the project.
167  }
168 }
169 
170 
172 {
173  if( !m_project )
174  return;
175 
176  PROJECT_FILE& project = m_project->GetProjectFile();
177 
178  // Owned by the BOARD
179  if( project.m_BoardSettings )
180  {
181  project.ReleaseNestedSettings( project.m_BoardSettings );
182  project.m_BoardSettings = nullptr;
183  }
184 
185  GetDesignSettings().SetParent( nullptr );
186  m_project = nullptr;
187 }
188 
189 
191 {
192  return ZeroOffset;
193 }
194 
195 
196 void BOARD::SetPosition( const wxPoint& aPos )
197 {
198  wxLogWarning( wxT( "This should not be called on the BOARD object") );
199 }
200 
201 
202 void BOARD::Move( const wxPoint& aMoveVector ) // overload
203 {
204  // @todo : anything like this elsewhere? maybe put into GENERAL_COLLECTOR class.
205  static const KICAD_T top_level_board_stuff[] = {
206  PCB_MARKER_T,
207  PCB_TEXT_T,
208  PCB_LINE_T,
210  PCB_TARGET_T,
211  PCB_VIA_T,
212  PCB_TRACE_T,
213  PCB_ARC_T,
214  // PCB_PAD_T, Can't be at board level
215  // PCB_MODULE_TEXT_T, Can't be at board level
216  PCB_MODULE_T,
218  EOT
219  };
220 
221  INSPECTOR_FUNC inspector = [&] ( EDA_ITEM* item, void* testData )
222  {
223  BOARD_ITEM* brd_item = (BOARD_ITEM*) item;
224 
225  // aMoveVector was snapshotted, don't need "data".
226  brd_item->Move( aMoveVector );
227 
229  };
230 
231  Visit( inspector, NULL, top_level_board_stuff );
232 }
233 
234 
235 TRACKS BOARD::TracksInNet( int aNetCode )
236 {
237  TRACKS ret;
238 
239  INSPECTOR_FUNC inspector = [aNetCode,&ret] ( EDA_ITEM* item, void* testData )
240  {
241  TRACK* t = (TRACK*) item;
242 
243  if( t->GetNetCode() == aNetCode )
244  ret.push_back( t );
245 
247  };
248 
249  // visit this BOARD's TRACKs and VIAs with above TRACK INSPECTOR which
250  // appends all in aNetCode to ret.
251  Visit( inspector, NULL, GENERAL_COLLECTOR::Tracks );
252 
253  return ret;
254 }
255 
256 
257 bool BOARD::SetLayerDescr( PCB_LAYER_ID aIndex, const LAYER& aLayer )
258 {
259  if( unsigned( aIndex ) < arrayDim( m_Layer ) )
260  {
261  m_Layer[ aIndex ] = aLayer;
262  return true;
263  }
264 
265  return false;
266 }
267 
268 
269 const PCB_LAYER_ID BOARD::GetLayerID( const wxString& aLayerName ) const
270 {
271 
272  // Look for the BOARD specific copper layer names
273  for( LAYER_NUM layer = 0; layer < PCB_LAYER_ID_COUNT; ++layer )
274  {
275  if ( IsCopperLayer( layer ) && ( m_Layer[ layer ].m_name == aLayerName ) )
276  {
277  return ToLAYER_ID( layer );
278  }
279  }
280 
281  // Otherwise fall back to the system standard layer names
282  for( LAYER_NUM layer = 0; layer < PCB_LAYER_ID_COUNT; ++layer )
283  {
284  if( GetStandardLayerName( ToLAYER_ID( layer ) ) == aLayerName )
285  {
286  return ToLAYER_ID( layer );
287  }
288  }
289 
290  return UNDEFINED_LAYER;
291 }
292 
293 const wxString BOARD::GetLayerName( PCB_LAYER_ID aLayer ) const
294 {
295  // All layer names are stored in the BOARD.
296  if( IsLayerEnabled( aLayer ) )
297  {
298  // Standard names were set in BOARD::BOARD() but they may be
299  // over-ridden by BOARD::SetLayerName().
300  // For copper layers, return the actual copper layer name,
301  // otherwise return the Standard English layer name.
302  if( IsCopperLayer( aLayer ) )
303  return m_Layer[aLayer].m_name;
304  }
305 
306  return GetStandardLayerName( aLayer );
307 }
308 
309 bool BOARD::SetLayerName( PCB_LAYER_ID aLayer, const wxString& aLayerName )
310 {
311  if( !IsCopperLayer( aLayer ) )
312  return false;
313 
314  if( aLayerName == wxEmptyString )
315  return false;
316 
317  // no quote chars in the name allowed
318  if( aLayerName.Find( wxChar( '"' ) ) != wxNOT_FOUND )
319  return false;
320 
321  wxString nameTemp = aLayerName;
322 
323  // replace any spaces with underscores before we do any comparing
324  nameTemp.Replace( wxT( " " ), wxT( "_" ) );
325 
326  if( IsLayerEnabled( aLayer ) )
327  {
328  m_Layer[aLayer].m_name = nameTemp;
329  return true;
330  }
331 
332  return false;
333 }
334 
335 
337 {
338  if( !IsCopperLayer( aLayer ) )
339  return LT_SIGNAL;
340 
341  //@@IMB: The original test was broken due to the discontinuity
342  // in the layer sequence.
343  if( IsLayerEnabled( aLayer ) )
344  return m_Layer[aLayer].m_type;
345 
346  return LT_SIGNAL;
347 }
348 
349 
350 bool BOARD::SetLayerType( PCB_LAYER_ID aLayer, LAYER_T aLayerType )
351 {
352  if( !IsCopperLayer( aLayer ) )
353  return false;
354 
355  //@@IMB: The original test was broken due to the discontinuity
356  // in the layer sequence.
357  if( IsLayerEnabled( aLayer ) )
358  {
359  m_Layer[aLayer].m_type = aLayerType;
360  return true;
361  }
362 
363  return false;
364 }
365 
366 
367 const char* LAYER::ShowType( LAYER_T aType )
368 {
369  const char* cp;
370 
371  switch( aType )
372  {
373  default:
374  case LT_SIGNAL:
375  cp = "signal";
376  break;
377 
378  case LT_POWER:
379  cp = "power";
380  break;
381 
382  case LT_MIXED:
383  cp = "mixed";
384  break;
385 
386  case LT_JUMPER:
387  cp = "jumper";
388  break;
389  }
390 
391  return cp;
392 }
393 
394 
395 LAYER_T LAYER::ParseType( const char* aType )
396 {
397  if( strcmp( aType, "signal" ) == 0 )
398  return LT_SIGNAL;
399  else if( strcmp( aType, "power" ) == 0 )
400  return LT_POWER;
401  else if( strcmp( aType, "mixed" ) == 0 )
402  return LT_MIXED;
403  else if( strcmp( aType, "jumper" ) == 0 )
404  return LT_JUMPER;
405  else
406  return LT_UNDEFINED;
407 }
408 
409 
411 {
413 }
414 
415 
416 void BOARD::SetCopperLayerCount( int aCount )
417 {
419 }
420 
421 
423 {
425 }
426 
427 
429 {
430  // If there is no project, assume layer is visible always
431  return GetDesignSettings().IsLayerEnabled( aLayer )
432  && ( !m_project || m_project->GetLocalSettings().m_VisibleLayers[aLayer] );
433 }
434 
435 
437 {
439 }
440 
441 
442 void BOARD::SetEnabledLayers( LSET aLayerSet )
443 {
444  GetDesignSettings().SetEnabledLayers( aLayerSet );
445 }
446 
447 
448 void BOARD::SetVisibleLayers( LSET aLayerSet )
449 {
450  if( m_project )
452 }
453 
454 
456 {
457  // Call SetElementVisibility for each item
458  // to ensure specific calculations that can be needed by some items,
459  // just changing the visibility flags could be not sufficient.
460  for( size_t i = 0; i < aSet.size(); i++ )
461  SetElementVisibility( GAL_LAYER_ID_START + static_cast<int>( i ), aSet[i] );
462 }
463 
464 
466 {
467  SetVisibleLayers( LSET().set() );
468 
469  // Call SetElementVisibility for each item,
470  // to ensure specific calculations that can be needed by some items
472  SetElementVisibility( ii, true );
473 }
474 
475 
477 {
479 }
480 
481 
483 {
485 }
486 
487 
488 void BOARD::SetElementVisibility( GAL_LAYER_ID aLayer, bool isEnabled )
489 {
490  if( m_project )
492 
493  switch( aLayer )
494  {
495  case LAYER_RATSNEST:
496  {
497  // because we have a tool to show/hide ratsnest relative to a pad or a module
498  // so the hide/show option is a per item selection
499 
500  for( auto track : Tracks() )
501  track->SetLocalRatsnestVisible( isEnabled );
502 
503  for( auto mod : Modules() )
504  {
505  for( auto pad : mod->Pads() )
506  pad->SetLocalRatsnestVisible( isEnabled );
507  }
508 
509  for( int i = 0; i<GetAreaCount(); i++ )
510  {
511  auto zone = GetArea( i );
512  zone->SetLocalRatsnestVisible( isEnabled );
513  }
514 
515  break;
516  }
517 
518  default:
519  ;
520  }
521 }
522 
523 
525 {
526  switch( aLayer )
527  {
528  case F_Cu:
529  return IsElementVisible( LAYER_MOD_FR );
530 
531  case B_Cu:
532  return IsElementVisible( LAYER_MOD_BK );
533 
534  default:
535  wxFAIL_MSG( wxT( "BOARD::IsModuleLayerVisible() param error: bad layer" ) );
536  return true;
537  }
538 }
539 
540 
541 void BOARD::Add( BOARD_ITEM* aBoardItem, ADD_MODE aMode )
542 {
543  if( aBoardItem == NULL )
544  {
545  wxFAIL_MSG( wxT( "BOARD::Add() param error: aBoardItem NULL" ) );
546  return;
547  }
548 
549  switch( aBoardItem->Type() )
550  {
551  case PCB_NETINFO_T:
552  m_NetInfo.AppendNet( (NETINFO_ITEM*) aBoardItem );
553  break;
554 
555  // this one uses a vector
556  case PCB_MARKER_T:
557  m_markers.push_back( (MARKER_PCB*) aBoardItem );
558  break;
559 
560  // this one uses a vector
561  case PCB_ZONE_AREA_T:
562  m_ZoneDescriptorList.push_back( (ZONE_CONTAINER*) aBoardItem );
563  break;
564 
565  case PCB_TRACE_T:
566  case PCB_VIA_T:
567  case PCB_ARC_T:
568 
569  // N.B. This inserts a small memory leak as we lose the
570  if( !IsCopperLayer( aBoardItem->GetLayer() ) )
571  {
572  wxFAIL_MSG( wxT( "BOARD::Add() Cannot place Track on non-copper layer" ) );
573  return;
574  }
575 
576  if( aMode == ADD_MODE::APPEND )
577  m_tracks.push_back( static_cast<TRACK*>( aBoardItem ) );
578  else
579  m_tracks.push_front( static_cast<TRACK*>( aBoardItem ) );
580 
581  break;
582 
583  case PCB_MODULE_T:
584  if( aMode == ADD_MODE::APPEND )
585  m_modules.push_back( (MODULE*) aBoardItem );
586  else
587  m_modules.push_front( (MODULE*) aBoardItem );
588 
589  break;
590 
591  case PCB_DIMENSION_T:
592  case PCB_LINE_T:
593  case PCB_TEXT_T:
594  case PCB_TARGET_T:
595  if( aMode == ADD_MODE::APPEND )
596  m_drawings.push_back( aBoardItem );
597  else
598  m_drawings.push_front( aBoardItem );
599 
600  break;
601 
602  // other types may use linked list
603  default:
604  {
605  wxString msg;
606  msg.Printf( wxT( "BOARD::Add() needs work: BOARD_ITEM type (%d) not handled" ),
607  aBoardItem->Type() );
608  wxFAIL_MSG( msg );
609  return;
610  }
611  break;
612  }
613 
614  aBoardItem->SetParent( this );
615  aBoardItem->ClearEditFlags();
616  m_connectivity->Add( aBoardItem );
617 
618  InvokeListeners( &BOARD_LISTENER::OnBoardItemAdded, *this, aBoardItem );
619 }
620 
621 
622 void BOARD::Remove( BOARD_ITEM* aBoardItem )
623 {
624  // find these calls and fix them! Don't send me no stinking' NULL.
625  wxASSERT( aBoardItem );
626 
627  switch( aBoardItem->Type() )
628  {
629  case PCB_NETINFO_T:
630  {
631  NETINFO_ITEM* item = (NETINFO_ITEM*) aBoardItem;
632  m_NetInfo.RemoveNet( item );
633  break;
634  }
635 
636  case PCB_MARKER_T:
637 
638  // find the item in the vector, then remove it
639  for( unsigned i = 0; i<m_markers.size(); ++i )
640  {
641  if( m_markers[i] == (MARKER_PCB*) aBoardItem )
642  {
643  m_markers.erase( m_markers.begin() + i );
644  break;
645  }
646  }
647 
648  break;
649 
650  case PCB_ZONE_AREA_T: // this one uses a vector
651  // find the item in the vector, then delete then erase it.
652  for( unsigned i = 0; i<m_ZoneDescriptorList.size(); ++i )
653  {
654  if( m_ZoneDescriptorList[i] == (ZONE_CONTAINER*) aBoardItem )
655  {
656  m_ZoneDescriptorList.erase( m_ZoneDescriptorList.begin() + i );
657  break;
658  }
659  }
660  break;
661 
662  case PCB_MODULE_T:
663  m_modules.erase( std::remove_if( m_modules.begin(), m_modules.end(),
664  [aBoardItem]( BOARD_ITEM* aItem )
665  {
666  return aItem == aBoardItem;
667  } ) );
668  break;
669 
670  case PCB_TRACE_T:
671  case PCB_ARC_T:
672  case PCB_VIA_T:
673  m_tracks.erase( std::remove_if( m_tracks.begin(), m_tracks.end(),
674  [aBoardItem]( BOARD_ITEM* aItem )
675  {
676  return aItem == aBoardItem;
677  } ) );
678  break;
679 
680  case PCB_DIMENSION_T:
681  case PCB_LINE_T:
682  case PCB_TEXT_T:
683  case PCB_TARGET_T:
684  m_drawings.erase( std::remove_if( m_drawings.begin(), m_drawings.end(),
685  [aBoardItem](BOARD_ITEM* aItem)
686  {
687  return aItem == aBoardItem;
688  } ) );
689  break;
690 
691  // other types may use linked list
692  default:
693  wxFAIL_MSG( wxT( "BOARD::Remove() needs more ::Type() support" ) );
694  }
695 
696  m_connectivity->Remove( aBoardItem );
697 
699 }
700 
701 
702 wxString BOARD::GetSelectMenuText( EDA_UNITS aUnits ) const
703 {
704  return wxString::Format( _( "PCB" ) );
705 }
706 
707 
709 {
710  // the vector does not know how to delete the MARKER_PCB, it holds pointers
711  for( MARKER_PCB* marker : m_markers )
712  delete marker;
713 
714  m_markers.clear();
715 }
716 
717 
718 void BOARD::DeleteMARKERs( bool aWarningsAndErrors, bool aExclusions )
719 {
720  // Deleting lots of items from a vector can be very slow. Copy remaining items instead.
721  MARKERS remaining;
722 
723  for( MARKER_PCB* marker : m_markers )
724  {
725  if( ( marker->IsExcluded() && aExclusions )
726  || ( !marker->IsExcluded() && aWarningsAndErrors ) )
727  {
728  delete marker;
729  }
730  else
731  {
732  remaining.push_back( marker );
733  }
734  }
735 
736  m_markers = remaining;
737 }
738 
739 
741 {
742  // the vector does not know how to delete the ZONE Outlines, it holds pointers
743  for( ZONE_CONTAINER* zone : m_ZoneDescriptorList )
744  delete zone;
745 
746  m_ZoneDescriptorList.clear();
747 }
748 
749 
751 {
752  if( aID == niluuid )
753  return nullptr;
754 
755  for( TRACK* track : Tracks() )
756  if( track->m_Uuid == aID )
757  return track;
758 
759  for( MODULE* module : Modules() )
760  {
761  if( module->m_Uuid == aID )
762  return module;
763 
764  for( D_PAD* pad : module->Pads() )
765  if( pad->m_Uuid == aID )
766  return pad;
767 
768  if( module->Reference().m_Uuid == aID )
769  return &module->Reference();
770 
771  if( module->Value().m_Uuid == aID )
772  return &module->Value();
773 
774  for( BOARD_ITEM* drawing : module->GraphicalItems() )
775  if( drawing->m_Uuid == aID )
776  return drawing;
777  }
778 
779  for( ZONE_CONTAINER* zone : Zones() )
780  if( zone->m_Uuid == aID )
781  return zone;
782 
783  for( BOARD_ITEM* drawing : Drawings() )
784  if( drawing->m_Uuid == aID )
785  return drawing;
786 
787  for( MARKER_PCB* marker : m_markers )
788  if( marker->m_Uuid == aID )
789  return marker;
790 
791  if( m_Uuid == aID )
792  return this;
793 
794  // Not found; weak reference has been deleted.
796 }
797 
798 
799 void BOARD::FillItemMap( std::map<KIID, EDA_ITEM*>& aMap )
800 {
801  for( TRACK* track : Tracks() )
802  aMap[ track->m_Uuid ] = track;
803 
804  for( MODULE* module : Modules() )
805  {
806  aMap[ module->m_Uuid ] = module;
807 
808  for( D_PAD* pad : module->Pads() )
809  aMap[ pad->m_Uuid ] = pad;
810 
811  aMap[ module->Reference().m_Uuid ] = &module->Reference();
812  aMap[ module->Value().m_Uuid ] = &module->Value();
813 
814  for( BOARD_ITEM* drawing : module->GraphicalItems() )
815  aMap[ drawing->m_Uuid ] = drawing;
816  }
817 
818  for( ZONE_CONTAINER* zone : Zones() )
819  aMap[ zone->m_Uuid ] = zone;
820 
821  for( BOARD_ITEM* drawing : Drawings() )
822  aMap[ drawing->m_Uuid ] = drawing;
823 
824  for( MARKER_PCB* marker : m_markers )
825  aMap[ marker->m_Uuid ] = marker;
826 }
827 
828 
829 unsigned BOARD::GetNodesCount( int aNet )
830 {
831  unsigned retval = 0;
832  for( auto mod : Modules() )
833  {
834  for( auto pad : mod->Pads() )
835  {
836  if( ( aNet == -1 && pad->GetNetCode() > 0 ) || aNet == pad->GetNetCode() )
837  retval++;
838  }
839  }
840 
841  return retval;
842 }
843 
844 
846 {
847  return m_connectivity->GetUnconnectedCount();
848 }
849 
850 
851 EDA_RECT BOARD::ComputeBoundingBox( bool aBoardEdgesOnly ) const
852 {
853  EDA_RECT area;
854  LSET visible = GetVisibleLayers();
855  bool showInvisibleText = IsElementVisible( LAYER_MOD_TEXT_INVISIBLE )
856  && PgmOrNull() && !PgmOrNull()->m_Printing;
857 
858  // Check segments, dimensions, texts, and fiducials
859  for( auto item : m_drawings )
860  {
861  if( aBoardEdgesOnly && ( item->GetLayer() != Edge_Cuts ) )
862  continue;
863 
864  if( ( item->GetLayerSet() & visible ).any() )
865  area.Merge( item->GetBoundingBox() );
866  }
867 
868  // Check modules
869  for( auto module : m_modules )
870  {
871  if( !( module->GetLayerSet() & visible ).any() )
872  continue;
873 
874  if( aBoardEdgesOnly )
875  {
876  for( const auto edge : module->GraphicalItems() )
877  {
878  if( edge->GetLayer() == Edge_Cuts )
879  area.Merge( edge->GetBoundingBox() );
880  }
881  }
882  else
883  {
884  area.Merge( module->GetBoundingBox( showInvisibleText ) );
885  }
886  }
887 
888  if( !aBoardEdgesOnly )
889  {
890  // Check tracks
891  for( auto track : m_tracks )
892  {
893  if( ( track->GetLayerSet() & visible ).any() )
894  area.Merge( track->GetBoundingBox() );
895  }
896 
897  // Check zones
898  for( auto aZone : m_ZoneDescriptorList )
899  {
900  if( ( aZone->GetLayerSet() & visible ).any() )
901  area.Merge( aZone->GetBoundingBox() );
902  }
903  }
904 
905  return area;
906 }
907 
908 
909 void BOARD::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
910 {
911  wxString txt;
912  int viasCount = 0;
913  int trackSegmentsCount = 0;
914 
915  for( auto item : m_tracks )
916  {
917  if( item->Type() == PCB_VIA_T )
918  viasCount++;
919  else
920  trackSegmentsCount++;
921  }
922 
923  txt.Printf( wxT( "%d" ), GetPadCount() );
924  aList.emplace_back( _( "Pads" ), txt, DARKGREEN );
925 
926  txt.Printf( wxT( "%d" ), viasCount );
927  aList.emplace_back( _( "Vias" ), txt, DARKGREEN );
928 
929  txt.Printf( wxT( "%d" ), trackSegmentsCount );
930  aList.emplace_back( _( "Track Segments" ), txt, DARKGREEN );
931 
932  txt.Printf( wxT( "%d" ), GetNodesCount() );
933  aList.emplace_back( _( "Nodes" ), txt, DARKCYAN );
934 
935  txt.Printf( wxT( "%d" ), m_NetInfo.GetNetCount() - 1 /* Don't include "No Net" in count */ );
936  aList.emplace_back( _( "Nets" ), txt, RED );
937 
938  txt.Printf( wxT( "%d" ), GetConnectivity()->GetUnconnectedCount() );
939  aList.emplace_back( _( "Unrouted" ), txt, BLUE );
940 }
941 
942 
943 SEARCH_RESULT BOARD::Visit( INSPECTOR inspector, void* testData, const KICAD_T scanTypes[] )
944 {
945  KICAD_T stype;
947  const KICAD_T* p = scanTypes;
948  bool done = false;
949 
950 #if 0 && defined(DEBUG)
951  std::cout << GetClass().mb_str() << ' ';
952 #endif
953 
954  while( !done )
955  {
956  stype = *p;
957 
958  switch( stype )
959  {
960  case PCB_T:
961  result = inspector( this, testData ); // inspect me
962  // skip over any types handled in the above call.
963  ++p;
964  break;
965 
966  /* Instances of the requested KICAD_T live in a list, either one
967  * that I manage, or that my modules manage. If it's a type managed
968  * by class MODULE, then simply pass it on to each module's
969  * MODULE::Visit() function by way of the
970  * IterateForward( m_Modules, ... ) call.
971  */
972 
973  case PCB_MODULE_T:
974  case PCB_PAD_T:
975  case PCB_MODULE_TEXT_T:
976  case PCB_MODULE_EDGE_T:
978 
979  // this calls MODULE::Visit() on each module.
980  result = IterateForward<MODULE*>( m_modules, inspector, testData, p );
981 
982  // skip over any types handled in the above call.
983  for( ; ; )
984  {
985  switch( stype = *++p )
986  {
987  case PCB_MODULE_T:
988  case PCB_PAD_T:
989  case PCB_MODULE_TEXT_T:
990  case PCB_MODULE_EDGE_T:
992  continue;
993 
994  default:
995  ;
996  }
997 
998  break;
999  }
1000 
1001  break;
1002 
1003  case PCB_LINE_T:
1004  case PCB_TEXT_T:
1005  case PCB_DIMENSION_T:
1006  case PCB_TARGET_T:
1007  result = IterateForward<BOARD_ITEM*>( m_drawings, inspector, testData, p );
1008 
1009  // skip over any types handled in the above call.
1010  for( ; ; )
1011  {
1012  switch( stype = *++p )
1013  {
1014  case PCB_LINE_T:
1015  case PCB_TEXT_T:
1016  case PCB_DIMENSION_T:
1017  case PCB_TARGET_T:
1018  continue;
1019 
1020  default:
1021  ;
1022  }
1023 
1024  break;
1025  }
1026 
1027  ;
1028  break;
1029 
1030 #if 0 // both these are on same list, so we must scan it twice in order
1031  // to get VIA priority, using new #else code below.
1032  // But we are not using separate lists for TRACKs and VIA, because
1033  // items are ordered (sorted) in the linked
1034  // list by netcode AND by physical distance:
1035  // when created, if a track or via is connected to an existing track or
1036  // via, it is put in linked list after this existing track or via
1037  // So usually, connected tracks or vias are grouped in this list
1038  // So the algorithm (used in ratsnest computations) which computes the
1039  // track connectivity is faster (more than 100 time regarding to
1040  // a non ordered list) because when it searches for a connection, first
1041  // it tests the near (near in term of linked list) 50 items
1042  // from the current item (track or via) in test.
1043  // Usually, because of this sort, a connected item (if exists) is
1044  // found.
1045  // If not found (and only in this case) an exhaustive (and time
1046  // consuming) search is made, but this case is statistically rare.
1047  case PCB_VIA_T:
1048  case PCB_TRACE_T:
1049  case PCB_ARC_T:
1050  result = IterateForward( m_Track, inspector, testData, p );
1051 
1052  // skip over any types handled in the above call.
1053  for( ; ; )
1054  {
1055  switch( stype = *++p )
1056  {
1057  case PCB_VIA_T:
1058  case PCB_TRACE_T:
1059  case PCB_ARC_T:
1060  continue;
1061 
1062  default:
1063  ;
1064  }
1065 
1066  break;
1067  }
1068 
1069  break;
1070 
1071 #else
1072  case PCB_VIA_T:
1073  result = IterateForward<TRACK*>( m_tracks, inspector, testData, p );
1074  ++p;
1075  break;
1076 
1077  case PCB_TRACE_T:
1078  case PCB_ARC_T:
1079  result = IterateForward<TRACK*>( m_tracks, inspector, testData, p );
1080  ++p;
1081  break;
1082 #endif
1083 
1084  case PCB_MARKER_T:
1085 
1086  // MARKER_PCBS are in the m_markers std::vector
1087  for( unsigned i = 0; i<m_markers.size(); ++i )
1088  {
1089  result = m_markers[i]->Visit( inspector, testData, p );
1090 
1091  if( result == SEARCH_RESULT::QUIT )
1092  break;
1093  }
1094 
1095  ++p;
1096  break;
1097 
1098  case PCB_ZONE_AREA_T:
1099 
1100  // PCB_ZONE_AREA_T are in the m_ZoneDescriptorList std::vector
1101  for( unsigned i = 0; i< m_ZoneDescriptorList.size(); ++i )
1102  {
1103  result = m_ZoneDescriptorList[i]->Visit( inspector, testData, p );
1104 
1105  if( result == SEARCH_RESULT::QUIT )
1106  break;
1107  }
1108 
1109  ++p;
1110  break;
1111 
1112  default: // catch EOT or ANY OTHER type here and return.
1113  done = true;
1114  break;
1115  }
1116 
1117  if( result == SEARCH_RESULT::QUIT )
1118  break;
1119  }
1120 
1121  return result;
1122 }
1123 
1124 
1125 NETINFO_ITEM* BOARD::FindNet( int aNetcode ) const
1126 {
1127  // the first valid netcode is 1 and the last is m_NetInfo.GetCount()-1.
1128  // zero is reserved for "no connection" and is not actually a net.
1129  // NULL is returned for non valid netcodes
1130 
1131  wxASSERT( m_NetInfo.GetNetCount() > 0 );
1132 
1133  if( aNetcode == NETINFO_LIST::UNCONNECTED && m_NetInfo.GetNetCount() == 0 )
1134  return NETINFO_LIST::OrphanedItem();
1135  else
1136  return m_NetInfo.GetNetItem( aNetcode );
1137 }
1138 
1139 
1140 NETINFO_ITEM* BOARD::FindNet( const wxString& aNetname ) const
1141 {
1142  return m_NetInfo.GetNetItem( aNetname );
1143 }
1144 
1145 
1146 MODULE* BOARD::FindModuleByReference( const wxString& aReference ) const
1147 {
1148  MODULE* found = nullptr;
1149 
1150  // search only for MODULES
1151  static const KICAD_T scanTypes[] = { PCB_MODULE_T, EOT };
1152 
1153  INSPECTOR_FUNC inspector = [&] ( EDA_ITEM* item, void* testData )
1154  {
1155  MODULE* module = (MODULE*) item;
1156 
1157  if( aReference == module->GetReference() )
1158  {
1159  found = module;
1160  return SEARCH_RESULT::QUIT;
1161  }
1162 
1163  return SEARCH_RESULT::CONTINUE;
1164  };
1165 
1166  // visit this BOARD with the above inspector
1167  BOARD* nonconstMe = (BOARD*) this;
1168  nonconstMe->Visit( inspector, NULL, scanTypes );
1169 
1170  return found;
1171 }
1172 
1173 
1175 {
1176  for( MODULE* module : m_modules )
1177  {
1178  if( module->GetPath() == aPath )
1179  return module;
1180  }
1181 
1182  return nullptr;
1183 }
1184 
1185 
1186 // The pad count for each netcode, stored in a buffer for a fast access.
1187 // This is needed by the sort function sortNetsByNodes()
1188 static std::vector<int> padCountListByNet;
1189 
1190 // Sort nets by decreasing pad count.
1191 // For same pad count, sort by alphabetic names
1192 static bool sortNetsByNodes( const NETINFO_ITEM* a, const NETINFO_ITEM* b )
1193 {
1194  int countA = padCountListByNet[a->GetNet()];
1195  int countB = padCountListByNet[b->GetNet()];
1196 
1197  if( countA == countB )
1198  return a->GetNetname() < b->GetNetname();
1199  else
1200  return countB < countA;
1201 }
1202 
1203 // Sort nets by alphabetic names
1204 static bool sortNetsByNames( const NETINFO_ITEM* a, const NETINFO_ITEM* b )
1205 {
1206  return a->GetNetname() < b->GetNetname();
1207 }
1208 
1209 int BOARD::SortedNetnamesList( wxArrayString& aNames, bool aSortbyPadsCount )
1210 {
1211  if( m_NetInfo.GetNetCount() == 0 )
1212  return 0;
1213 
1214  // Build the list
1215  std::vector <NETINFO_ITEM*> netBuffer;
1216 
1217  netBuffer.reserve( m_NetInfo.GetNetCount() );
1218  int max_netcode = 0;
1219 
1220  for( NETINFO_ITEM* net : m_NetInfo )
1221  {
1222  auto netcode = net->GetNet();
1223 
1224  if( netcode > 0 && net->IsCurrent() )
1225  {
1226  netBuffer.push_back( net );
1227  max_netcode = std::max( netcode, max_netcode);
1228  }
1229  }
1230 
1231  // sort the list
1232  if( aSortbyPadsCount )
1233  {
1234  // Build the pad count by net:
1235  padCountListByNet.clear();
1236  std::vector<D_PAD*> pads = GetPads();
1237 
1238  padCountListByNet.assign( max_netcode + 1, 0 );
1239 
1240  for( D_PAD* pad : pads )
1241  {
1242  int netCode = pad->GetNetCode();
1243 
1244  if( netCode >= 0 )
1245  padCountListByNet[ netCode ]++;
1246  }
1247 
1248  sort( netBuffer.begin(), netBuffer.end(), sortNetsByNodes );
1249  }
1250  else
1251  {
1252  sort( netBuffer.begin(), netBuffer.end(), sortNetsByNames );
1253  }
1254 
1255  for( NETINFO_ITEM* net : netBuffer )
1256  aNames.Add( UnescapeString( net->GetNetname() ) );
1257 
1258  return netBuffer.size();
1259 }
1260 
1261 
1263 {
1264  std::vector<wxString> names;
1265 
1266  for( NETINFO_ITEM* net : m_NetInfo )
1267  {
1268  if( !net->GetShortNetname().IsEmpty() )
1269  names.emplace_back( net->GetShortNetname() );
1270  }
1271 
1272  return names;
1273 }
1274 
1275 
1277 {
1278  if( m_project )
1279  {
1280  NET_SETTINGS* netSettings = m_project->GetProjectFile().m_NetSettings.get();
1281  NETCLASSES& netClasses = netSettings->m_NetClasses;
1282  NETCLASSPTR defaultNetClass = netClasses.GetDefault();
1283 
1284  for( NETINFO_ITEM* net : m_NetInfo )
1285  {
1286  const wxString& netname = net->GetNetname();
1287  const wxString& shortname = net->GetShortNetname();
1288 
1289  if( netSettings->m_NetClassAssignments.count( netname ) )
1290  {
1291  const wxString& classname = netSettings->m_NetClassAssignments[ netname ];
1292  net->SetClass( netClasses.Find( classname ) );
1293  }
1294  else if( netSettings->m_NetClassAssignments.count( shortname ) )
1295  {
1296  const wxString& classname = netSettings->m_NetClassAssignments[ shortname ];
1297  net->SetClass( netClasses.Find( classname ) );
1298  }
1299  else
1300  {
1301  net->SetClass( defaultNetClass );
1302  }
1303  }
1304 
1306 
1307  // Set initial values for custom track width & via size to match the default netclass settings
1308  bds.UseCustomTrackViaSize( false );
1309  bds.SetCustomTrackWidth( defaultNetClass->GetTrackWidth() );
1310  bds.SetCustomViaSize( defaultNetClass->GetViaDiameter() );
1311  bds.SetCustomViaDrill( defaultNetClass->GetViaDrill() );
1312  bds.SetCustomDiffPairWidth( defaultNetClass->GetDiffPairWidth() );
1313  bds.SetCustomDiffPairGap( defaultNetClass->GetDiffPairGap() );
1314  bds.SetCustomDiffPairViaGap( defaultNetClass->GetDiffPairViaGap() );
1315  }
1316 
1318 }
1319 
1320 
1322 {
1323  int error_count = 0;
1324 
1325  for( int ii = 0; ii < GetAreaCount(); ii++ )
1326  {
1327  ZONE_CONTAINER* it = GetArea( ii );
1328 
1329  if( !it->IsOnCopperLayer() )
1330  {
1332  continue;
1333  }
1334 
1335  if( it->GetNetCode() != 0 ) // i.e. if this zone is connected to a net
1336  {
1337  const NETINFO_ITEM* net = it->GetNet();
1338 
1339  if( net )
1340  {
1341  it->SetNetCode( net->GetNet() );
1342  }
1343  else
1344  {
1345  error_count++;
1346 
1347  // keep Net Name and set m_NetCode to -1 : error flag.
1348  it->SetNetCode( -1 );
1349  }
1350  }
1351  }
1352 
1353  return error_count;
1354 }
1355 
1356 
1357 D_PAD* BOARD::GetPad( const wxPoint& aPosition, LSET aLayerSet )
1358 {
1359  if( !aLayerSet.any() )
1360  aLayerSet = LSET::AllCuMask();
1361 
1362  for( auto module : m_modules )
1363  {
1364  D_PAD* pad = NULL;
1365 
1366  if( module->HitTest( aPosition ) )
1367  pad = module->GetPad( aPosition, aLayerSet );
1368 
1369  if( pad )
1370  return pad;
1371  }
1372 
1373  return NULL;
1374 }
1375 
1376 
1377 D_PAD* BOARD::GetPad( TRACK* aTrace, ENDPOINT_T aEndPoint )
1378 {
1379  const wxPoint& aPosition = aTrace->GetEndPoint( aEndPoint );
1380 
1381  LSET lset( aTrace->GetLayer() );
1382 
1383  return GetPad( aPosition, lset );
1384 }
1385 
1386 
1387 D_PAD* BOARD::GetPadFast( const wxPoint& aPosition, LSET aLayerSet )
1388 {
1389  for( auto mod : Modules() )
1390  {
1391  for ( auto pad : mod->Pads() )
1392  {
1393  if( pad->GetPosition() != aPosition )
1394  continue;
1395 
1396  // Pad found, it must be on the correct layer
1397  if( ( pad->GetLayerSet() & aLayerSet ).any() )
1398  return pad;
1399  }
1400  }
1401 
1402  return nullptr;
1403 }
1404 
1405 
1406 D_PAD* BOARD::GetPad( std::vector<D_PAD*>& aPadList, const wxPoint& aPosition, LSET aLayerSet )
1407 {
1408  // Search aPadList for aPosition
1409  // aPadList is sorted by X then Y values, and a fast binary search is used
1410  int idxmax = aPadList.size()-1;
1411 
1412  int delta = aPadList.size();
1413 
1414  int idx = 0; // Starting index is the beginning of list
1415 
1416  while( delta )
1417  {
1418  // Calculate half size of remaining interval to test.
1419  // Ensure the computed value is not truncated (too small)
1420  if( (delta & 1) && ( delta > 1 ) )
1421  delta++;
1422 
1423  delta /= 2;
1424 
1425  D_PAD* pad = aPadList[idx];
1426 
1427  if( pad->GetPosition() == aPosition ) // candidate found
1428  {
1429  // The pad must match the layer mask:
1430  if( ( aLayerSet & pad->GetLayerSet() ).any() )
1431  return pad;
1432 
1433  // More than one pad can be at aPosition
1434  // search for a pad at aPosition that matched this mask
1435 
1436  // search next
1437  for( int ii = idx+1; ii <= idxmax; ii++ )
1438  {
1439  pad = aPadList[ii];
1440 
1441  if( pad->GetPosition() != aPosition )
1442  break;
1443 
1444  if( ( aLayerSet & pad->GetLayerSet() ).any() )
1445  return pad;
1446  }
1447  // search previous
1448  for( int ii = idx-1 ;ii >=0; ii-- )
1449  {
1450  pad = aPadList[ii];
1451 
1452  if( pad->GetPosition() != aPosition )
1453  break;
1454 
1455  if( ( aLayerSet & pad->GetLayerSet() ).any() )
1456  return pad;
1457  }
1458 
1459  // Not found:
1460  return 0;
1461  }
1462 
1463  if( pad->GetPosition().x == aPosition.x ) // Must search considering Y coordinate
1464  {
1465  if( pad->GetPosition().y < aPosition.y ) // Must search after this item
1466  {
1467  idx += delta;
1468 
1469  if( idx > idxmax )
1470  idx = idxmax;
1471  }
1472  else // Must search before this item
1473  {
1474  idx -= delta;
1475 
1476  if( idx < 0 )
1477  idx = 0;
1478  }
1479  }
1480  else if( pad->GetPosition().x < aPosition.x ) // Must search after this item
1481  {
1482  idx += delta;
1483 
1484  if( idx > idxmax )
1485  idx = idxmax;
1486  }
1487  else // Must search before this item
1488  {
1489  idx -= delta;
1490 
1491  if( idx < 0 )
1492  idx = 0;
1493  }
1494  }
1495 
1496  return NULL;
1497 }
1498 
1499 
1505 bool sortPadsByXthenYCoord( D_PAD* const & ref, D_PAD* const & comp )
1506 {
1507  if( ref->GetPosition().x == comp->GetPosition().x )
1508  return ref->GetPosition().y < comp->GetPosition().y;
1509  return ref->GetPosition().x < comp->GetPosition().x;
1510 }
1511 
1512 
1513 void BOARD::GetSortedPadListByXthenYCoord( std::vector<D_PAD*>& aVector, int aNetCode )
1514 {
1515  for ( auto mod : Modules() )
1516  {
1517  for ( auto pad : mod->Pads( ) )
1518  {
1519  if( aNetCode < 0 || pad->GetNetCode() == aNetCode )
1520  {
1521  aVector.push_back( pad );
1522  }
1523  }
1524  }
1525 
1526  std::sort( aVector.begin(), aVector.end(), sortPadsByXthenYCoord );
1527 }
1528 
1529 
1531 {
1532  GetConnectivity()->Remove( aPad );
1533 
1535 
1536  aPad->DeleteStructure();
1537 }
1538 
1539 
1540 std::tuple<int, double, double> BOARD::GetTrackLength( const TRACK& aTrack ) const
1541 {
1542  int count = 0;
1543  double length = 0.0;
1544  double package_length = 0.0;
1545 
1546  constexpr KICAD_T types[] = { PCB_TRACE_T, PCB_ARC_T, PCB_VIA_T, PCB_PAD_T, EOT };
1547  auto connectivity = GetBoard()->GetConnectivity();
1548 
1549  for( auto item : connectivity->GetConnectedItems(
1550  static_cast<const BOARD_CONNECTED_ITEM*>( &aTrack ), types ) )
1551  {
1552  count++;
1553 
1554  if( auto track = dyn_cast<TRACK*>( item ) )
1555  {
1556  bool inPad = false;
1557 
1558  for( auto pad_it : connectivity->GetConnectedPads( item ) )
1559  {
1560  auto pad = static_cast<D_PAD*>( pad_it );
1561 
1562  if( pad->HitTest( track->GetStart(), track->GetWidth() / 2 )
1563  && pad->HitTest( track->GetEnd(), track->GetWidth() / 2 ) )
1564  {
1565  inPad = true;
1566  break;
1567  }
1568  }
1569 
1570  if( !inPad )
1571  length += track->GetLength();
1572  }
1573  else if( auto pad = dyn_cast<D_PAD*>( item ) )
1574  package_length += pad->GetPadToDieLength();
1575  }
1576 
1577  return std::make_tuple( count, length, package_length );
1578 }
1579 
1580 
1581 MODULE* BOARD::GetFootprint( const wxPoint& aPosition, PCB_LAYER_ID aActiveLayer,
1582  bool aVisibleOnly, bool aIgnoreLocked )
1583 {
1584  MODULE* module = NULL;
1585  MODULE* alt_module = NULL;
1586  int min_dim = 0x7FFFFFFF;
1587  int alt_min_dim = 0x7FFFFFFF;
1588  bool current_layer_back = IsBackLayer( aActiveLayer );
1589 
1590  for( auto pt_module : m_modules )
1591  {
1592  // is the ref point within the module's bounds?
1593  if( !pt_module->HitTest( aPosition ) )
1594  continue;
1595 
1596  // if caller wants to ignore locked modules, and this one is locked, skip it.
1597  if( aIgnoreLocked && pt_module->IsLocked() )
1598  continue;
1599 
1600  PCB_LAYER_ID layer = pt_module->GetLayer();
1601 
1602  // Filter non visible modules if requested
1603  if( !aVisibleOnly || IsModuleLayerVisible( layer ) )
1604  {
1605  EDA_RECT bb = pt_module->GetFootprintRect();
1606 
1607  int offx = bb.GetX() + bb.GetWidth() / 2;
1608  int offy = bb.GetY() + bb.GetHeight() / 2;
1609 
1610  // off x & offy point to the middle of the box.
1611  int dist = ( aPosition.x - offx ) * ( aPosition.x - offx ) +
1612  ( aPosition.y - offy ) * ( aPosition.y - offy );
1613 
1614  if( current_layer_back == IsBackLayer( layer ) )
1615  {
1616  if( dist <= min_dim )
1617  {
1618  // better footprint shown on the active side
1619  module = pt_module;
1620  min_dim = dist;
1621  }
1622  }
1623  else if( aVisibleOnly && IsModuleLayerVisible( layer ) )
1624  {
1625  if( dist <= alt_min_dim )
1626  {
1627  // better footprint shown on the other side
1628  alt_module = pt_module;
1629  alt_min_dim = dist;
1630  }
1631  }
1632  }
1633  }
1634 
1635  if( module )
1636  {
1637  return module;
1638  }
1639 
1640  if( alt_module)
1641  {
1642  return alt_module;
1643  }
1644 
1645  return NULL;
1646 }
1647 
1648 std::list<ZONE_CONTAINER*> BOARD::GetZoneList( bool aIncludeZonesInFootprints )
1649 {
1650  std::list<ZONE_CONTAINER*> zones;
1651 
1652  for( int ii = 0; ii < GetAreaCount(); ii++ )
1653  {
1654  zones.push_back( GetArea( ii ) );
1655  }
1656 
1657  if( aIncludeZonesInFootprints )
1658  {
1659  for( MODULE* mod : m_modules )
1660  {
1661  for( MODULE_ZONE_CONTAINER* zone : mod->Zones() )
1662  {
1663  zones.push_back( zone );
1664  }
1665  }
1666  }
1667 
1668  return zones;
1669 }
1670 
1671 
1672 ZONE_CONTAINER* BOARD::AddArea( PICKED_ITEMS_LIST* aNewZonesList, int aNetcode, PCB_LAYER_ID aLayer,
1673  wxPoint aStartPointPosition, ZONE_BORDER_DISPLAY_STYLE aHatch )
1674 {
1675  ZONE_CONTAINER* new_area = InsertArea( aNetcode,
1676  m_ZoneDescriptorList.size( ) - 1,
1677  aLayer, aStartPointPosition.x,
1678  aStartPointPosition.y, aHatch );
1679 
1680  if( aNewZonesList )
1681  {
1682  ITEM_PICKER picker( nullptr, new_area, UR_NEW );
1683  aNewZonesList->PushItem( picker );
1684  }
1685 
1686  return new_area;
1687 }
1688 
1689 
1690 void BOARD::RemoveArea( PICKED_ITEMS_LIST* aDeletedList, ZONE_CONTAINER* area_to_remove )
1691 {
1692  if( area_to_remove == NULL )
1693  return;
1694 
1695  if( aDeletedList )
1696  {
1697  ITEM_PICKER picker( nullptr, area_to_remove, UR_DELETED );
1698  aDeletedList->PushItem( picker );
1699  Remove( area_to_remove ); // remove from zone list, but does not delete it
1700  }
1701  else
1702  {
1703  Delete( area_to_remove );
1704  }
1705 }
1706 
1707 
1708 ZONE_CONTAINER* BOARD::InsertArea( int aNetcode, int aAreaIdx, PCB_LAYER_ID aLayer, int aCornerX,
1709  int aCornerY, ZONE_BORDER_DISPLAY_STYLE aHatch )
1710 {
1711  ZONE_CONTAINER* new_area = new ZONE_CONTAINER( this );
1712 
1713  new_area->SetNetCode( aNetcode );
1714  new_area->SetLayer( aLayer );
1715 
1716  if( aAreaIdx < (int) ( m_ZoneDescriptorList.size() - 1 ) )
1717  m_ZoneDescriptorList.insert( m_ZoneDescriptorList.begin() + aAreaIdx + 1, new_area );
1718  else
1719  m_ZoneDescriptorList.push_back( new_area );
1720 
1721  new_area->SetHatchStyle( (ZONE_BORDER_DISPLAY_STYLE) aHatch );
1722 
1723  // Add the first corner to the new zone
1724  new_area->AppendCorner( wxPoint( aCornerX, aCornerY ), -1 );
1725 
1726  return new_area;
1727 }
1728 
1729 
1731 {
1732  // mark all areas as unmodified except this one, if modified
1733  for( ZONE_CONTAINER* zone : m_ZoneDescriptorList )
1734  zone->SetLocalFlags( 0 );
1735 
1736  aCurrArea->SetLocalFlags( 1 );
1737 
1738  if( aCurrArea->Outline()->IsSelfIntersecting() )
1739  {
1740  aCurrArea->UnHatchBorder();
1741 
1742  // Normalize copied area and store resulting number of polygons
1743  int n_poly = aCurrArea->Outline()->NormalizeAreaOutlines();
1744 
1745  // If clipping has created some polygons, we must add these new copper areas.
1746  if( n_poly > 1 )
1747  {
1748  ZONE_CONTAINER* NewArea;
1749 
1750  // Move the newly created polygons to new areas, removing them from the current area
1751  for( int ip = 1; ip < n_poly; ip++ )
1752  {
1753  // Create new copper area and copy poly into it
1754  SHAPE_POLY_SET* new_p = new SHAPE_POLY_SET( aCurrArea->Outline()->UnitSet( ip ) );
1755  NewArea = AddArea( aNewZonesList, aCurrArea->GetNetCode(), aCurrArea->GetLayer(),
1756  wxPoint(0, 0), aCurrArea->GetHatchStyle() );
1757 
1758  // remove the poly that was automatically created for the new area
1759  // and replace it with a poly from NormalizeAreaOutlines
1760  delete NewArea->Outline();
1761  NewArea->SetOutline( new_p );
1762  NewArea->HatchBorder();
1763  NewArea->SetLocalFlags( 1 );
1764  }
1765 
1766  SHAPE_POLY_SET* new_p = new SHAPE_POLY_SET( aCurrArea->Outline()->UnitSet( 0 ) );
1767  delete aCurrArea->Outline();
1768  aCurrArea->SetOutline( new_p );
1769  }
1770  }
1771 
1772  aCurrArea->HatchBorder();
1773 
1774  return true;
1775 }
1776 
1777 
1778 /* Extracts the board outlines and build a closed polygon
1779  * from lines, arcs and circle items on edge cut layer
1780  * Any closed outline inside the main outline is a hole
1781  * All contours should be closed, i.e. are valid vertices for a closed polygon
1782  * return true if success, false if a contour is not valid
1783  */
1784 extern bool BuildBoardPolygonOutlines( BOARD* aBoard, SHAPE_POLY_SET& aOutlines,
1785  wxString* aErrorText, unsigned int aTolerance,
1786  wxPoint* aErrorLocation = nullptr );
1787 
1788 
1789 bool BOARD::GetBoardPolygonOutlines( SHAPE_POLY_SET& aOutlines, wxString* aErrorText, wxPoint* aErrorLocation )
1790 {
1791 
1792  bool success = BuildBoardPolygonOutlines( this, aOutlines, aErrorText,
1793  GetDesignSettings().m_MaxError, aErrorLocation );
1794 
1795  // Make polygon strictly simple to avoid issues (especially in 3D viewer)
1797 
1798  return success;
1799 }
1800 
1801 
1802 const std::vector<D_PAD*> BOARD::GetPads()
1803 {
1804  std::vector<D_PAD*> allPads;
1805 
1806  for( MODULE* mod : Modules() )
1807  {
1808  for( D_PAD* pad : mod->Pads() )
1809  allPads.push_back( pad );
1810  }
1811 
1812  return allPads;
1813 }
1814 
1815 
1817 {
1818  unsigned retval = 0;
1819 
1820  for( auto mod : Modules() )
1821  retval += mod->Pads().size();
1822 
1823  return retval;
1824 }
1825 
1826 
1831 D_PAD* BOARD::GetPad( unsigned aIndex ) const
1832 {
1833  unsigned count = 0;
1834 
1835  for( auto mod : m_modules )
1836  {
1837  for( auto pad : mod->Pads() )
1838  {
1839  if( count == aIndex )
1840  return pad;
1841 
1842  count++;
1843  }
1844  }
1845 
1846  return nullptr;
1847 }
1848 
1849 
1850 const std::vector<BOARD_CONNECTED_ITEM*> BOARD::AllConnectedItems()
1851 {
1852  std::vector<BOARD_CONNECTED_ITEM*> items;
1853 
1854  for( auto track : Tracks() )
1855  {
1856  items.push_back( track );
1857  }
1858 
1859  for( auto mod : Modules() )
1860  {
1861  for( auto pad : mod->Pads() )
1862  {
1863  items.push_back( pad );
1864  }
1865  }
1866 
1867  for( int i = 0; i<GetAreaCount(); i++ )
1868  {
1869  auto zone = GetArea( i );
1870  items.push_back( zone );
1871  }
1872 
1873  return items;
1874 }
1875 
1876 
1878 {
1879  for( BOARD_CONNECTED_ITEM* item : AllConnectedItems() )
1880  item->SetNetCode( 0 );
1881 }
1882 
1883 
1884 void BOARD::MapNets( const BOARD* aDestBoard )
1885 {
1886  for( BOARD_CONNECTED_ITEM* item : AllConnectedItems() )
1887  {
1888  NETINFO_ITEM* netInfo = aDestBoard->FindNet( item->GetNetname() );
1889 
1890  if( netInfo )
1891  item->SetNet( netInfo );
1892  else
1893  item->SetNetCode( 0 );
1894  }
1895 }
1896 
1897 
1899 {
1900  for ( BOARD_CONNECTED_ITEM* item : AllConnectedItems() )
1901  {
1902  if( FindNet( item->GetNetCode() ) == nullptr )
1903  item->SetNetCode( NETINFO_LIST::ORPHANED );
1904  }
1905 }
1906 
1907 
1909 {
1910  if( std::find( m_listeners.begin(), m_listeners.end(), aListener ) == m_listeners.end() )
1911  m_listeners.push_back( aListener );
1912 }
1913 
1914 
1916 {
1917  auto i = std::find( m_listeners.begin(), m_listeners.end(), aListener );
1918 
1919  if( i != m_listeners.end() )
1920  {
1921  std::iter_swap( i, m_listeners.end() - 1 );
1922  m_listeners.pop_back();
1923  }
1924 }
1925 
1926 
1928 {
1930 }
1931 
1932 
1934 {
1935  m_highLight.Clear();
1937 
1939 }
1940 
1941 
1942 void BOARD::SetHighLightNet( int aNetCode, bool aMulti )
1943 {
1944  if( !m_highLight.m_netCodes.count( aNetCode ) )
1945  {
1946  if( !aMulti )
1947  m_highLight.m_netCodes.clear();
1948 
1949  m_highLight.m_netCodes.insert( aNetCode );
1951  }
1952 }
1953 
1954 
1955 void BOARD::HighLightON( bool aValue )
1956 {
1957  if( m_highLight.m_highLightOn != aValue )
1958  {
1959  m_highLight.m_highLightOn = aValue;
1961  }
1962 }
MODULES m_modules
MODULES for components on the board, owned by pointer.
Definition: class_board.h:195
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Function AllCuMask returns a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:712
EDA_UNITS
Definition: common.h:198
LSET m_VisibleLayers
Board settings.
void InvokeListeners(Func &&aFunc, Args &&... args)
Definition: class_board.h:241
void AddListener(BOARD_LISTENER *aListener)
Add a listener to the board to receive calls whenever something on the board has been modified.
virtual void OnBoardItemRemoved(BOARD &aBoard, BOARD_ITEM *aBoardItem)
Definition: class_board.h:164
NETINFO_ITEM * FindNet(int aNetcode) const
Function FindNet searches for a net with the given netcode.
void SetNetClasses(NETCLASSES *aNetClasses)
void SetCopperLayerCount(int aNewLayerCount)
Function SetCopperLayerCount do what its name says...
void SetEnabledLayers(LSET aMask)
Function SetEnabledLayers changes the bit-mask of enabled layers.
ZONE_CONTAINER handles a list of polygons defining a copper zone.
Definition: class_zone.h:61
std::map< wxString, wxString > m_NetClassAssignments
Definition: net_settings.h:43
void HatchBorder()
Function HatchBorder computes the hatch lines depending on the hatch parameters and stores it in the ...
Definition: class_zone.cpp:961
const PCB_LAYER_ID GetLayerID(const wxString &aLayerName) const
Function GetLayerID returns the ID of a layer.
MODULE * FindModuleByPath(const KIID_PATH &aPath) const
Function FindModuleByPath searches for a MODULE within this board with the given path.
Class that draws missing connections on a PCB.
void DeleteZONEOutlines()
Function DeleteZONEOutlines deletes ALL zone outlines from the board.
int GetNetCode() const
Function GetNetCode.
Definition: typeinfo.h:85
std::function< SEARCH_RESULT(EDA_ITEM *aItem, void *aTestData) > INSPECTOR_FUNC
Typedef INSPECTOR is used to inspect and possibly collect the (search) results of iterating over a li...
Definition: base_struct.h:80
void Merge(const EDA_RECT &aRect)
Function Merge modifies the position and size of the rectangle in order to contain aRect.
void SetElementVisibility(GAL_LAYER_ID aLayer, bool aNewState)
Function SetElementVisibility changes the visibility of an element category.
PROJECT holds project specific data.
Definition: project.h:61
NETCLASSPTR Find(const wxString &aName) const
Function Find searches this container for a NETCLASS given by aName.
Definition: netclass.cpp:132
static const KICAD_T Tracks[]
A scan list for only TRACKS.
Definition: collectors.h:313
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:486
int GetCurrentViaDrill() const
Function GetCurrentViaDrill.
wxString m_name
The name of the layer, there should be no spaces in this name.
Definition: class_board.h:106
void PadDelete(D_PAD *aPad)
Function PadDelete deletes a given bad from the BOARD by removing it from its module and from the m_N...
bool m_LegacyNetclassesLoaded
True if netclasses were loaded from the file.
Definition: class_board.h:303
int GetCurrentTrackWidth() const
Function GetCurrentTrackWidth.
void SetCustomDiffPairViaGap(int aGap)
Function SetCustomDiffPairViaGap Sets custom via gap for differential pairs (i.e.
void HighLightON(bool aValue=true)
Enable or disable net highlighting.
BOARD_ITEM is a base class for any item which can be embedded within the BOARD container class,...
wxPoint GetPosition() const override
Definition: class_pad.h:165
int GetX() const
Definition: eda_rect.h:111
bool IsLayerEnabled(PCB_LAYER_ID aLayerId) const
Function IsLayerEnabled tests whether a given layer is enabled.
D_PAD * GetPadFast(const wxPoint &aPosition, LSET aLayerMask)
Function GetPadFast return pad found at aPosition on aLayerMask using the fast search method.
VTBL_ENTRY PROJECT_LOCAL_SETTINGS & GetLocalSettings() const
Definition: project.h:143
NETINFO_ITEM * GetNet() const
Function GetNet Returns NET_INFO object for a given item.
const wxString & GetName() const
Definition: netclass.h:96
bool IsBackLayer(PCB_LAYER_ID aLayerId)
Layer classification: check if it's a back layer.
void SetCustomViaDrill(int aDrill)
Function SetCustomViaDrill Sets custom size for via drill (i.e.
Class that computes missing connections on a PCB.
LAYER_T m_type
The type of the layer.
Definition: class_board.h:107
void GetSortedPadListByXthenYCoord(std::vector< D_PAD * > &aVector, int aNetCode=-1)
Function GetSortedPadListByXthenYCoord first empties then fills the vector with all pads and sorts th...
int NormalizeAreaOutlines()
Function NormalizeAreaOutlines Convert a self-intersecting polygon to one (or more) non self-intersec...
class ZONE_CONTAINER, a zone area
Definition: typeinfo.h:102
virtual PCB_LAYER_ID GetLayer() const override
Function GetLayer returns the primary layer this item is on.
Definition: class_zone.cpp:212
ZONE_CONTAINER * m_CurrentZoneContour
zone contour currently in progress
Definition: class_board.h:293
int GetWidth() const
Definition: eda_rect.h:119
SHAPE_POLY_SET * Outline()
Definition: class_zone.h:282
void DeleteStructure()
Function DeleteStructure deletes this object after removing from its parent if it has one.
GAL_LAYER_ID
GAL layers are "virtual" layers, i.e.
void SetCopperLayerCount(int aCount)
class TEXTE_PCB, text on a layer
Definition: typeinfo.h:92
bool SetNetCode(int aNetCode, bool aNoAssert)
Sets net using a net code.
LSET GetVisibleLayers() const
Function GetVisibleLayers is a proxy function that calls the correspondent function in m_BoardSetting...
void RemoveArea(PICKED_ITEMS_LIST *aDeletedList, ZONE_CONTAINER *area_to_remove)
Function RemoveArea remove copper area from net, and put it in a deleted list (if exists)
class ARC, an arc track segment on a copper layer
Definition: typeinfo.h:98
void SetVisibleElements(const GAL_SET &aMask)
Function SetVisibleElements is a proxy function that calls the correspondent function in m_BoardSetti...
void SetDescription(const wxString &aDesc)
Definition: netclass.h:156
NET_SETTINGS & NetSettings()
Definition: project_file.h:92
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:553
ZONE_BORDER_DISPLAY_STYLE GetHatchStyle() const
Definition: class_zone.h:577
void SetVisibleAlls()
Function SetVisibleAlls changes the bit-mask of visible element categories and layers.
void PushItem(const ITEM_PICKER &aItem)
Function PushItem pushes aItem to the top of the list.
class D_PAD, a pad in a footprint
Definition: typeinfo.h:90
void SetPosition(const wxPoint &aPos) override
virtual void OnBoardItemChanged(BOARD &aBoard, BOARD_ITEM *aBoardItem)
Definition: class_board.h:166
LSET GetEnabledLayers() const
Function GetEnabledLayers is a proxy function that calls the corresponding function in m_BoardSetting...
This is the end of the layers used for visibility bitmasks in Pcbnew There can be at most 32 layers a...
bool SetLayerType(PCB_LAYER_ID aLayer, LAYER_T aLayerType)
Function SetLayerType changes the type of the layer given by aLayer.
HIGH_LIGHT_INFO m_highLight
Definition: class_board.h:206
NETINFO_LIST m_NetInfo
Definition: class_board.h:230
HIGH_LIGHT_INFO m_highLightPrevious
Definition: class_board.h:207
The base class for create windows for drawing purpose.
bool IsLayerEnabled(PCB_LAYER_ID aLayer) const
Function IsLayerEnabled is a proxy function that calls the correspondent function in m_BoardSettings ...
Definition: class_board.h:465
D_PAD * GetPad(unsigned aIndex) const
Function GetPad.
TRACKS m_tracks
TRACKS for traces on the board, owned by pointer.
Definition: class_board.h:198
void GetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList) override
Function GetMsgPanelInfo populates aList of MSG_PANEL_ITEM objects with it's internal state for displ...
BOARD_CONNECTED_ITEM is a base class derived from BOARD_ITEM for items that can be connected and have...
BOARD_ITEM * GetItem(const KIID &aID)
virtual void OnBoardItemAdded(BOARD &aBoard, BOARD_ITEM *aBoardItem)
Definition: class_board.h:163
class EDGE_MODULE, a footprint edge
Definition: typeinfo.h:94
PROJECT_FILE is the backing store for a PROJECT, in JSON format.
Definition: project_file.h:62
void SetOutline(SHAPE_POLY_SET *aOutline)
Definition: class_zone.h:285
void SetCustomViaSize(int aSize)
Function SetCustomViaSize Sets custom size for via diameter (i.e.
search types array terminator (End Of Types)
Definition: typeinfo.h:82
KICAD_T
Enum KICAD_T is the set of class identification values, stored in EDA_ITEM::m_StructType.
Definition: typeinfo.h:78
static wxPoint ZeroOffset
A value of wxPoint(0,0) which can be passed to the Draw() functions.
virtual void SetParent(EDA_ITEM *aParent)
Definition: base_struct.h:196
A single base class (TRACK) represents both tracks and vias, with subclasses for curved tracks (ARC) ...
class TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:96
const wxString GetReference() const
Function GetReference.
Definition: class_module.h:444
static const char * ShowType(LAYER_T aType)
Function ShowType converts a LAYER_T enum to a const char*.
Classes used in Pcbnew, CvPcb and GerbView.
void AppendNet(NETINFO_ITEM *aNewElement)
Function AppendNet adds aNewElement to the end of the net list.
show modules on front
const INSPECTOR_FUNC & INSPECTOR
Definition: base_struct.h:105
SEARCH_RESULT Visit(INSPECTOR inspector, void *testData, const KICAD_T scanTypes[]) override
Function Visit may be re-implemented for each derived class in order to handle all the types given by...
void SynchronizeNetsAndNetClasses()
Function SynchronizeNetsAndNetClasses copies NETCLASS info to each NET, based on NET membership in a ...
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT) override
Adds an item to the container.
Definition: common.h:68
class MODULE, a footprint
Definition: typeinfo.h:89
Markers used to show a drc problem on boards.
std::shared_ptr< NET_SETTINGS > m_NetSettings
Net settings for this project (owned here) NOTE: If we go multi-board in the future,...
Definition: project_file.h:186
PCB_LAYER_ID
A quick note on layer IDs:
const std::vector< BOARD_CONNECTED_ITEM * > AllConnectedItems()
void RemoveNet(NETINFO_ITEM *aNet)
Function RemoveNet Removes a new from the net list.
int GetAreaCount() const
Function GetAreaCount.
Definition: class_board.h:934
LSET is a set of PCB_LAYER_IDs.
void ResetNetHighLight()
Function ResetNetHighLight Reset all high light data to the init state.
NETCLASSES is a container for NETCLASS instances.
Definition: netclass.h:222
NETCLASSES m_NetClasses
Definition: net_settings.h:39
GAL_SET m_VisibleItems
The GAL layers (aka items) that are turned on for viewing (.
#define NULL
bool NormalizeAreaPolygon(PICKED_ITEMS_LIST *aNewZonesList, ZONE_CONTAINER *aCurrArea)
Function NormalizeAreaPolygon Process an area that has been modified, by normalizing its polygon agai...
unsigned GetNodesCount(int aNet=-1)
Function GetNodesCount.
void RemoveListener(BOARD_LISTENER *aListener)
Remove the specified listener.
MODULES & Modules()
Definition: class_board.h:266
void DeleteMARKERs()
Function DeleteMARKERs deletes ALL MARKERS from the board.
ZONE_CONTAINER * AddArea(PICKED_ITEMS_LIST *aNewZonesList, int aNetcode, PCB_LAYER_ID aLayer, wxPoint aStartPointPosition, ZONE_BORDER_DISPLAY_STYLE aHatch)
Function AddArea Add an empty copper area to board areas list.
#define GAL_LAYER_INDEX(x)
Use this macro to convert a GAL layer to a 0-indexed offset from LAYER_VIAS.
virtual void Move(const wxPoint &aMoveVector)
Function Move move this object.
SHAPE_POLY_SET.
void SetVisibleLayers(LSET aLayerMask)
Function SetVisibleLayers is a proxy function that calls the correspondent function in m_BoardSetting...
SHAPE_LINE_CHAIN & Outline(int aIndex)
Returns the reference to aIndex-th outline in the set
static DELETED_BOARD_ITEM * GetInstance()
GAL_SET GetVisibleElements() const
Returns a set of all the element categories that are visible.
VTBL_ENTRY PROJECT_FILE & GetProjectFile() const
Definition: project.h:137
PAGE_INFO describes the page size and margins of a paper page on which to eventually print or plot.
Definition: page_info.h:54
void SetCustomDiffPairWidth(int aWidth)
Function SetCustomDiffPairWidth Sets custom track width for differential pairs (i....
bool sortPadsByXthenYCoord(D_PAD *const &ref, D_PAD *const &comp)
Function SortPadsByXCoord is used by GetSortedPadListByXCoord to Sort a pad list by x coordinate valu...
LAYER_T
Enum LAYER_T gives the allowed types of layers, same as Specctra DSN spec.
Definition: class_board.h:66
virtual void OnBoardNetSettingsChanged(BOARD &aBoard)
Definition: class_board.h:165
NETCLASS handles a collection of nets and the parameters used to route or test these nets.
Definition: netclass.h:49
void SetNetCode(int aNetCode)
Definition: netinfo.h:225
KIID niluuid(0)
LSET GetLayerSet() const override
Function GetLayerSet returns a "layer mask", which is a bitmap of all layers on which the TRACK segme...
Definition: class_pad.h:335
unsigned GetUnconnectedNetCount() const
Function GetUnconnectedNetCount.
virtual BOARD * GetBoard() const
Function GetBoard returns the BOARD in which this BOARD_ITEM resides, or NULL if none.
bool SetLayerName(PCB_LAYER_ID aLayer, const wxString &aLayerName)
Function SetLayerName changes the name of the layer given by aLayer.
std::shared_ptr< CONNECTIVITY_DATA > GetConnectivity() const
Function GetConnectivity() returns list of missing connections between components/tracks.
Definition: class_board.h:355
bool SetLayerDescr(PCB_LAYER_ID aIndex, const LAYER &aLayer)
Function SetLayerDescr returns the type of the copper layer given by aLayer.
Helper for storing and iterating over GAL_LAYER_IDs.
int SortedNetnamesList(wxArrayString &aNames, bool aSortbyPadsCount)
Function SortedNetnamesList.
virtual void SetLayer(PCB_LAYER_ID aLayer) override
Function SetLayer sets the layer this item is on.
Definition: class_zone.cpp:232
const wxString & GetNetname() const
Function GetNetname.
Definition: netinfo.h:231
NET_SETTINGS stores various net-related settings in a project context.
Definition: net_settings.h:31
NETCLASSES & GetNetClasses() const
static LSET AllLayersMask()
Definition: lset.cpp:749
void Simplify(POLYGON_MODE aFastMode)
Simplifies the polyset (merges overlapping polys, eliminates degeneracy/self-intersections) For aFast...
int SetAreasNetCodesFromNetNames(void)
Function SetAreasNetCodesFromNetNames Set the .m_NetCode member of all copper areas,...
bool GetBoardPolygonOutlines(SHAPE_POLY_SET &aOutlines, wxString *aErrorText=nullptr, wxPoint *aErrorLocation=nullptr)
Function GetBoardPolygonOutlines Extracts the board outlines and build a closed polygon from lines,...
void BuildConnectivity()
Builds or rebuilds the board connectivity database for the board, especially the list of connected it...
ENDPOINT_T
Definition: class_track.h:60
MARKERS m_markers
MARKER_PCBs for clearance problems, owned by pointer.
Definition: class_board.h:189
void SetHighLightNet(int aNetCode, bool aMulti=false)
Function SetHighLightNet Select the netcode to be highlighted.
void SetCustomDiffPairGap(int aGap)
Function SetCustomDiffPairGap Sets custom gap for differential pairs (i.e.
bool BuildBoardPolygonOutlines(BOARD *aBoard, SHAPE_POLY_SET &aOutlines, wxString *aErrorText, unsigned int aTolerance, wxPoint *aErrorLocation=nullptr)
PICKED_ITEMS_LIST is a holder to handle information on schematic or board items.
static LAYER_T ParseType(const char *aType)
Function ParseType converts a string to a LAYER_T.
DRAWINGS m_drawings
BOARD_ITEMs for drawings on the board, owned by pointer.
Definition: class_board.h:192
class DIMENSION, a dimension (graphic item)
Definition: typeinfo.h:100
Definition: color4d.h:59
unsigned GetPadCount()
Function GetPadCount.
void UnHatchBorder()
Function UnHatchBorder clears the zone's hatch.
Definition: class_zone.cpp:947
wxString GetSelectMenuText(EDA_UNITS aUnits) const override
Function GetSelectMenuText returns the text to display to be used in the selection clarification cont...
void SetCustomTrackWidth(int aWidth)
Function SetCustomTrackWidth Sets custom width for track (i.e.
int GetHeight() const
Definition: eda_rect.h:120
void ClearProject()
class PCB_TARGET, a target (graphic item)
Definition: typeinfo.h:101
static const int ORPHANED
Constant that forces initialization of a netinfo item to the NETINFO_ITEM ORPHANED (typically -1) whe...
Definition: netinfo.h:482
int LAYER_NUM
Type LAYER_NUM can be replaced with int and removed.
static bool sortNetsByNames(const NETINFO_ITEM *a, const NETINFO_ITEM *b)
constexpr std::size_t arrayDim(T const (&)[N]) noexcept
Definition: macros.h:160
TRACKS TracksInNet(int aNetCode)
Function TrackInNet collects all the TRACKs and VIAs that are members of a net given by aNetCode.
const KIID m_Uuid
Definition: base_struct.h:162
bool IsElementVisible(GAL_LAYER_ID aLayer) const
Function IsElementVisible tests whether a given element category is visible.
class TEXTE_MODULE, text in a footprint
Definition: typeinfo.h:93
void SetProject(PROJECT *aProject)
Links a board to a given project.
LAYER_T GetLayerType(PCB_LAYER_ID aLayer) const
Function GetLayerType returns the type of the copper layer given by aLayer.
void Move(const wxPoint &aMoveVector) override
Function Move move this object.
std::set< int > m_netCodes
Definition: class_board.h:136
const std::vector< D_PAD * > GetPads()
Function GetPads returns a reference to a list of all the pads.
int GetCurrentViaSize() const
Function GetCurrentViaSize.
NETINFO_ITEM handles the data for a net.
Definition: netinfo.h:65
void MapNets(const BOARD *aDestBoard)
Map all nets in the given board to nets with the same name (if any) in the destination board.
bool IsLayerVisible(PCB_LAYER_ID aLayer) const
Function IsLayerVisible is a proxy function that calls the correspondent function in m_BoardSettings ...
Definition: color4d.h:56
class MARKER_PCB, a marker used to show something
Definition: typeinfo.h:99
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:341
ZONE_CONTAINERS & Zones()
Definition: class_board.h:280
BOARD_DESIGN_SETTINGS * m_BoardSettings
Board design settings for this project's board.
Definition: project_file.h:178
bool SetCurrentNetClass(const wxString &aNetClassName)
Function SetCurrentNetClass Must be called after a netclass selection (or after a netclass parameter ...
virtual void OnBoardHighlightNetChanged(BOARD &aBoard)
Definition: class_board.h:167
see class PGM_BASE
SHAPE_POLY_SET UnitSet(int aPolygonIndex)
Class to handle a graphic segment.
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
int m_fileFormatVersionAtLoad
Definition: class_board.h:209
int GetNet() const
Function GetNet.
Definition: netinfo.h:223
LAYER holds information pertinent to a layer of a BOARD.
Definition: class_board.h:80
BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:180
ZONE_CONTAINER * InsertArea(int aNetcode, int aAreaIdx, PCB_LAYER_ID aLayer, int aCornerX, int aCornerY, ZONE_BORDER_DISPLAY_STYLE aHatch)
Add a copper area to net, inserting after m_ZoneDescriptorList[aAreaIdx].
LSET GetEnabledLayers() const
Function GetEnabledLayers returns a bit-mask of all the layers that are enabled.
wxPoint GetPosition() const override
#define _(s)
Definition: 3d_actions.cpp:33
wxString UnescapeString(const wxString &aSource)
Definition: string.cpp:125
ZONE_CONTAINERS m_ZoneDescriptorList
edge zone descriptors, owned by pointer.
Definition: class_board.h:201
class NETINFO_ITEM, a description of a net
Definition: typeinfo.h:104
int GetCopperLayerCount() const
Function GetCopperLayerCount.
void SanitizeNetcodes()
LAYER m_Layer[PCB_LAYER_ID_COUNT]
Definition: class_board.h:203
std::shared_ptr< CONNECTIVITY_DATA > m_connectivity
Definition: class_board.h:211
EDA_RECT handles the component boundary box.
Definition: eda_rect.h:44
NETCLASS * GetDefault() const
Function GetDefault.
int GetY() const
Definition: eda_rect.h:112
void OnItemChanged(BOARD_ITEM *aItem)
Notify the board and its listeners that an item on the board has been modified in some way.
EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boards.
Definition: base_struct.h:159
static bool sortNetsByNodes(const NETINFO_ITEM *a, const NETINFO_ITEM *b)
void SetLocalFlags(int aFlags)
Definition: class_zone.h:268
MODULE_ZONE_CONTAINER is the same item as ZONE_CONTAINER, but with a specific type id ZONE_CONTAINER ...
Definition: class_zone.h:950
bool IsModuleLayerVisible(PCB_LAYER_ID aLayer)
Function IsModuleLayerVisible expects either of the two layers on which a module can reside,...
MODULE * FindModuleByReference(const wxString &aReference) const
Function FindModuleByReference searches for a MODULE within this board with the given reference desig...
wxString GetClass() const override
Function GetClass returns the class name.
Definition: class_board.h:867
EDA_RECT ComputeBoundingBox(bool aBoardEdgesOnly=false) const
Function ComputeBoundingBox calculates the bounding box containing all board items (or board edge seg...
unsigned GetNetCount() const
Function GetNetCount.
Definition: netinfo.h:449
bool IsCopperLayer(LAYER_NUM aLayerId)
Function IsCopperLayer tests whether a layer is a copper layer.
virtual void Delete(BOARD_ITEM *aItem)
Removes an item from the container and deletes it.
NETCLASSPTR GetDefault() const
Function GetDefault.
Definition: netclass.h:262
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: class_zone.cpp:873
ZONE_BORDER_DISPLAY_STYLE
Zone border styles.
Definition: zone_settings.h:46
PCB_TARGET class definition.
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:97
static SEARCH_RESULT IterateForward(std::deque< T > &aList, INSPECTOR inspector, void *testData, const KICAD_T scanTypes[])
IterateForward( EDA_ITEM*, INSPECTOR, void*, const KICAD_T )
Definition: base_struct.h:383
ZONE_CONTAINER * GetArea(int index) const
Function GetArea returns the Area (Zone Container) at a given index.
Definition: class_board.h:899
Abstract interface for BOARD_ITEMs capable of storing other items inside.
class ZONE_CONTAINER, managed by a footprint
Definition: typeinfo.h:95
PGM_BASE * PgmOrNull()
similat to PGM_BASE& Pgm(), but return a reference that can be nullptr when running a shared lib from...
SEARCH_RESULT
Definition: base_struct.h:51
NETINFO_ITEM * GetNetItem(int aNetCode) const
Function GetItem.
void ReleaseNestedSettings(NESTED_SETTINGS *aSettings)
Saves and frees a nested settings object, if it exists within this one.
std::tuple< int, double, double > GetTrackLength(const TRACK &aTrack) const
Returns data on the length and number of track segments connected to a given track.
class DRAWSEGMENT, a segment not on copper layers
Definition: typeinfo.h:91
void ClearEditFlags()
Definition: base_struct.h:251
const wxPoint & GetEndPoint(ENDPOINT_T aEndPoint) const
Return the selected endpoint (start or end)
Definition: class_track.h:127
MODULE * GetFootprint(const wxPoint &aPosition, PCB_LAYER_ID aActiveLayer, bool aVisibleOnly, bool aIgnoreLocked=false)
Function GetFootprint get a footprint by its bounding rectangle at aPosition on aLayer.
wxString GetLayerName() const
Function GetLayerName returns the name of the PCB layer on which the item resides.
std::vector< wxString > GetNetClassAssignmentCandidates()
Function GetNetClassAssignmentCandidates Returns a list of name candidates for netclass assignment.
virtual PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
static std::vector< int > padCountListByNet
static const int UNCONNECTED
Constant that holds the "unconnected net" number (typically 0) all items "connected" to this net are ...
Definition: netinfo.h:478
int GetCopperLayerCount() const
Function GetCopperLayerCount.
DRAWINGS & Drawings()
Definition: class_board.h:275
void FillItemMap(std::map< KIID, EDA_ITEM * > &aMap)
LSET m_LegacyVisibleLayers
Visibility settings stored in board prior to 6.0, only used for loading legacy files.
Definition: class_board.h:296
void ClearAllNetCodes()
Function ClearAllNetCodes() Resets all items' netcodes to 0 (no net).
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:849
void SetEnabledLayers(LSET aLayerMask)
Function SetEnabledLayers is a proxy function that calls the correspondent function in m_BoardSetting...
std::vector< BOARD_LISTENER * > m_listeners
Definition: class_board.h:232
void Remove(BOARD_ITEM *aBoardItem) override
Removes an item from the container.
TRACKS & Tracks()
Definition: class_board.h:257
void SetHatchStyle(ZONE_BORDER_DISPLAY_STYLE aStyle)
Definition: class_zone.h:578
bool IsOnCopperLayer() const override
Function IsOnCopperLayer.
Definition: class_zone.cpp:218
void UseCustomTrackViaSize(bool aEnabled)
Function UseCustomTrackViaSize Enables/disables custom track/via size settings.
PROJECT * m_project
Definition: class_board.h:216
KICAD_T Type() const
Function Type()
Definition: base_struct.h:193
static wxString GetStandardLayerName(PCB_LAYER_ID aLayerId)
Function GetStandardLayerName returns an "English Standard" name of a PCB layer when given aLayerNumb...
Definition: class_board.h:650
std::list< ZONE_CONTAINER * > GetZoneList(bool aIncludeZonesInFootprints=false)
Function GetZoneList.
BOARD_DESIGN_SETTINGS contains design settings for a BOARD object.
bool IsSelfIntersecting() const
Function IsSelfIntersecting Checks whether any of the polygons in the set is self intersecting.
void SetParent(JSON_SETTINGS *aParent)
GAL_SET m_LegacyVisibleItems
Definition: class_board.h:297