KiCad PCB EDA Suite
class_board.cpp
Go to the documentation of this file.
1 
6 /*
7  * This program source code file is part of KiCad, a free EDA CAD application.
8  *
9  * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
10  * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
11  * Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
12  *
13  * Copyright (C) 1992-2017 KiCad Developers, see AUTHORS.txt for contributors.
14  *
15  * This program is free software; you can redistribute it and/or
16  * modify it under the terms of the GNU General Public License
17  * as published by the Free Software Foundation; either version 2
18  * of the License, or (at your option) any later version.
19  *
20  * This program is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23  * GNU General Public License for more details.
24  *
25  * You should have received a copy of the GNU General Public License
26  * along with this program; if not, you may find one here:
27  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
28  * or you may search the http://www.gnu.org website for the version 2 license,
29  * or you may write to the Free Software Foundation, Inc.,
30  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
31  */
32 
33 #include <limits.h>
34 #include <algorithm>
35 
36 #include <fctsys.h>
37 #include <common.h>
38 #include <kicad_string.h>
39 #include <wxBasePcbFrame.h>
40 #include <msgpanel.h>
41 #include <pcb_netlist.h>
42 #include <reporter.h>
43 #include <base_units.h>
44 #include <ratsnest_data.h>
45 #include <ratsnest_viewitem.h>
46 #include <worksheet_viewitem.h>
47 
48 #include <pcbnew.h>
49 #include <colors_selection.h>
50 #include <collectors.h>
51 
52 #include <class_board.h>
53 #include <class_module.h>
54 #include <class_track.h>
55 #include <class_zone.h>
56 #include <class_marker_pcb.h>
57 #include <class_drawsegment.h>
58 #include <class_pcb_text.h>
59 #include <class_mire.h>
60 #include <class_dimension.h>
61 
62 
63 /* This is an odd place for this, but CvPcb won't link if it is
64  * in class_board_item.cpp like I first tried it.
65  */
67 
68 
71  m_NetInfo( this ),
72  m_paper( PAGE_INFO::A4 )
73 {
74  // we have not loaded a board yet, assume latest until then.
75  m_fileFormatVersionAtLoad = LEGACY_BOARD_FILE_VERSION;
76 
77  m_Status_Pcb = 0; // Status word: bit 1 = calculate.
79  m_nodeCount = 0; // Number of connected pads.
80  m_unconnectedNetCount = 0; // Number of unconnected nets.
81 
82  m_CurrentZoneContour = NULL; // This ZONE_CONTAINER handle the
83  // zone contour currently in progress
84 
85  BuildListOfNets(); // prepare pad and netlist containers.
86 
87  for( LAYER_NUM layer = 0; layer < PCB_LAYER_ID_COUNT; ++layer )
88  {
89  m_Layer[layer].m_name = GetStandardLayerName( ToLAYER_ID( layer ) );
90 
91  if( IsCopperLayer( layer ) )
92  m_Layer[layer].m_type = LT_SIGNAL;
93  else
94  m_Layer[layer].m_type = LT_UNDEFINED;
95  }
96 
97  // Initialize default netclass.
98  NETCLASSPTR defaultClass = m_designSettings.GetDefault();
99  defaultClass->SetDescription( _( "This is the default net class." ) );
100  m_designSettings.SetCurrentNetClass( defaultClass->GetName() );
101 
102  // Set sensible initial values for custom track width & via size
107 
108  // Initialize ratsnest
109  m_ratsnest = new RN_DATA( this );
110 }
111 
112 
114 {
115  while( m_ZoneDescriptorList.size() )
116  {
117  ZONE_CONTAINER* area_to_remove = m_ZoneDescriptorList[0];
118  Delete( area_to_remove );
119  }
120 
121  delete m_ratsnest;
122 
123  m_FullRatsnest.clear();
124  m_LocalRatsnest.clear();
125 
126  DeleteMARKERs();
128 
129  delete m_CurrentZoneContour;
130  m_CurrentZoneContour = NULL;
131 }
132 
133 
135 {
136  wxLogWarning( wxT( "This should not be called on the BOARD object") );
137 
138  return ZeroOffset;
139 }
140 
141 void BOARD::SetPosition( const wxPoint& aPos )
142 {
143  wxLogWarning( wxT( "This should not be called on the BOARD object") );
144 }
145 
146 
147 void BOARD::Move( const wxPoint& aMoveVector ) // overload
148 {
149  // @todo : anything like this elsewhere? maybe put into GENERAL_COLLECTOR class.
150  static const KICAD_T top_level_board_stuff[] = {
151  PCB_MARKER_T,
152  PCB_TEXT_T,
153  PCB_LINE_T,
155  PCB_TARGET_T,
156  PCB_VIA_T,
157  PCB_TRACE_T,
158  // PCB_PAD_T, Can't be at board level
159  // PCB_MODULE_TEXT_T, Can't be at board level
160  PCB_MODULE_T,
162  EOT
163  };
164 
165  INSPECTOR_FUNC inspector = [&] ( EDA_ITEM* item, void* testData )
166  {
167  BOARD_ITEM* brd_item = (BOARD_ITEM*) item;
168 
169  // aMoveVector was snapshotted, don't need "data".
170  brd_item->Move( aMoveVector );
171 
172  return SEARCH_CONTINUE;
173  };
174 
175  Visit( inspector, NULL, top_level_board_stuff );
176 }
177 
178 
179 TRACKS BOARD::TracksInNet( int aNetCode )
180 {
181  TRACKS ret;
182 
183  INSPECTOR_FUNC inspector = [aNetCode,&ret] ( EDA_ITEM* item, void* testData )
184  {
185  TRACK* t = (TRACK*) item;
186 
187  if( t->GetNetCode() == aNetCode )
188  ret.push_back( t );
189 
190  return SEARCH_CONTINUE;
191  };
192 
193  // visit this BOARD's TRACKs and VIAs with above TRACK INSPECTOR which
194  // appends all in aNetCode to ret.
195  Visit( inspector, NULL, GENERAL_COLLECTOR::Tracks );
196 
197  return ret;
198 }
199 
200 
205 static void removeTrack( TRACKS* aList, TRACK* aOneToRemove )
206 {
207  aList->erase( std::remove( aList->begin(), aList->end(), aOneToRemove ), aList->end() );
208 }
209 
210 
211 static void otherEnd( const TRACK& aTrack, const wxPoint& aNotThisEnd, wxPoint* aOtherEnd )
212 {
213  if( aTrack.GetStart() == aNotThisEnd )
214  {
215  *aOtherEnd = aTrack.GetEnd();
216  }
217  else
218  {
219  wxASSERT( aTrack.GetEnd() == aNotThisEnd );
220  *aOtherEnd = aTrack.GetStart();
221  }
222 }
223 
224 
229 static int find_vias_and_tracks_at( TRACKS& at_next, TRACKS& in_net, LSET& lset, const wxPoint& next )
230 {
231  // first find all vias (in this net) at 'next' location, and expand LSET with each
232  for( TRACKS::iterator it = in_net.begin(); it != in_net.end(); )
233  {
234  TRACK* t = *it;
235 
236  if( t->Type() == PCB_VIA_T && (t->GetLayerSet() & lset).any() &&
237  ( t->GetStart() == next || t->GetEnd() == next ) )
238  {
239  lset |= t->GetLayerSet();
240  at_next.push_back( t );
241  it = in_net.erase( it );
242  }
243  else
244  ++it;
245  }
246 
247  int track_count = 0;
248 
249  // with expanded lset, find all tracks with an end on any of the layers in lset
250  for( TRACKS::iterator it = in_net.begin(); it != in_net.end(); /* iterates in the loop body */ )
251  {
252  TRACK* t = *it;
253 
254  if( ( t->GetLayerSet() & lset ).any() && ( t->GetStart() == next || t->GetEnd() == next ) )
255  {
256  at_next.push_back( t );
257  it = in_net.erase( it );
258  ++track_count;
259  }
260  else
261  {
262  ++it;
263  }
264  }
265 
266  return track_count;
267 }
268 
269 
281 static void checkConnectedTo( BOARD* aBoard, TRACKS* aList, const TRACKS& aTracksInNet,
282  const wxPoint& aGoal, const wxPoint& aStart, TRACK* aFirstTrack )
283 {
284  TRACKS in_net = aTracksInNet; // copy source list so the copy can be modified
285  wxPoint next;
286 
287  otherEnd( *aFirstTrack, aStart, &next );
288 
289  aList->push_back( aFirstTrack );
290  removeTrack( &in_net, aFirstTrack );
291 
292  LSET lset( aFirstTrack->GetLayer() );
293 
294  while( in_net.size() )
295  {
296  if( next == aGoal )
297  return; // success
298 
299  // Want an exact match on the position of next, i.e. pad at next,
300  // not a forgiving HitTest() with tolerance type of match, otherwise the overall
301  // algorithm will not work. GetPadFast() is an exact match as I write this.
302  if( aBoard->GetPadFast( next, lset ) )
303  {
304  std::string m = StrPrintf(
305  "intervening pad at:(xy %s) between start:(xy %s) and goal:(xy %s)",
306  BOARD_ITEM::FormatInternalUnits( next ).c_str(),
307  BOARD_ITEM::FormatInternalUnits( aStart ).c_str(),
308  BOARD_ITEM::FormatInternalUnits( aGoal ).c_str()
309  );
310  THROW_IO_ERROR( m );
311  }
312 
313  int track_count = find_vias_and_tracks_at( *aList, in_net, lset, next );
314 
315  if( track_count != 1 )
316  {
317  std::string m = StrPrintf(
318  "found %d tracks intersecting at (xy %s), exactly 2 would be acceptable.",
319  track_count + aList->size() == 1 ? 1 : 0,
320  BOARD_ITEM::FormatInternalUnits( next ).c_str()
321  );
322  THROW_IO_ERROR( m );
323  }
324 
325  // reduce lset down to the layer that the last track at 'next' is on.
326  lset = aList->back()->GetLayerSet();
327 
328  otherEnd( *aList->back(), next, &next );
329  }
330 
331  std::string m = StrPrintf(
332  "not enough tracks connecting start:(xy %s) and goal:(xy %s).",
333  BOARD_ITEM::FormatInternalUnits( aStart ).c_str(),
334  BOARD_ITEM::FormatInternalUnits( aGoal ).c_str()
335  );
336  THROW_IO_ERROR( m );
337 }
338 
339 
340 TRACKS BOARD::TracksInNetBetweenPoints( const wxPoint& aStartPos, const wxPoint& aGoalPos, int aNetCode )
341 {
342  TRACKS in_between_pts;
343  TRACKS on_start_point;
344  TRACKS in_net = TracksInNet( aNetCode ); // a small subset of TRACKs and VIAs
345 
346  for( auto t : in_net )
347  {
348  if( t->Type() == PCB_TRACE_T && ( t->GetStart() == aStartPos || t->GetEnd() == aStartPos ) )
349  on_start_point.push_back( t );
350  }
351 
352  wxString per_path_problem_text;
353 
354  for( auto t : on_start_point ) // explore each trace (path) leaving aStartPos
355  {
356  // checkConnectedTo() fills in_between_pts on every attempt. For failures
357  // this set needs to be cleared.
358  in_between_pts.clear();
359 
360  try
361  {
362  checkConnectedTo( this, &in_between_pts, in_net, aGoalPos, aStartPos, t );
363  }
364  catch( const IO_ERROR& ioe ) // means not connected
365  {
366  per_path_problem_text += "\n\t";
367  per_path_problem_text += ioe.Problem();
368  continue; // keep trying, there may be other paths leaving from aStartPos
369  }
370 
371  // success, no exception means a valid connection,
372  // return this set of TRACKS without throwing.
373  return in_between_pts;
374  }
375 
376  wxString m = wxString::Format(
377  "no clean path connecting start:(xy %s) with goal:(xy %s)",
378  BOARD_ITEM::FormatInternalUnits( aStartPos ).c_str(),
379  BOARD_ITEM::FormatInternalUnits( aGoalPos ).c_str()
380  );
381 
382  THROW_IO_ERROR( m + per_path_problem_text );
383 }
384 
385 
386 void BOARD::chainMarkedSegments( wxPoint aPosition, const LSET& aLayerSet, TRACKS* aList )
387 {
388  LSET layer_set = aLayerSet;
389 
390  if( !m_Track ) // no tracks at all in board
391  return;
392 
393  /* Set the BUSY flag of all connected segments, first search starting at
394  * aPosition. The search ends when a pad is found (end of a track), a
395  * segment end has more than one other segment end connected, or when no
396  * connected item found.
397  *
398  * Vias are a special case because they must look for segments connected
399  * on other layers and they change the layer mask. They can be a track
400  * end or not. They will be analyzer later and vias on terminal points
401  * of the track will be considered as part of this track if they do not
402  * connect segments of another track together and will be considered as
403  * part of an other track when removing the via, the segments of that other
404  * track are disconnected.
405  */
406  for( ; ; )
407  {
408 
409 
410  if( GetPad( aPosition, layer_set ) != NULL )
411  return;
412 
413  /* Test for a via: a via changes the layer mask and can connect a lot
414  * of segments at location aPosition. When found, the via is just
415  * pushed in list. Vias will be examined later, when all connected
416  * segment are found and push in list. This is because when a via
417  * is found we do not know at this time the number of connected items
418  * and we do not know if this via is on the track or finish the track
419  */
420  TRACK* via = m_Track->GetVia( NULL, aPosition, layer_set );
421 
422  if( via )
423  {
424  layer_set = via->GetLayerSet();
425 
426  aList->push_back( via );
427  }
428 
429  int seg_count = 0;
430  TRACK* candidate = NULL;
431 
432  /* Search all segments connected to point aPosition.
433  * if only 1 segment at aPosition: then this segment is "candidate"
434  * if > 1 segment:
435  * then end of "track" (because more than 2 segments are connected at aPosition)
436  */
437  TRACK* segment = m_Track;
438 
439  while( ( segment = ::GetTrack( segment, NULL, aPosition, layer_set ) ) != NULL )
440  {
441  if( segment->GetState( BUSY ) ) // already found and selected: skip it
442  {
443  segment = segment->Next();
444  continue;
445  }
446 
447  if( segment == via ) // just previously found: skip it
448  {
449  segment = segment->Next();
450  continue;
451  }
452 
453  if( ++seg_count == 1 ) // if first connected item: then segment is candidate
454  {
455  candidate = segment;
456  segment = segment->Next();
457  }
458  else // More than 1 segment connected -> location is end of track
459  {
460  return;
461  }
462  }
463 
464  if( candidate ) // A candidate is found: flag it and push it in list
465  {
466  /* Initialize parameters to search items connected to this
467  * candidate:
468  * we must analyze connections to its other end
469  */
470  if( aPosition == candidate->GetStart() )
471  {
472  aPosition = candidate->GetEnd();
473  }
474  else
475  {
476  aPosition = candidate->GetStart();
477  }
478 
479  layer_set = candidate->GetLayerSet();
480 
481  // flag this item and push it in list of selected items
482  aList->push_back( candidate );
483  candidate->SetState( BUSY, true );
484  }
485  else
486  {
487  return;
488  }
489  }
490 }
491 
492 
494 {
496 }
497 
498 
500 {
503 }
504 
505 
506 bool BOARD::SetLayerDescr( PCB_LAYER_ID aIndex, const LAYER& aLayer )
507 {
508  if( unsigned( aIndex ) < DIM( m_Layer ) )
509  {
510  m_Layer[ aIndex ] = aLayer;
511  return true;
512  }
513 
514  return false;
515 }
516 
517 #include <stdio.h>
518 
519 const PCB_LAYER_ID BOARD::GetLayerID( const wxString& aLayerName ) const
520 {
521 
522  // Look for the BOARD specific copper layer names
523  for( LAYER_NUM layer = 0; layer < PCB_LAYER_ID_COUNT; ++layer )
524  {
525  if ( IsCopperLayer( layer ) && ( m_Layer[ layer ].m_name == aLayerName ) )
526  {
527  return ToLAYER_ID( layer );
528  }
529  }
530 
531  // Otherwise fall back to the system standard layer names
532  for( LAYER_NUM layer = 0; layer < PCB_LAYER_ID_COUNT; ++layer )
533  {
534  if( GetStandardLayerName( ToLAYER_ID( layer ) ) == aLayerName )
535  {
536  return ToLAYER_ID( layer );
537  }
538  }
539 
540  return UNDEFINED_LAYER;
541 }
542 
543 const wxString BOARD::GetLayerName( PCB_LAYER_ID aLayer ) const
544 {
545  // All layer names are stored in the BOARD.
546  if( IsLayerEnabled( aLayer ) )
547  {
548  // Standard names were set in BOARD::BOARD() but they may be
549  // over-ridden by BOARD::SetLayerName().
550  // For copper layers, return the actual copper layer name,
551  // otherwise return the Standard English layer name.
552  if( IsCopperLayer( aLayer ) )
553  return m_Layer[aLayer].m_name;
554  }
555 
556  return GetStandardLayerName( aLayer );
557 }
558 
559 bool BOARD::SetLayerName( PCB_LAYER_ID aLayer, const wxString& aLayerName )
560 {
561  if( !IsCopperLayer( aLayer ) )
562  return false;
563 
564  if( aLayerName == wxEmptyString || aLayerName.Len() > 20 )
565  return false;
566 
567  // no quote chars in the name allowed
568  if( aLayerName.Find( wxChar( '"' ) ) != wxNOT_FOUND )
569  return false;
570 
571  wxString nameTemp = aLayerName;
572 
573  // replace any spaces with underscores before we do any comparing
574  nameTemp.Replace( wxT( " " ), wxT( "_" ) );
575 
576  if( IsLayerEnabled( aLayer ) )
577  {
578 #if 0
579  for( LAYER_NUM i = FIRST_COPPER_LAYER; i < NB_COPPER_LAYERS; ++i )
580  {
581  if( i != aLayer && IsLayerEnabled( i ) && nameTemp == m_Layer[i].m_Name )
582  return false;
583  }
584 #else
585  for( LSEQ cu = GetEnabledLayers().CuStack(); cu; ++cu )
586  {
587  PCB_LAYER_ID id = *cu;
588 
589  // veto changing the name if it exists elsewhere.
590  if( id != aLayer && nameTemp == m_Layer[id].m_name )
591 // if( id != aLayer && nameTemp == wxString( m_Layer[id].m_name ) )
592  return false;
593  }
594 #endif
595 
596  m_Layer[aLayer].m_name = nameTemp;
597 
598  return true;
599  }
600 
601  return false;
602 }
603 
604 
606 {
607  if( !IsCopperLayer( aLayer ) )
608  return LT_SIGNAL;
609 
610  //@@IMB: The original test was broken due to the discontinuity
611  // in the layer sequence.
612  if( IsLayerEnabled( aLayer ) )
613  return m_Layer[aLayer].m_type;
614 
615  return LT_SIGNAL;
616 }
617 
618 
619 bool BOARD::SetLayerType( PCB_LAYER_ID aLayer, LAYER_T aLayerType )
620 {
621  if( !IsCopperLayer( aLayer ) )
622  return false;
623 
624  //@@IMB: The original test was broken due to the discontinuity
625  // in the layer sequence.
626  if( IsLayerEnabled( aLayer ) )
627  {
628  m_Layer[aLayer].m_type = aLayerType;
629  return true;
630  }
631 
632  return false;
633 }
634 
635 
636 const char* LAYER::ShowType( LAYER_T aType )
637 {
638  const char* cp;
639 
640  switch( aType )
641  {
642  default:
643  case LT_SIGNAL:
644  cp = "signal";
645  break;
646 
647  case LT_POWER:
648  cp = "power";
649  break;
650 
651  case LT_MIXED:
652  cp = "mixed";
653  break;
654 
655  case LT_JUMPER:
656  cp = "jumper";
657  break;
658  }
659 
660  return cp;
661 }
662 
663 
664 LAYER_T LAYER::ParseType( const char* aType )
665 {
666  if( strcmp( aType, "signal" ) == 0 )
667  return LT_SIGNAL;
668  else if( strcmp( aType, "power" ) == 0 )
669  return LT_POWER;
670  else if( strcmp( aType, "mixed" ) == 0 )
671  return LT_MIXED;
672  else if( strcmp( aType, "jumper" ) == 0 )
673  return LT_JUMPER;
674  else
675  return LT_UNDEFINED;
676 }
677 
678 
680 {
682 }
683 
684 
685 void BOARD::SetCopperLayerCount( int aCount )
686 {
688 }
689 
690 
692 {
694 }
695 
696 
698 {
700 }
701 
702 
703 void BOARD::SetEnabledLayers( LSET aLayerSet )
704 {
705  m_designSettings.SetEnabledLayers( aLayerSet );
706 }
707 
708 
709 void BOARD::SetVisibleLayers( LSET aLayerSet )
710 {
711  m_designSettings.SetVisibleLayers( aLayerSet );
712 }
713 
714 
715 void BOARD::SetVisibleElements( int aMask )
716 {
717  // Call SetElementVisibility for each item
718  // to ensure specific calculations that can be needed by some items,
719  // just changing the visibility flags could be not sufficient.
721  {
722  int item_mask = 1 << GAL_LAYER_INDEX( ii );
723  SetElementVisibility( ii, aMask & item_mask );
724  }
725 }
726 
727 
729 {
730  SetVisibleLayers( LSET().set() );
731 
732  // Call SetElementVisibility for each item,
733  // to ensure specific calculations that can be needed by some items
735  SetElementVisibility( ii, true );
736 }
737 
738 
740 {
742 }
743 
744 
745 bool BOARD::IsElementVisible( GAL_LAYER_ID LAYER_aPCB ) const
746 {
747  return m_designSettings.IsElementVisible( LAYER_aPCB );
748 }
749 
750 
751 void BOARD::SetElementVisibility( GAL_LAYER_ID LAYER_aPCB, bool isEnabled )
752 {
753  m_designSettings.SetElementVisibility( LAYER_aPCB, isEnabled );
754 
755  switch( LAYER_aPCB )
756  {
757  case LAYER_RATSNEST:
758 
759  // we must clear or set the CH_VISIBLE flags to hide/show ratsnest
760  // because we have a tool to show/hide ratsnest relative to a pad or a module
761  // so the hide/show option is a per item selection
763  {
764  for( unsigned ii = 0; ii < GetRatsnestsCount(); ii++ )
766  }
767  else
768  {
769  for( unsigned ii = 0; ii < GetRatsnestsCount(); ii++ )
771  }
772  break;
773 
774  default:
775  ;
776  }
777 }
778 
779 
781 {
782  COLOR4D color = COLOR4D::UNSPECIFIED;
783 
784  switch( aLayerId )
785  {
786  case LAYER_NON_PLATED:
787  case LAYER_VIA_THROUGH:
788  case LAYER_VIA_MICROVIA:
789  case LAYER_VIA_BBLIND:
790  case LAYER_MOD_TEXT_FR:
791  case LAYER_MOD_TEXT_BK:
793  case LAYER_ANCHOR:
794  case LAYER_PAD_FR:
795  case LAYER_PAD_BK:
796  case LAYER_RATSNEST:
797  case LAYER_GRID:
798  color = GetColorsSettings()->GetItemColor( aLayerId );
799  break;
800 
801  default:
802  wxLogDebug( wxT( "BOARD::GetVisibleElementColor(): bad arg %d" ), aLayerId );
803  }
804 
805  return color;
806 }
807 
808 
810 {
811  switch( aLayerId )
812  {
813  case LAYER_NON_PLATED:
814  case LAYER_VIA_THROUGH:
815  case LAYER_VIA_MICROVIA:
816  case LAYER_VIA_BBLIND:
817  case LAYER_MOD_TEXT_FR:
818  case LAYER_MOD_TEXT_BK:
820  case LAYER_ANCHOR:
821  case LAYER_PAD_FR:
822  case LAYER_PAD_BK:
823  case LAYER_GRID:
824  case LAYER_RATSNEST:
825  GetColorsSettings()->SetItemColor( aLayerId, aColor );
826  break;
827 
828  default:
829  wxLogDebug( wxT( "BOARD::SetVisibleElementColor(): bad arg %d" ), aLayerId );
830  }
831 }
832 
833 
835 {
836  GetColorsSettings()->SetLayerColor( aLayer, aColor );
837 }
838 
839 
841 {
842  return GetColorsSettings()->GetLayerColor( aLayer );
843 }
844 
845 
847 {
848  switch( layer )
849  {
850  case F_Cu:
851  return IsElementVisible( LAYER_MOD_FR );
852 
853  case B_Cu:
854  return IsElementVisible( LAYER_MOD_BK );
855 
856  default:
857  wxFAIL_MSG( wxT( "BOARD::IsModuleLayerVisible() param error: bad layer" ) );
858  return true;
859  }
860 }
861 
862 
863 void BOARD::Add( BOARD_ITEM* aBoardItem, ADD_MODE aMode )
864 {
865  if( aBoardItem == NULL )
866  {
867  wxFAIL_MSG( wxT( "BOARD::Add() param error: aBoardItem NULL" ) );
868  return;
869  }
870 
871  switch( aBoardItem->Type() )
872  {
873  case PCB_NETINFO_T:
874  m_NetInfo.AppendNet( (NETINFO_ITEM*) aBoardItem );
875  break;
876 
877  // this one uses a vector
878  case PCB_MARKER_T:
879  m_markers.push_back( (MARKER_PCB*) aBoardItem );
880  break;
881 
882  // this one uses a vector
883  case PCB_ZONE_AREA_T:
884  m_ZoneDescriptorList.push_back( (ZONE_CONTAINER*) aBoardItem );
885  break;
886 
887  case PCB_TRACE_T:
888  case PCB_VIA_T:
889  if( aMode == ADD_APPEND )
890  {
891  m_Track.PushBack( (TRACK*) aBoardItem );
892  }
893  else
894  {
895  TRACK* insertAid;
896  insertAid = ( (TRACK*) aBoardItem )->GetBestInsertPoint( this );
897  m_Track.Insert( (TRACK*) aBoardItem, insertAid );
898  }
899 
900  break;
901 
902  case PCB_ZONE_T:
903  if( aMode == ADD_APPEND )
904  m_Zone.PushBack( (SEGZONE*) aBoardItem );
905  else
906  m_Zone.PushFront( (SEGZONE*) aBoardItem );
907 
908  break;
909 
910  case PCB_MODULE_T:
911  if( aMode == ADD_APPEND )
912  m_Modules.PushBack( (MODULE*) aBoardItem );
913  else
914  m_Modules.PushFront( (MODULE*) aBoardItem );
915 
916  // Because the list of pads has changed, reset the status
917  // This indicate the list of pad and nets must be recalculated before use
918  m_Status_Pcb = 0;
919  break;
920 
921  case PCB_DIMENSION_T:
922  case PCB_LINE_T:
923  case PCB_TEXT_T:
924  case PCB_TARGET_T:
925  if( aMode == ADD_APPEND )
926  m_Drawings.PushBack( aBoardItem );
927  else
928  m_Drawings.PushFront( aBoardItem );
929 
930  break;
931 
932  // other types may use linked list
933  default:
934  {
935  wxString msg;
936  msg.Printf( wxT( "BOARD::Add() needs work: BOARD_ITEM type (%d) not handled" ),
937  aBoardItem->Type() );
938  wxFAIL_MSG( msg );
939  return;
940  }
941  break;
942  }
943 
944  aBoardItem->SetParent( this );
945  m_ratsnest->Add( aBoardItem );
946 }
947 
948 
949 void BOARD::Remove( BOARD_ITEM* aBoardItem )
950 {
951  // find these calls and fix them! Don't send me no stinking' NULL.
952  wxASSERT( aBoardItem );
953 
954  switch( aBoardItem->Type() )
955  {
956  case PCB_NETINFO_T:
957  {
958  NETINFO_ITEM* item = (NETINFO_ITEM*) aBoardItem;
959  m_NetInfo.RemoveNet( item );
960  break;
961  }
962 
963  case PCB_MARKER_T:
964 
965  // find the item in the vector, then remove it
966  for( unsigned i = 0; i<m_markers.size(); ++i )
967  {
968  if( m_markers[i] == (MARKER_PCB*) aBoardItem )
969  {
970  m_markers.erase( m_markers.begin() + i );
971  break;
972  }
973  }
974 
975  break;
976 
977  case PCB_ZONE_AREA_T: // this one uses a vector
978  // find the item in the vector, then delete then erase it.
979  for( unsigned i = 0; i<m_ZoneDescriptorList.size(); ++i )
980  {
981  if( m_ZoneDescriptorList[i] == (ZONE_CONTAINER*) aBoardItem )
982  {
983  m_ZoneDescriptorList.erase( m_ZoneDescriptorList.begin() + i );
984  break;
985  }
986  }
987  break;
988 
989  case PCB_MODULE_T:
990  m_Modules.Remove( (MODULE*) aBoardItem );
991  break;
992 
993  case PCB_TRACE_T:
994  case PCB_VIA_T:
995  m_Track.Remove( (TRACK*) aBoardItem );
996  break;
997 
998  case PCB_ZONE_T:
999  m_Zone.Remove( (SEGZONE*) aBoardItem );
1000  break;
1001 
1002  case PCB_DIMENSION_T:
1003  case PCB_LINE_T:
1004  case PCB_TEXT_T:
1005  case PCB_TARGET_T:
1006  m_Drawings.Remove( aBoardItem );
1007  break;
1008 
1009  // other types may use linked list
1010  default:
1011  wxFAIL_MSG( wxT( "BOARD::Remove() needs more ::Type() support" ) );
1012  }
1013 
1014  m_ratsnest->Remove( aBoardItem );
1015 }
1016 
1017 
1019 {
1020  // the vector does not know how to delete the MARKER_PCB, it holds pointers
1021  for( unsigned i = 0; i<m_markers.size(); ++i )
1022  delete m_markers[i];
1023 
1024  m_markers.clear();
1025 }
1026 
1027 
1029 {
1030  // the vector does not know how to delete the ZONE Outlines, it holds
1031  // pointers
1032  for( unsigned i = 0; i<m_ZoneDescriptorList.size(); ++i )
1033  delete m_ZoneDescriptorList[i];
1034 
1035  m_ZoneDescriptorList.clear();
1036 }
1037 
1038 
1040 {
1041  return m_Track.GetCount();
1042 }
1043 
1044 
1046 {
1047  return m_Zone.GetCount();
1048 }
1049 
1050 
1051 unsigned BOARD::GetNodesCount() const
1052 {
1053  return m_nodeCount;
1054 }
1055 
1056 
1057 EDA_RECT BOARD::ComputeBoundingBox( bool aBoardEdgesOnly ) const
1058 {
1059  bool hasItems = false;
1060  EDA_RECT area;
1061 
1062  // Check segments, dimensions, texts, and fiducials
1063  for( BOARD_ITEM* item = m_Drawings; item; item = item->Next() )
1064  {
1065  if( aBoardEdgesOnly && (item->Type() != PCB_LINE_T || item->GetLayer() != Edge_Cuts ) )
1066  continue;
1067 
1068  if( !hasItems )
1069  area = item->GetBoundingBox();
1070  else
1071  area.Merge( item->GetBoundingBox() );
1072 
1073  hasItems = true;
1074  }
1075 
1076  if( !aBoardEdgesOnly )
1077  {
1078  // Check modules
1079  for( MODULE* module = m_Modules; module; module = module->Next() )
1080  {
1081  if( !hasItems )
1082  area = module->GetBoundingBox();
1083  else
1084  area.Merge( module->GetBoundingBox() );
1085 
1086  hasItems = true;
1087  }
1088 
1089  // Check tracks
1090  for( TRACK* track = m_Track; track; track = track->Next() )
1091  {
1092  if( !hasItems )
1093  area = track->GetBoundingBox();
1094  else
1095  area.Merge( track->GetBoundingBox() );
1096 
1097  hasItems = true;
1098  }
1099 
1100  // Check segment zones
1101  for( TRACK* track = m_Zone; track; track = track->Next() )
1102  {
1103  if( !hasItems )
1104  area = track->GetBoundingBox();
1105  else
1106  area.Merge( track->GetBoundingBox() );
1107 
1108  hasItems = true;
1109  }
1110 
1111  // Check polygonal zones
1112  for( unsigned int i = 0; i < m_ZoneDescriptorList.size(); i++ )
1113  {
1115 
1116  if( !hasItems )
1117  area = aZone->GetBoundingBox();
1118  else
1119  area.Merge( aZone->GetBoundingBox() );
1120 
1121  area.Merge( aZone->GetBoundingBox() );
1122  hasItems = true;
1123  }
1124  }
1125 
1126  return area;
1127 }
1128 
1129 
1130 // virtual, see pcbstruct.h
1131 void BOARD::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList )
1132 {
1133  wxString txt;
1134  int viasCount = 0;
1135  int trackSegmentsCount = 0;
1136 
1137  for( BOARD_ITEM* item = m_Track; item; item = item->Next() )
1138  {
1139  if( item->Type() == PCB_VIA_T )
1140  viasCount++;
1141  else
1142  trackSegmentsCount++;
1143  }
1144 
1145  txt.Printf( wxT( "%d" ), GetPadCount() );
1146  aList.push_back( MSG_PANEL_ITEM( _( "Pads" ), txt, DARKGREEN ) );
1147 
1148  txt.Printf( wxT( "%d" ), viasCount );
1149  aList.push_back( MSG_PANEL_ITEM( _( "Vias" ), txt, DARKGREEN ) );
1150 
1151  txt.Printf( wxT( "%d" ), trackSegmentsCount );
1152  aList.push_back( MSG_PANEL_ITEM( _( "Track Segments" ), txt, DARKGREEN ) );
1153 
1154  txt.Printf( wxT( "%d" ), GetNodesCount() );
1155  aList.push_back( MSG_PANEL_ITEM( _( "Nodes" ), txt, DARKCYAN ) );
1156 
1157  txt.Printf( wxT( "%d" ), m_NetInfo.GetNetCount() );
1158  aList.push_back( MSG_PANEL_ITEM( _( "Nets" ), txt, RED ) );
1159 
1160  /* These parameters are known only if the full ratsnest is available,
1161  * so, display them only if this is the case
1162  */
1163  if( (m_Status_Pcb & NET_CODES_OK) )
1164  {
1165  txt.Printf( wxT( "%d" ), GetRatsnestsCount() );
1166  aList.push_back( MSG_PANEL_ITEM( _( "Links" ), txt, DARKGREEN ) );
1167 
1168  txt.Printf( wxT( "%d" ), GetRatsnestsCount() - GetUnconnectedNetCount() );
1169  aList.push_back( MSG_PANEL_ITEM( _( "Connections" ), txt, DARKGREEN ) );
1170 
1171  txt.Printf( wxT( "%d" ), GetUnconnectedNetCount() );
1172  aList.push_back( MSG_PANEL_ITEM( _( "Unconnected" ), txt, BLUE ) );
1173  }
1174 }
1175 
1176 
1177 // virtual, see pcbstruct.h
1178 SEARCH_RESULT BOARD::Visit( INSPECTOR inspector, void* testData, const KICAD_T scanTypes[] )
1179 {
1180  KICAD_T stype;
1181  SEARCH_RESULT result = SEARCH_CONTINUE;
1182  const KICAD_T* p = scanTypes;
1183  bool done = false;
1184 
1185 #if 0 && defined(DEBUG)
1186  std::cout << GetClass().mb_str() << ' ';
1187 #endif
1188 
1189  while( !done )
1190  {
1191  stype = *p;
1192 
1193  switch( stype )
1194  {
1195  case PCB_T:
1196  result = inspector( this, testData ); // inspect me
1197  // skip over any types handled in the above call.
1198  ++p;
1199  break;
1200 
1201  /* Instances of the requested KICAD_T live in a list, either one
1202  * that I manage, or that my modules manage. If it's a type managed
1203  * by class MODULE, then simply pass it on to each module's
1204  * MODULE::Visit() function by way of the
1205  * IterateForward( m_Modules, ... ) call.
1206  */
1207 
1208  case PCB_MODULE_T:
1209  case PCB_PAD_T:
1210  case PCB_MODULE_TEXT_T:
1211  case PCB_MODULE_EDGE_T:
1212 
1213  // this calls MODULE::Visit() on each module.
1214  result = IterateForward( m_Modules, inspector, testData, p );
1215 
1216  // skip over any types handled in the above call.
1217  for( ; ; )
1218  {
1219  switch( stype = *++p )
1220  {
1221  case PCB_MODULE_T:
1222  case PCB_PAD_T:
1223  case PCB_MODULE_TEXT_T:
1224  case PCB_MODULE_EDGE_T:
1225  continue;
1226 
1227  default:
1228  ;
1229  }
1230 
1231  break;
1232  }
1233 
1234  break;
1235 
1236  case PCB_LINE_T:
1237  case PCB_TEXT_T:
1238  case PCB_DIMENSION_T:
1239  case PCB_TARGET_T:
1240  result = IterateForward( m_Drawings, inspector, testData, p );
1241 
1242  // skip over any types handled in the above call.
1243  for( ; ; )
1244  {
1245  switch( stype = *++p )
1246  {
1247  case PCB_LINE_T:
1248  case PCB_TEXT_T:
1249  case PCB_DIMENSION_T:
1250  case PCB_TARGET_T:
1251  continue;
1252 
1253  default:
1254  ;
1255  }
1256 
1257  break;
1258  }
1259 
1260  ;
1261  break;
1262 
1263 #if 0 // both these are on same list, so we must scan it twice in order
1264  // to get VIA priority, using new #else code below.
1265  // But we are not using separate lists for TRACKs and VIA, because
1266  // items are ordered (sorted) in the linked
1267  // list by netcode AND by physical distance:
1268  // when created, if a track or via is connected to an existing track or
1269  // via, it is put in linked list after this existing track or via
1270  // So usually, connected tracks or vias are grouped in this list
1271  // So the algorithm (used in ratsnest computations) which computes the
1272  // track connectivity is faster (more than 100 time regarding to
1273  // a non ordered list) because when it searches for a connection, first
1274  // it tests the near (near in term of linked list) 50 items
1275  // from the current item (track or via) in test.
1276  // Usually, because of this sort, a connected item (if exists) is
1277  // found.
1278  // If not found (and only in this case) an exhaustive (and time
1279  // consuming) search is made, but this case is statistically rare.
1280  case PCB_VIA_T:
1281  case PCB_TRACE_T:
1282  result = IterateForward( m_Track, inspector, testData, p );
1283 
1284  // skip over any types handled in the above call.
1285  for( ; ; )
1286  {
1287  switch( stype = *++p )
1288  {
1289  case PCB_VIA_T:
1290  case PCB_TRACE_T:
1291  continue;
1292 
1293  default:
1294  ;
1295  }
1296 
1297  break;
1298  }
1299 
1300  break;
1301 
1302 #else
1303  case PCB_VIA_T:
1304  result = IterateForward( m_Track, inspector, testData, p );
1305  ++p;
1306  break;
1307 
1308  case PCB_TRACE_T:
1309  result = IterateForward( m_Track, inspector, testData, p );
1310  ++p;
1311  break;
1312 #endif
1313 
1314  case PCB_MARKER_T:
1315 
1316  // MARKER_PCBS are in the m_markers std::vector
1317  for( unsigned i = 0; i<m_markers.size(); ++i )
1318  {
1319  result = m_markers[i]->Visit( inspector, testData, p );
1320 
1321  if( result == SEARCH_QUIT )
1322  break;
1323  }
1324 
1325  ++p;
1326  break;
1327 
1328  case PCB_ZONE_AREA_T:
1329 
1330  // PCB_ZONE_AREA_T are in the m_ZoneDescriptorList std::vector
1331  for( unsigned i = 0; i< m_ZoneDescriptorList.size(); ++i )
1332  {
1333  result = m_ZoneDescriptorList[i]->Visit( inspector, testData, p );
1334 
1335  if( result == SEARCH_QUIT )
1336  break;
1337  }
1338 
1339  ++p;
1340  break;
1341 
1342  case PCB_ZONE_T:
1343  result = IterateForward( m_Zone, inspector, testData, p );
1344  ++p;
1345  break;
1346 
1347  default: // catch EOT or ANY OTHER type here and return.
1348  done = true;
1349  break;
1350  }
1351 
1352  if( result == SEARCH_QUIT )
1353  break;
1354  }
1355 
1356  return result;
1357 }
1358 
1359 
1360 NETINFO_ITEM* BOARD::FindNet( int aNetcode ) const
1361 {
1362  // the first valid netcode is 1 and the last is m_NetInfo.GetCount()-1.
1363  // zero is reserved for "no connection" and is not actually a net.
1364  // NULL is returned for non valid netcodes
1365 
1366  wxASSERT( m_NetInfo.GetNetCount() > 0 ); // net zero should exist
1367 
1368  if( aNetcode == NETINFO_LIST::UNCONNECTED && m_NetInfo.GetNetCount() == 0 )
1370  else
1371  return m_NetInfo.GetNetItem( aNetcode );
1372 }
1373 
1374 
1375 NETINFO_ITEM* BOARD::FindNet( const wxString& aNetname ) const
1376 {
1377  return m_NetInfo.GetNetItem( aNetname );
1378 }
1379 
1380 
1381 MODULE* BOARD::FindModuleByReference( const wxString& aReference ) const
1382 {
1383  MODULE* found = nullptr;
1384 
1385  // search only for MODULES
1386  static const KICAD_T scanTypes[] = { PCB_MODULE_T, EOT };
1387 
1388  INSPECTOR_FUNC inspector = [&] ( EDA_ITEM* item, void* testData )
1389  {
1390  MODULE* module = (MODULE*) item;
1391 
1392  if( aReference == module->GetReference() )
1393  {
1394  found = module;
1395  return SEARCH_QUIT;
1396  }
1397 
1398  return SEARCH_CONTINUE;
1399  };
1400 
1401  // visit this BOARD with the above inspector
1402  BOARD* nonconstMe = (BOARD*) this;
1403  nonconstMe->Visit( inspector, NULL, scanTypes );
1404 
1405  return found;
1406 }
1407 
1408 
1409 MODULE* BOARD::FindModule( const wxString& aRefOrTimeStamp, bool aSearchByTimeStamp ) const
1410 {
1411  if( aSearchByTimeStamp )
1412  {
1413  for( MODULE* module = m_Modules; module; module = module->Next() )
1414  {
1415  if( aRefOrTimeStamp.CmpNoCase( module->GetPath() ) == 0 )
1416  return module;
1417  }
1418  }
1419  else
1420  {
1421  return FindModuleByReference( aRefOrTimeStamp );
1422  }
1423 
1424  return NULL;
1425 }
1426 
1427 
1428 // Sort nets by decreasing pad count. For same pad count, sort by alphabetic names
1429 static bool sortNetsByNodes( const NETINFO_ITEM* a, const NETINFO_ITEM* b )
1430 {
1431  if( b->GetNodesCount() == a->GetNodesCount() )
1432  return a->GetNetname() < b->GetNetname();
1433 
1434  return b->GetNodesCount() < a->GetNodesCount();
1435 }
1436 
1437 // Sort nets by alphabetic names
1438 static bool sortNetsByNames( const NETINFO_ITEM* a, const NETINFO_ITEM* b )
1439 {
1440  return a->GetNetname() < b->GetNetname();
1441 }
1442 
1443 int BOARD::SortedNetnamesList( wxArrayString& aNames, bool aSortbyPadsCount )
1444 {
1445  if( m_NetInfo.GetNetCount() == 0 )
1446  return 0;
1447 
1448  // Build the list
1449  std::vector <NETINFO_ITEM*> netBuffer;
1450 
1451  netBuffer.reserve( m_NetInfo.GetNetCount() );
1452 
1453  for( NETINFO_LIST::iterator net( m_NetInfo.begin() ), netEnd( m_NetInfo.end() );
1454  net != netEnd; ++net )
1455  {
1456  if( net->GetNet() > 0 )
1457  netBuffer.push_back( *net );
1458  }
1459 
1460  // sort the list
1461  if( aSortbyPadsCount )
1462  sort( netBuffer.begin(), netBuffer.end(), sortNetsByNodes );
1463  else
1464  sort( netBuffer.begin(), netBuffer.end(), sortNetsByNames );
1465 
1466  for( unsigned ii = 0; ii < netBuffer.size(); ii++ )
1467  aNames.Add( netBuffer[ii]->GetNetname() );
1468 
1469  return netBuffer.size();
1470 }
1471 
1472 
1473 void BOARD::RedrawAreasOutlines( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode, PCB_LAYER_ID aLayer )
1474 {
1475  if( !aDC )
1476  return;
1477 
1478  for( int ii = 0; ii < GetAreaCount(); ii++ )
1479  {
1480  ZONE_CONTAINER* edge_zone = GetArea( ii );
1481 
1482  if( (aLayer < 0) || ( aLayer == edge_zone->GetLayer() ) )
1483  edge_zone->Draw( panel, aDC, aDrawMode );
1484  }
1485 }
1486 
1487 
1488 void BOARD::RedrawFilledAreas( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode, PCB_LAYER_ID aLayer )
1489 {
1490  if( !aDC )
1491  return;
1492 
1493  for( int ii = 0; ii < GetAreaCount(); ii++ )
1494  {
1495  ZONE_CONTAINER* edge_zone = GetArea( ii );
1496 
1497  if( (aLayer < 0) || ( aLayer == edge_zone->GetLayer() ) )
1498  edge_zone->DrawFilledArea( panel, aDC, aDrawMode );
1499  }
1500 }
1501 
1502 
1504  PCB_LAYER_ID aStartLayer, PCB_LAYER_ID aEndLayer, int aNetCode )
1505 {
1506  if( aEndLayer < 0 )
1507  aEndLayer = aStartLayer;
1508 
1509  if( aEndLayer < aStartLayer )
1510  std::swap( aEndLayer, aStartLayer );
1511 
1512  for( unsigned ia = 0; ia < m_ZoneDescriptorList.size(); ia++ )
1513  {
1515  LAYER_NUM layer = area->GetLayer();
1516 
1517  if( layer < aStartLayer || layer > aEndLayer )
1518  continue;
1519 
1520  // In locate functions we must skip tagged items with BUSY flag set.
1521  if( area->GetState( BUSY ) )
1522  continue;
1523 
1524  if( aNetCode >= 0 && area->GetNetCode() != aNetCode )
1525  continue;
1526 
1527  if( area->HitTestFilledArea( aRefPos ) )
1528  return area;
1529  }
1530 
1531  return NULL;
1532 }
1533 
1534 
1536 {
1537  int error_count = 0;
1538 
1539  for( int ii = 0; ii < GetAreaCount(); ii++ )
1540  {
1541  ZONE_CONTAINER* it = GetArea( ii );
1542 
1543  if( !it->IsOnCopperLayer() )
1544  {
1546  continue;
1547  }
1548 
1549  if( it->GetNetCode() != 0 ) // i.e. if this zone is connected to a net
1550  {
1551  const NETINFO_ITEM* net = it->GetNet();
1552 
1553  if( net )
1554  {
1555  it->SetNetCode( net->GetNet() );
1556  }
1557  else
1558  {
1559  error_count++;
1560 
1561  // keep Net Name and set m_NetCode to -1 : error flag.
1562  it->SetNetCode( -1 );
1563  }
1564  }
1565  }
1566 
1567  return error_count;
1568 }
1569 
1570 
1571 VIA* BOARD::GetViaByPosition( const wxPoint& aPosition, PCB_LAYER_ID aLayer) const
1572 {
1573  for( VIA *via = GetFirstVia( m_Track); via; via = GetFirstVia( via->Next() ) )
1574  {
1575  if( (via->GetStart() == aPosition) &&
1576  (via->GetState( BUSY | IS_DELETED ) == 0) &&
1577  ((aLayer == UNDEFINED_LAYER) || (via->IsOnLayer( aLayer ))) )
1578  return via;
1579  }
1580 
1581  return NULL;
1582 }
1583 
1584 
1585 D_PAD* BOARD::GetPad( const wxPoint& aPosition, LSET aLayerSet )
1586 {
1587  if( !aLayerSet.any() )
1588  aLayerSet = LSET::AllCuMask();
1589 
1590  for( MODULE* module = m_Modules; module; module = module->Next() )
1591  {
1592  D_PAD* pad = module->GetPad( aPosition, aLayerSet );
1593 
1594  if( pad )
1595  return pad;
1596  }
1597 
1598  return NULL;
1599 }
1600 
1601 
1602 D_PAD* BOARD::GetPad( TRACK* aTrace, ENDPOINT_T aEndPoint )
1603 {
1604  const wxPoint& aPosition = aTrace->GetEndPoint( aEndPoint );
1605 
1606  LSET lset( aTrace->GetLayer() );
1607 
1608  for( MODULE* module = m_Modules; module; module = module->Next() )
1609  {
1610  D_PAD* pad = module->GetPad( aPosition, lset );
1611 
1612  if( pad )
1613  return pad;
1614  }
1615 
1616  return NULL;
1617 }
1618 
1619 
1620 D_PAD* BOARD::GetPadFast( const wxPoint& aPosition, LSET aLayerSet )
1621 {
1622  for( unsigned i=0; i<GetPadCount(); ++i )
1623  {
1624  D_PAD* pad = m_NetInfo.GetPad(i);
1625 
1626  if( pad->GetPosition() != aPosition )
1627  continue;
1628 
1629  // Pad found, it must be on the correct layer
1630  if( ( pad->GetLayerSet() & aLayerSet ).any() )
1631  return pad;
1632  }
1633 
1634  return NULL;
1635 }
1636 
1637 
1638 D_PAD* BOARD::GetPad( std::vector<D_PAD*>& aPadList, const wxPoint& aPosition, LSET aLayerSet )
1639 {
1640  // Search aPadList for aPosition
1641  // aPadList is sorted by X then Y values, and a fast binary search is used
1642  int idxmax = aPadList.size()-1;
1643 
1644  int delta = aPadList.size();
1645 
1646  int idx = 0; // Starting index is the beginning of list
1647 
1648  while( delta )
1649  {
1650  // Calculate half size of remaining interval to test.
1651  // Ensure the computed value is not truncated (too small)
1652  if( (delta & 1) && ( delta > 1 ) )
1653  delta++;
1654 
1655  delta /= 2;
1656 
1657  D_PAD* pad = aPadList[idx];
1658 
1659  if( pad->GetPosition() == aPosition ) // candidate found
1660  {
1661  // The pad must match the layer mask:
1662  if( ( aLayerSet & pad->GetLayerSet() ).any() )
1663  return pad;
1664 
1665  // More than one pad can be at aPosition
1666  // search for a pad at aPosition that matched this mask
1667 
1668  // search next
1669  for( int ii = idx+1; ii <= idxmax; ii++ )
1670  {
1671  pad = aPadList[ii];
1672 
1673  if( pad->GetPosition() != aPosition )
1674  break;
1675 
1676  if( ( aLayerSet & pad->GetLayerSet() ).any() )
1677  return pad;
1678  }
1679  // search previous
1680  for( int ii = idx-1 ;ii >=0; ii-- )
1681  {
1682  pad = aPadList[ii];
1683 
1684  if( pad->GetPosition() != aPosition )
1685  break;
1686 
1687  if( ( aLayerSet & pad->GetLayerSet() ).any() )
1688  return pad;
1689  }
1690 
1691  // Not found:
1692  return 0;
1693  }
1694 
1695  if( pad->GetPosition().x == aPosition.x ) // Must search considering Y coordinate
1696  {
1697  if( pad->GetPosition().y < aPosition.y ) // Must search after this item
1698  {
1699  idx += delta;
1700 
1701  if( idx > idxmax )
1702  idx = idxmax;
1703  }
1704  else // Must search before this item
1705  {
1706  idx -= delta;
1707 
1708  if( idx < 0 )
1709  idx = 0;
1710  }
1711  }
1712  else if( pad->GetPosition().x < aPosition.x ) // Must search after this item
1713  {
1714  idx += delta;
1715 
1716  if( idx > idxmax )
1717  idx = idxmax;
1718  }
1719  else // Must search before this item
1720  {
1721  idx -= delta;
1722 
1723  if( idx < 0 )
1724  idx = 0;
1725  }
1726  }
1727 
1728  return NULL;
1729 }
1730 
1731 
1737 bool sortPadsByXthenYCoord( D_PAD* const & ref, D_PAD* const & comp )
1738 {
1739  if( ref->GetPosition().x == comp->GetPosition().x )
1740  return ref->GetPosition().y < comp->GetPosition().y;
1741  return ref->GetPosition().x < comp->GetPosition().x;
1742 }
1743 
1744 
1745 void BOARD::GetSortedPadListByXthenYCoord( std::vector<D_PAD*>& aVector, int aNetCode )
1746 {
1747  if( aNetCode < 0 )
1748  {
1749  aVector.insert( aVector.end(), m_NetInfo.m_PadsFullList.begin(),
1750  m_NetInfo.m_PadsFullList.end() );
1751  }
1752  else
1753  {
1754  const NETINFO_ITEM* net = m_NetInfo.GetNetItem( aNetCode );
1755  if( net )
1756  {
1757  aVector.insert( aVector.end(), net->m_PadInNetList.begin(),
1758  net->m_PadInNetList.end() );
1759  }
1760  }
1761 
1762  sort( aVector.begin(), aVector.end(), sortPadsByXthenYCoord );
1763 }
1764 
1765 
1767 {
1768  m_NetInfo.DeletePad( aPad );
1769 
1770  aPad->DeleteStructure();
1771 }
1772 
1773 
1774 TRACK* BOARD::GetVisibleTrack( TRACK* aStartingTrace, const wxPoint& aPosition,
1775  LSET aLayerSet ) const
1776 {
1777  for( TRACK* track = aStartingTrace; track; track = track->Next() )
1778  {
1779  PCB_LAYER_ID layer = track->GetLayer();
1780 
1781  if( track->GetState( BUSY | IS_DELETED ) )
1782  continue;
1783 
1784  // track's layer is not visible
1785  if( m_designSettings.IsLayerVisible( layer ) == false )
1786  continue;
1787 
1788  if( track->Type() == PCB_VIA_T ) // VIA encountered.
1789  {
1790  if( track->HitTest( aPosition ) )
1791  return track;
1792  }
1793  else
1794  {
1795  if( !aLayerSet[layer] )
1796  continue; // track's layer is not in aLayerSet
1797 
1798  if( track->HitTest( aPosition ) )
1799  return track;
1800  }
1801  }
1802 
1803  return NULL;
1804 }
1805 
1806 
1807 #if defined(DEBUG) && 0
1808 static void dump_tracks( const char* aName, const TRACKS& aList )
1809 {
1810  printf( "%s: count=%zd\n", aName, aList.size() );
1811 
1812  for( unsigned i = 0; i < aList.size(); ++i )
1813  {
1814  TRACK* seg = aList[i];
1815  ::VIA* via = dynamic_cast< ::VIA* >( seg );
1816 
1817  if( via )
1818  printf( " via[%u]: (%d, %d)\n", i, via->GetStart().x, via->GetStart().y );
1819  else
1820  printf( " seg[%u]: (%d, %d) (%d, %d)\n", i,
1821  seg->GetStart().x, seg->GetStart().y,
1822  seg->GetEnd().x, seg->GetEnd().y );
1823  }
1824 }
1825 #endif
1826 
1827 
1828 
1829 
1830 TRACK* BOARD::MarkTrace( TRACK* aTrace, int* aCount,
1831  double* aTraceLength, double* aPadToDieLength,
1832  bool aReorder )
1833 {
1834  TRACKS trackList;
1835 
1836  if( aCount )
1837  *aCount = 0;
1838 
1839  if( aTraceLength )
1840  *aTraceLength = 0;
1841 
1842  if( aTrace == NULL )
1843  return NULL;
1844 
1845  // Ensure the flag BUSY of all tracks of the board is cleared
1846  // because we use it to mark segments of the track
1847  for( TRACK* track = m_Track; track; track = track->Next() )
1848  track->SetState( BUSY, false );
1849 
1850  // Set flags of the initial track segment
1851  aTrace->SetState( BUSY, true );
1852  LSET layer_set = aTrace->GetLayerSet();
1853 
1854  trackList.push_back( aTrace );
1855 
1856  /* Examine the initial track segment : if it is really a segment, this is
1857  * easy.
1858  * If it is a via, one must search for connected segments.
1859  * If <=2, this via connect 2 segments (or is connected to only one
1860  * segment) and this via and these 2 segments are a part of a track.
1861  * If > 2 only this via is flagged (the track has only this via)
1862  */
1863  if( aTrace->Type() == PCB_VIA_T )
1864  {
1865  TRACK* segm1 = ::GetTrack( m_Track, NULL, aTrace->GetStart(), layer_set );
1866  TRACK* segm2 = NULL;
1867  TRACK* segm3 = NULL;
1868 
1869  if( segm1 )
1870  {
1871  segm2 = ::GetTrack( segm1->Next(), NULL, aTrace->GetStart(), layer_set );
1872  }
1873 
1874  if( segm2 )
1875  {
1876  segm3 = ::GetTrack( segm2->Next(), NULL, aTrace->GetStart(), layer_set );
1877  }
1878 
1879  if( segm3 )
1880  {
1881  // More than 2 segments are connected to this via.
1882  // The "track" is only this via.
1883 
1884  if( aCount )
1885  *aCount = 1;
1886 
1887  return aTrace;
1888  }
1889 
1890  if( segm1 ) // search for other segments connected to the initial segment start point
1891  {
1892  layer_set = segm1->GetLayerSet();
1893  chainMarkedSegments( aTrace->GetStart(), layer_set, &trackList );
1894  }
1895 
1896  if( segm2 ) // search for other segments connected to the initial segment end point
1897  {
1898  layer_set = segm2->GetLayerSet();
1899  chainMarkedSegments( aTrace->GetStart(), layer_set, &trackList );
1900  }
1901  }
1902  else // mark the chain using both ends of the initial segment
1903  {
1904  TRACKS from_start;
1905  TRACKS from_end;
1906 
1907  chainMarkedSegments( aTrace->GetStart(), layer_set, &from_start );
1908  chainMarkedSegments( aTrace->GetEnd(), layer_set, &from_end );
1909 
1910  // DBG( dump_tracks( "first_clicked", trackList ); )
1911  // DBG( dump_tracks( "from_start", from_start ); )
1912  // DBG( dump_tracks( "from_end", from_end ); )
1913 
1914  // combine into one trackList:
1915  trackList.insert( trackList.end(), from_start.begin(), from_start.end() );
1916  trackList.insert( trackList.end(), from_end.begin(), from_end.end() );
1917  }
1918 
1919  // Now examine selected vias and flag them if they are on the track
1920  // If a via is connected to only one or 2 segments, it is flagged (is on the track)
1921  // If a via is connected to more than 2 segments, it is a track end, and it
1922  // is removed from the list.
1923  // Go through the list backwards.
1924  for( int i = trackList.size() - 1; i>=0; --i )
1925  {
1926  ::VIA* via = dynamic_cast< ::VIA* >( trackList[i] );
1927 
1928  if( !via )
1929  continue;
1930 
1931  if( via == aTrace )
1932  continue;
1933 
1934  via->SetState( BUSY, true ); // Try to flag it. the flag will be cleared later if needed
1935 
1936  layer_set = via->GetLayerSet();
1937 
1938  TRACK* track = ::GetTrack( m_Track, NULL, via->GetStart(), layer_set );
1939 
1940  // GetTrace does not consider tracks flagged BUSY.
1941  // So if no connected track found, this via is on the current track
1942  // only: keep it
1943  if( track == NULL )
1944  continue;
1945 
1946  /* If a track is found, this via connects also other segments of
1947  * another track. This case happens when a via ends the selected
1948  * track but must we consider this via is on the selected track, or
1949  * on another track.
1950  * (this is important when selecting a track for deletion: must this
1951  * via be deleted or not?)
1952  * We consider this via to be on our track if other segments connected
1953  * to this via remain connected when removing this via.
1954  * We search for all other segments connected together:
1955  * if they are on the same layer, then the via is on the selected track;
1956  * if they are on different layers, the via is on another track.
1957  */
1958  LAYER_NUM layer = track->GetLayer();
1959 
1960  while( ( track = ::GetTrack( track->Next(), NULL, via->GetStart(), layer_set ) ) != NULL )
1961  {
1962  if( layer != track->GetLayer() )
1963  {
1964  // The via connects segments of another track: it is removed
1965  // from list because it is member of another track
1966 
1967  DBG(printf( "%s: omit track (%d, %d) (%d, %d) on layer:%d (!= our_layer:%d)\n",
1968  __func__,
1969  track->GetStart().x, track->GetStart().y,
1970  track->GetEnd().x, track->GetEnd().y,
1971  track->GetLayer(), layer
1972  ); )
1973 
1974  via->SetState( BUSY, false );
1975  break;
1976  }
1977  }
1978  }
1979 
1980  /* Rearrange the track list in order to have flagged segments linked
1981  * from firstTrack so the NbSegmBusy segments are consecutive segments
1982  * in list, the first item in the full track list is firstTrack, and
1983  * the NbSegmBusy-1 next items (NbSegmBusy when including firstTrack)
1984  * are the flagged segments
1985  */
1986  int busy_count = 0;
1987  TRACK* firstTrack;
1988 
1989  for( firstTrack = m_Track; firstTrack; firstTrack = firstTrack->Next() )
1990  {
1991  // Search for the first flagged BUSY segments
1992  if( firstTrack->GetState( BUSY ) )
1993  {
1994  busy_count = 1;
1995  break;
1996  }
1997  }
1998 
1999  if( firstTrack == NULL )
2000  return NULL;
2001 
2002  // First step: calculate the track length and find the pads (when exist)
2003  // at each end of the trace.
2004  double full_len = 0;
2005  double lenPadToDie = 0;
2006  // Because we have a track (a set of track segments between 2 nodes),
2007  // only 2 pads (maximum) will be taken in account:
2008  // that are on each end of the track, if any.
2009  // keep trace of them, to know the die length and the track length ibside each pad.
2010  D_PAD* s_pad = NULL; // the pad on one end of the trace
2011  D_PAD* e_pad = NULL; // the pad on the other end of the trace
2012  int dist_fromstart = INT_MAX;
2013  int dist_fromend = INT_MAX;
2014 
2015  for( TRACK* track = firstTrack; track; track = track->Next() )
2016  {
2017  if( !track->GetState( BUSY ) )
2018  continue;
2019 
2020  layer_set = track->GetLayerSet();
2021  D_PAD * pad_on_start = GetPad( track->GetStart(), layer_set );
2022  D_PAD * pad_on_end = GetPad( track->GetEnd(), layer_set );
2023 
2024  // a segment fully inside a pad does not contribute to the track len
2025  // (an other track end inside this pad will contribute to this lenght)
2026  if( pad_on_start && ( pad_on_start == pad_on_end ) )
2027  continue;
2028 
2029  full_len += track->GetLength();
2030 
2031  if( pad_on_start == NULL && pad_on_end == NULL )
2032  // This most of time the case
2033  continue;
2034 
2035  // At this point, we can have one track end on a pad, or the 2 track ends on
2036  // 2 different pads.
2037  // We don't know what pad (s_pad or e_pad) must be used to store the
2038  // start point and the end point of the track, so if a pad is already set,
2039  // use the other
2040  if( pad_on_start )
2041  {
2042  SEG segm( track->GetStart(), pad_on_start->GetPosition() );
2043  int dist = segm.Length();
2044 
2045  if( s_pad == NULL )
2046  {
2047  dist_fromstart = dist;
2048  s_pad = pad_on_start;
2049  }
2050  else if( e_pad == NULL )
2051  {
2052  dist_fromend = dist;
2053  e_pad = pad_on_start;
2054  }
2055  else // Should not occur, at least for basic pads
2056  {
2057  // wxLogMessage( "BOARD::MarkTrace: multiple pad_on_start" );
2058  }
2059  }
2060 
2061  if( pad_on_end )
2062  {
2063  SEG segm( track->GetEnd(), pad_on_end->GetPosition() );
2064  int dist = segm.Length();
2065 
2066  if( s_pad == NULL )
2067  {
2068  dist_fromstart = dist;
2069  s_pad = pad_on_end;
2070  }
2071  else if( e_pad == NULL )
2072  {
2073  dist_fromend = dist;
2074  e_pad = pad_on_end;
2075  }
2076  else // Should not occur, at least for basic pads
2077  {
2078  // wxLogMessage( "BOARD::MarkTrace: multiple pad_on_end" );
2079  }
2080  }
2081  }
2082 
2083  if( aReorder )
2084  {
2085  DLIST<TRACK>* list = (DLIST<TRACK>*)firstTrack->GetList();
2086  wxASSERT( list );
2087 
2088  /* Rearrange the chain starting at firstTrack
2089  * All other BUSY flagged items are moved from their position to the end
2090  * of the flagged list
2091  */
2092  TRACK* next;
2093 
2094  for( TRACK* track = firstTrack->Next(); track; track = next )
2095  {
2096  next = track->Next();
2097 
2098  if( track->GetState( BUSY ) ) // move it!
2099  {
2100  busy_count++;
2101  track->UnLink();
2102  list->Insert( track, firstTrack->Next() );
2103 
2104  }
2105  }
2106  }
2107  else if( aTraceLength )
2108  {
2109  busy_count = 0;
2110 
2111  for( TRACK* track = firstTrack; track; track = track->Next() )
2112  {
2113  if( track->GetState( BUSY ) )
2114  {
2115  busy_count++;
2116  track->SetState( BUSY, false );
2117  }
2118  }
2119 
2120  DBG( printf( "%s: busy_count:%d\n", __func__, busy_count ); )
2121  }
2122 
2123  if( s_pad )
2124  {
2125  full_len += dist_fromstart;
2126  lenPadToDie += (double) s_pad->GetPadToDieLength();
2127  }
2128 
2129  if( e_pad )
2130  {
2131  full_len += dist_fromend;
2132  lenPadToDie += (double) e_pad->GetPadToDieLength();
2133  }
2134 
2135  if( aTraceLength )
2136  *aTraceLength = full_len;
2137 
2138  if( aPadToDieLength )
2139  *aPadToDieLength = lenPadToDie;
2140 
2141  if( aCount )
2142  *aCount = busy_count;
2143 
2144  return firstTrack;
2145 }
2146 
2147 
2148 MODULE* BOARD::GetFootprint( const wxPoint& aPosition, PCB_LAYER_ID aActiveLayer,
2149  bool aVisibleOnly, bool aIgnoreLocked )
2150 {
2151  MODULE* pt_module;
2152  MODULE* module = NULL;
2153  MODULE* alt_module = NULL;
2154  int min_dim = 0x7FFFFFFF;
2155  int alt_min_dim = 0x7FFFFFFF;
2156  bool current_layer_back = IsBackLayer( aActiveLayer );
2157 
2158  for( pt_module = m_Modules; pt_module; pt_module = pt_module->Next() )
2159  {
2160  // is the ref point within the module's bounds?
2161  if( !pt_module->HitTest( aPosition ) )
2162  continue;
2163 
2164  // if caller wants to ignore locked modules, and this one is locked, skip it.
2165  if( aIgnoreLocked && pt_module->IsLocked() )
2166  continue;
2167 
2168  PCB_LAYER_ID layer = pt_module->GetLayer();
2169 
2170  // Filter non visible modules if requested
2171  if( !aVisibleOnly || IsModuleLayerVisible( layer ) )
2172  {
2173  EDA_RECT bb = pt_module->GetFootprintRect();
2174 
2175  int offx = bb.GetX() + bb.GetWidth() / 2;
2176  int offy = bb.GetY() + bb.GetHeight() / 2;
2177 
2178  // off x & offy point to the middle of the box.
2179  int dist = ( aPosition.x - offx ) * ( aPosition.x - offx ) +
2180  ( aPosition.y - offy ) * ( aPosition.y - offy );
2181 
2182  if( current_layer_back == IsBackLayer( layer ) )
2183  {
2184  if( dist <= min_dim )
2185  {
2186  // better footprint shown on the active side
2187  module = pt_module;
2188  min_dim = dist;
2189  }
2190  }
2191  else if( aVisibleOnly && IsModuleLayerVisible( layer ) )
2192  {
2193  if( dist <= alt_min_dim )
2194  {
2195  // better footprint shown on the other side
2196  alt_module = pt_module;
2197  alt_min_dim = dist;
2198  }
2199  }
2200  }
2201  }
2202 
2203  if( module )
2204  {
2205  return module;
2206  }
2207 
2208  if( alt_module)
2209  {
2210  return alt_module;
2211  }
2212 
2213  return NULL;
2214 }
2215 
2216 
2217 BOARD_CONNECTED_ITEM* BOARD::GetLockPoint( const wxPoint& aPosition, LSET aLayerSet )
2218 {
2219  for( MODULE* module = m_Modules; module; module = module->Next() )
2220  {
2221  D_PAD* pad = module->GetPad( aPosition, aLayerSet );
2222 
2223  if( pad )
2224  return pad;
2225  }
2226 
2227  // No pad has been located so check for a segment of the trace.
2228  TRACK* segment = ::GetTrack( m_Track, NULL, aPosition, aLayerSet );
2229 
2230  if( !segment )
2231  segment = GetVisibleTrack( m_Track, aPosition, aLayerSet );
2232 
2233  return segment;
2234 }
2235 
2236 
2238 {
2239  /* creates an intermediate point on aSegment and break it into two segments
2240  * at aPosition.
2241  * The new segment starts from aPosition and ends at the end point of
2242  * aSegment. The original segment now ends at aPosition.
2243  */
2244  if( aSegment->GetStart() == aPosition || aSegment->GetEnd() == aPosition )
2245  return NULL;
2246 
2247  // A via is a good lock point
2248  if( aSegment->Type() == PCB_VIA_T )
2249  {
2250  aPosition = aSegment->GetStart();
2251  return aSegment;
2252  }
2253 
2254  // Calculation coordinate of intermediate point relative to the start point of aSegment
2255  wxPoint delta = aSegment->GetEnd() - aSegment->GetStart();
2256 
2257  // calculate coordinates of aPosition relative to aSegment->GetStart()
2258  wxPoint lockPoint = aPosition - aSegment->GetStart();
2259 
2260  // lockPoint must be on aSegment:
2261  // Ensure lockPoint.y/lockPoint.y = delta.y/delta.x
2262  if( delta.x == 0 )
2263  lockPoint.x = 0; // horizontal segment
2264  else
2265  lockPoint.y = KiROUND( ( (double)lockPoint.x * delta.y ) / delta.x );
2266 
2267  /* Create the intermediate point (that is to say creation of a new
2268  * segment, beginning at the intermediate point.
2269  */
2270  lockPoint += aSegment->GetStart();
2271 
2272  TRACK* newTrack = (TRACK*)aSegment->Clone();
2273  // The new segment begins at the new point,
2274  newTrack->SetStart(lockPoint);
2275  newTrack->start = aSegment;
2276  newTrack->SetState( BEGIN_ONPAD, false );
2277 
2278  DLIST<TRACK>* list = (DLIST<TRACK>*)aSegment->GetList();
2279  wxASSERT( list );
2280  list->Insert( newTrack, aSegment->Next() );
2281 
2282  if( aList )
2283  {
2284  // Prepare the undo command for the now track segment
2285  ITEM_PICKER picker( newTrack, UR_NEW );
2286  aList->PushItem( picker );
2287  // Prepare the undo command for the old track segment
2288  // before modifications
2289  picker.SetItem( aSegment );
2290  picker.SetStatus( UR_CHANGED );
2291  picker.SetLink( aSegment->Clone() );
2292  aList->PushItem( picker );
2293  }
2294 
2295  // Old track segment now ends at new point.
2296  aSegment->SetEnd(lockPoint);
2297  aSegment->end = newTrack;
2298  aSegment->SetState( END_ONPAD, false );
2299 
2300  D_PAD * pad = GetPad( newTrack, ENDPOINT_START );
2301 
2302  if( pad )
2303  {
2304  newTrack->start = pad;
2305  newTrack->SetState( BEGIN_ONPAD, true );
2306  aSegment->end = pad;
2307  aSegment->SetState( END_ONPAD, true );
2308  }
2309 
2310  aPosition = lockPoint;
2311  return newTrack;
2312 }
2313 
2314 
2315 ZONE_CONTAINER* BOARD::AddArea( PICKED_ITEMS_LIST* aNewZonesList, int aNetcode,
2316  PCB_LAYER_ID aLayer, wxPoint aStartPointPosition, int aHatch )
2317 {
2318  ZONE_CONTAINER* new_area = InsertArea( aNetcode,
2319  m_ZoneDescriptorList.size( ) - 1,
2320  aLayer, aStartPointPosition.x,
2321  aStartPointPosition.y, aHatch );
2322 
2323  if( aNewZonesList )
2324  {
2325  ITEM_PICKER picker( new_area, UR_NEW );
2326  aNewZonesList->PushItem( picker );
2327  }
2328 
2329  return new_area;
2330 }
2331 
2332 
2333 void BOARD::RemoveArea( PICKED_ITEMS_LIST* aDeletedList, ZONE_CONTAINER* area_to_remove )
2334 {
2335  if( area_to_remove == NULL )
2336  return;
2337 
2338  if( aDeletedList )
2339  {
2340  ITEM_PICKER picker( area_to_remove, UR_DELETED );
2341  aDeletedList->PushItem( picker );
2342  Remove( area_to_remove ); // remove from zone list, but does not delete it
2343  }
2344  else
2345  {
2346  Delete( area_to_remove );
2347  }
2348 }
2349 
2350 
2351 ZONE_CONTAINER* BOARD::InsertArea( int netcode, int iarea, PCB_LAYER_ID layer, int x, int y, int hatch )
2352 {
2353  ZONE_CONTAINER* new_area = new ZONE_CONTAINER( this );
2354 
2355  new_area->SetNetCode( netcode );
2356  new_area->SetLayer( layer );
2357  new_area->SetTimeStamp( GetNewTimeStamp() );
2358 
2359  if( iarea < (int) ( m_ZoneDescriptorList.size() - 1 ) )
2360  m_ZoneDescriptorList.insert( m_ZoneDescriptorList.begin() + iarea + 1, new_area );
2361  else
2362  m_ZoneDescriptorList.push_back( new_area );
2363 
2364  new_area->SetHatchStyle( (ZONE_CONTAINER::HATCH_STYLE) hatch );
2365  new_area->AppendCorner( wxPoint( x, y ) );
2366 
2367  return new_area;
2368 }
2369 
2370 
2372 {
2373  // mark all areas as unmodified except this one, if modified
2374  for( unsigned ia = 0; ia < m_ZoneDescriptorList.size(); ia++ )
2375  m_ZoneDescriptorList[ia]->SetLocalFlags( 0 );
2376 
2377  aCurrArea->SetLocalFlags( 1 );
2378 
2379  if( aCurrArea->Outline()->IsSelfIntersecting() )
2380  {
2381  aCurrArea->UnHatch();
2382 
2383  // Normalize copied area and store resulting number of polygons
2384  int n_poly = aCurrArea->Outline()->NormalizeAreaOutlines();
2385 
2386  // If clipping has created some polygons, we must add these new copper areas.
2387  if( n_poly > 1 )
2388  {
2389  ZONE_CONTAINER* NewArea;
2390 
2391  // Move the newly created polygons to new areas, removing them from the current area
2392  for( int ip = 1; ip < n_poly; ip++ )
2393  {
2394  // Create new copper area and copy poly into it
2395  SHAPE_POLY_SET* new_p = new SHAPE_POLY_SET( aCurrArea->Outline()->UnitSet( ip ) );
2396  NewArea = AddArea( aNewZonesList, aCurrArea->GetNetCode(), aCurrArea->GetLayer(),
2397  wxPoint(0, 0), aCurrArea->GetHatchStyle() );
2398 
2399  // remove the poly that was automatically created for the new area
2400  // and replace it with a poly from NormalizeAreaOutlines
2401  delete NewArea->Outline();
2402  NewArea->SetOutline( new_p );
2403  NewArea->Hatch();
2404  NewArea->SetLocalFlags( 1 );
2405  }
2406 
2407  SHAPE_POLY_SET* new_p = new SHAPE_POLY_SET( aCurrArea->Outline()->UnitSet( 0 ) );
2408  delete aCurrArea->Outline();
2409  aCurrArea->SetOutline( new_p );
2410  }
2411  }
2412 
2413  aCurrArea->Hatch();
2414 
2415  return true;
2416 }
2417 
2418 
2419 void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets,
2420  std::vector<MODULE*>* aNewFootprints, REPORTER* aReporter )
2421 {
2422  unsigned i;
2423  wxPoint bestPosition;
2424  wxString msg;
2425  std::vector<MODULE*> newFootprints;
2426 
2427  if( !IsEmpty() )
2428  {
2429  // Position new components below any existing board features.
2431 
2432  if( bbbox.GetWidth() || bbbox.GetHeight() )
2433  {
2434  bestPosition.x = bbbox.Centre().x;
2435  bestPosition.y = bbbox.GetBottom() + Millimeter2iu( 10 );
2436  }
2437  }
2438  else
2439  {
2440  // Position new components in the center of the page when the board is empty.
2441  wxSize pageSize = m_paper.GetSizeIU();
2442 
2443  bestPosition.x = pageSize.GetWidth() / 2;
2444  bestPosition.y = pageSize.GetHeight() / 2;
2445  }
2446 
2447  m_Status_Pcb = 0;
2448 
2449  for( i = 0; i < aNetlist.GetCount(); i++ )
2450  {
2451  COMPONENT* component = aNetlist.GetComponent( i );
2452  MODULE* footprint;
2453 
2454  if( aReporter )
2455  {
2456 
2457  msg.Printf( _( "Checking netlist component footprint \"%s:%s:%s\".\n" ),
2458  GetChars( component->GetReference() ),
2459  GetChars( component->GetTimeStamp() ),
2460  GetChars( FROM_UTF8( component->GetFPID().Format() ) ) );
2461  aReporter->Report( msg, REPORTER::RPT_INFO );
2462  }
2463 
2464  if( aNetlist.IsFindByTimeStamp() )
2465  footprint = FindModule( aNetlist.GetComponent( i )->GetTimeStamp(), true );
2466  else
2467  footprint = FindModule( aNetlist.GetComponent( i )->GetReference() );
2468 
2469  if( footprint == NULL ) // A new footprint.
2470  {
2471  if( aReporter )
2472  {
2473  if( component->GetModule() != NULL )
2474  {
2475  msg.Printf( _( "Adding new component \"%s:%s\" footprint \"%s\".\n" ),
2476  GetChars( component->GetReference() ),
2477  GetChars( component->GetTimeStamp() ),
2478  GetChars( FROM_UTF8( component->GetFPID().Format() ) ) );
2479 
2480  aReporter->Report( msg, REPORTER::RPT_ACTION );
2481  }
2482  else
2483  {
2484  msg.Printf( _( "Cannot add new component \"%s:%s\" due to missing "
2485  "footprint \"%s\".\n" ),
2486  GetChars( component->GetReference() ),
2487  GetChars( component->GetTimeStamp() ),
2488  GetChars( FROM_UTF8( component->GetFPID().Format() ) ) );
2489 
2490  aReporter->Report( msg, REPORTER::RPT_ERROR );
2491  }
2492  }
2493 
2494  if( !aNetlist.IsDryRun() && (component->GetModule() != NULL) )
2495  {
2496  // Owned by NETLIST, can only copy it.
2497  footprint = new MODULE( *component->GetModule() );
2498  footprint->SetParent( this );
2499  footprint->SetPosition( bestPosition );
2500  footprint->SetTimeStamp( GetNewTimeStamp() );
2501  newFootprints.push_back( footprint );
2502  Add( footprint, ADD_APPEND );
2503  }
2504  }
2505  else // An existing footprint.
2506  {
2507  // Test for footprint change.
2508  if( !component->GetFPID().empty() &&
2509  footprint->GetFPID() != component->GetFPID() )
2510  {
2511  if( aNetlist.GetReplaceFootprints() )
2512  {
2513  if( aReporter )
2514  {
2515  if( component->GetModule() != NULL )
2516  {
2517  msg.Printf( _( "Replacing component \"%s:%s\" footprint \"%s\" with "
2518  "\"%s\".\n" ),
2519  GetChars( footprint->GetReference() ),
2520  GetChars( footprint->GetPath() ),
2521  GetChars( FROM_UTF8( footprint->GetFPID().Format() ) ),
2522  GetChars( FROM_UTF8( component->GetFPID().Format() ) ) );
2523 
2524  aReporter->Report( msg, REPORTER::RPT_ACTION );
2525  }
2526  else
2527  {
2528  msg.Printf( _( "Cannot replace component \"%s:%s\" due to missing "
2529  "footprint \"%s\".\n" ),
2530  GetChars( footprint->GetReference() ),
2531  GetChars( footprint->GetPath() ),
2532  GetChars( FROM_UTF8( component->GetFPID().Format() ) ) );
2533 
2534  aReporter->Report( msg, REPORTER::RPT_ERROR );
2535  }
2536  }
2537 
2538  if( !aNetlist.IsDryRun() && (component->GetModule() != NULL) )
2539  {
2540  wxASSERT( footprint != NULL );
2541  MODULE* newFootprint = new MODULE( *component->GetModule() );
2542 
2543  if( aNetlist.IsFindByTimeStamp() )
2544  newFootprint->SetReference( footprint->GetReference() );
2545  else
2546  newFootprint->SetPath( footprint->GetPath() );
2547 
2548  // Copy placement and pad net names.
2549  // optionally, copy or not local settings (like local clearances)
2550  // if the second parameter is "true", previous values will be used.
2551  // if "false", the default library values of the new footprint
2552  // will be used
2553  footprint->CopyNetlistSettings( newFootprint, false );
2554 
2555  // Compare the footprint name only, in case the nickname is empty or in case
2556  // user moved the footprint to a new library. Chances are if footprint name is
2557  // same then the footprint is very nearly the same and the two texts should
2558  // be kept at same size, position, and rotation.
2559  if( newFootprint->GetFPID().GetLibItemName() == footprint->GetFPID().GetLibItemName() )
2560  {
2561  newFootprint->Reference().SetEffects( footprint->Reference() );
2562  newFootprint->Value().SetEffects( footprint->Value() );
2563  }
2564 
2565  Remove( footprint );
2566  Add( newFootprint, ADD_APPEND );
2567  footprint = newFootprint;
2568  }
2569  }
2570  }
2571 
2572  // Test for reference designator field change.
2573  if( footprint->GetReference() != component->GetReference() )
2574  {
2575  if( aReporter )
2576  {
2577  msg.Printf( _( "Changing component \"%s:%s\" reference to \"%s\".\n" ),
2578  GetChars( footprint->GetReference() ),
2579  GetChars( footprint->GetPath() ),
2580  GetChars( component->GetReference() ) );
2581  aReporter->Report( msg, REPORTER::RPT_ACTION );
2582  }
2583 
2584  if( !aNetlist.IsDryRun() )
2585  footprint->SetReference( component->GetReference() );
2586  }
2587 
2588  // Test for value field change.
2589  if( footprint->GetValue() != component->GetValue() )
2590  {
2591  if( aReporter )
2592  {
2593  msg.Printf( _( "Changing component \"%s:%s\" value from \"%s\" to \"%s\".\n" ),
2594  GetChars( footprint->GetReference() ),
2595  GetChars( footprint->GetPath() ),
2596  GetChars( footprint->GetValue() ),
2597  GetChars( component->GetValue() ) );
2598  aReporter->Report( msg, REPORTER::RPT_ACTION );
2599  }
2600 
2601  if( !aNetlist.IsDryRun() )
2602  footprint->SetValue( component->GetValue() );
2603  }
2604 
2605  // Test for time stamp change.
2606  if( footprint->GetPath() != component->GetTimeStamp() )
2607  {
2608  if( aReporter )
2609  {
2610  msg.Printf( _( "Changing component path \"%s:%s\" to \"%s\".\n" ),
2611  GetChars( footprint->GetReference() ),
2612  GetChars( footprint->GetPath() ),
2613  GetChars( component->GetTimeStamp() ) );
2614  aReporter->Report( msg, REPORTER::RPT_INFO );
2615  }
2616 
2617  if( !aNetlist.IsDryRun() )
2618  footprint->SetPath( component->GetTimeStamp() );
2619  }
2620  }
2621 
2622  if( footprint == NULL )
2623  continue;
2624 
2625  // At this point, the component footprint is updated. Now update the nets.
2626  for( D_PAD* pad = footprint->Pads(); pad; pad = pad->Next() )
2627  {
2628  COMPONENT_NET net = component->GetNet( pad->GetPadName() );
2629 
2630  if( !net.IsValid() ) // Footprint pad had no net.
2631  {
2632  if( aReporter && !pad->GetNetname().IsEmpty() )
2633  {
2634  msg.Printf( _( "Clearing component \"%s:%s\" pin \"%s\" net name.\n" ),
2635  GetChars( footprint->GetReference() ),
2636  GetChars( footprint->GetPath() ),
2637  GetChars( pad->GetPadName() ) );
2638  aReporter->Report( msg, REPORTER::RPT_ACTION );
2639  }
2640 
2641  if( !aNetlist.IsDryRun() )
2642  pad->SetNetCode( NETINFO_LIST::UNCONNECTED );
2643  }
2644  else // Footprint pad has a net.
2645  {
2646  if( net.GetNetName() != pad->GetNetname() )
2647  {
2648  if( aReporter )
2649  {
2650  msg.Printf( _( "Changing component \"%s:%s\" pin \"%s\" net name from "
2651  "\"%s\" to \"%s\".\n" ),
2652  GetChars( footprint->GetReference() ),
2653  GetChars( footprint->GetPath() ),
2654  GetChars( pad->GetPadName() ),
2655  GetChars( pad->GetNetname() ),
2656  GetChars( net.GetNetName() ) );
2657  aReporter->Report( msg, REPORTER::RPT_ACTION );
2658  }
2659 
2660  if( !aNetlist.IsDryRun() )
2661  {
2662  NETINFO_ITEM* netinfo = FindNet( net.GetNetName() );
2663  if( netinfo == NULL )
2664  {
2665  // It is a new net, we have to add it
2666  netinfo = new NETINFO_ITEM( this, net.GetNetName() );
2667  Add( netinfo );
2668  }
2669 
2670  pad->SetNetCode( netinfo->GetNet() );
2671  }
2672  }
2673  }
2674  }
2675  }
2676 
2677  // Remove all components not in the netlist.
2678  if( aNetlist.GetDeleteExtraFootprints() )
2679  {
2680  MODULE* nextModule;
2681  const COMPONENT* component;
2682 
2683  for( MODULE* module = m_Modules; module != NULL; module = nextModule )
2684  {
2685  nextModule = module->Next();
2686 
2687  if( module->IsLocked() )
2688  continue;
2689 
2690  if( aNetlist.IsFindByTimeStamp() )
2691  component = aNetlist.GetComponentByTimeStamp( module->GetPath() );
2692  else
2693  component = aNetlist.GetComponentByReference( module->GetReference() );
2694 
2695  if( component == NULL )
2696  {
2697  if( aReporter )
2698  {
2699  msg.Printf( _( "Removing unused component \"%s:%s\".\n" ),
2700  GetChars( module->GetReference() ),
2701  GetChars( module->GetPath() ) );
2702  aReporter->Report( msg, REPORTER::RPT_ACTION );
2703  }
2704 
2705  if( !aNetlist.IsDryRun() )
2706  module->DeleteStructure();
2707  }
2708  }
2709  }
2710 
2711  // We need the pad list, for next tests.
2712  // padlist is the list of pads, sorted by netname.
2713  BuildListOfNets();
2714  std::vector<D_PAD*> padlist = GetPads();
2715 
2716  // If needed, remove the single pad nets:
2717  if( aDeleteSinglePadNets && !aNetlist.IsDryRun() )
2718  {
2719  int count = 0;
2720  wxString netname;
2721  D_PAD* pad = NULL;
2722  D_PAD* previouspad = NULL;
2723 
2724  for( unsigned kk = 0; kk < padlist.size(); kk++ )
2725  {
2726  pad = padlist[kk];
2727 
2728  if( pad->GetNetname().IsEmpty() )
2729  continue;
2730 
2731  if( netname != pad->GetNetname() ) // End of net
2732  {
2733  if( previouspad && count == 1 )
2734  {
2735  // First, see if we have a copper zone attached to this pad.
2736  // If so, this is not really a single pad net
2737 
2738  for( int ii = 0; ii < GetAreaCount(); ii++ )
2739  {
2740  ZONE_CONTAINER* zone = GetArea( ii );
2741 
2742  if( !zone->IsOnCopperLayer() )
2743  continue;
2744 
2745  if( zone->GetIsKeepout() )
2746  continue;
2747 
2748  if( zone->GetNet() == previouspad->GetNet() )
2749  {
2750  count++;
2751  break;
2752  }
2753  }
2754 
2755  if( count == 1 ) // Really one pad, and nothing else
2756  {
2757  if( aReporter )
2758  {
2759  msg.Printf( _( "Remove single pad net \"%s\" on \"%s\" pad '%s'\n" ),
2760  GetChars( previouspad->GetNetname() ),
2761  GetChars( previouspad->GetParent()->GetReference() ),
2762  GetChars( previouspad->GetPadName() ) );
2763  aReporter->Report( msg, REPORTER::RPT_ACTION );
2764  }
2765 
2766  previouspad->SetNetCode( NETINFO_LIST::UNCONNECTED );
2767  }
2768  }
2769 
2770  netname = pad->GetNetname();
2771  count = 1;
2772  }
2773  else
2774  count++;
2775 
2776  previouspad = pad;
2777  }
2778 
2779  // Examine last pad
2780  if( pad && count == 1 )
2782  }
2783 
2784  // Last step: Some tests:
2785  // verify all pads found in netlist:
2786  // They should exist in footprints, otherwise the footprint is wrong
2787  // note also references or time stamps are updated, so we use only
2788  // the reference to find a footprint
2789  //
2790  // Also verify if zones have acceptable nets, i.e. nets with pads.
2791  // Zone with no pad belongs to a "dead" net which happens after changes in schematic
2792  // when no more pad use this net name.
2793  if( aReporter )
2794  {
2795  wxString padname;
2796  for( i = 0; i < aNetlist.GetCount(); i++ )
2797  {
2798  const COMPONENT* component = aNetlist.GetComponent( i );
2799  MODULE* footprint = FindModuleByReference( component->GetReference() );
2800 
2801  if( footprint == NULL ) // It can be missing in partial designs
2802  continue;
2803 
2804  // Explore all pins/pads in component
2805  for( unsigned jj = 0; jj < component->GetNetCount(); jj++ )
2806  {
2807  COMPONENT_NET net = component->GetNet( jj );
2808  padname = net.GetPinName();
2809 
2810  if( footprint->FindPadByName( padname ) )
2811  continue; // OK, pad found
2812 
2813  // not found: bad footprint, report error
2814  msg.Printf( _( "Component '%s' pad '%s' not found in footprint '%s'\n" ),
2815  GetChars( component->GetReference() ),
2816  GetChars( padname ),
2817  GetChars( FROM_UTF8( footprint->GetFPID().Format() ) ) );
2818  aReporter->Report( msg, REPORTER::RPT_ERROR );
2819  }
2820  }
2821 
2822  // Test copper zones to detect "dead" nets (nets without any pad):
2823  for( int ii = 0; ii < GetAreaCount(); ii++ )
2824  {
2825  ZONE_CONTAINER* zone = GetArea( ii );
2826 
2827  if( !zone->IsOnCopperLayer() || zone->GetIsKeepout() )
2828  continue;
2829 
2830  if( zone->GetNet()->GetNodesCount() == 0 )
2831  {
2832  msg.Printf( _( "Copper zone (net name '%s'): net has no pads connected." ),
2833  GetChars( zone->GetNet()->GetNetname() ) );
2834  aReporter->Report( msg, REPORTER::RPT_WARNING );
2835  }
2836  }
2837  }
2838 
2839  std::swap( newFootprints, *aNewFootprints );
2840 }
2841 
2842 
2844  bool aAddToBoard )
2845 {
2846  BOARD_ITEM* new_item = NULL;
2847 
2848  switch( aItem->Type() )
2849  {
2850  case PCB_MODULE_T:
2851  case PCB_TEXT_T:
2852  case PCB_LINE_T:
2853  case PCB_TRACE_T:
2854  case PCB_VIA_T:
2855  case PCB_ZONE_AREA_T:
2856  case PCB_TARGET_T:
2857  case PCB_DIMENSION_T:
2858  new_item = static_cast<BOARD_ITEM*>( aItem->Clone() );
2859  break;
2860 
2861  default:
2862  // Un-handled item for duplication
2863  new_item = NULL;
2864  break;
2865  }
2866 
2867  if( new_item && aAddToBoard )
2868  Add( new_item );
2869 
2870  return new_item;
2871 }
2872 
2873 
2874 /* Extracts the board outlines and build a closed polygon
2875  * from lines, arcs and circle items on edge cut layer
2876  * Any closed outline inside the main outline is a hole
2877  * All contours should be closed, i.e. are valid vertices for a closed polygon
2878  * return true if success, false if a contour is not valid
2879  */
2880 extern bool BuildBoardPolygonOutlines( BOARD* aBoard,
2881  SHAPE_POLY_SET& aOutlines,
2882  wxString* aErrorText );
2883 
2885  wxString* aErrorText )
2886 {
2887  bool success = BuildBoardPolygonOutlines( this, aOutlines, aErrorText );
2888 
2889  // Make polygon strictly simple to avoid issues (especially in 3D viewer)
2891 
2892  return success;
2893 
2894 }
std::vector< RATSNEST_ITEM > m_LocalRatsnest
Ratsnest list relative to a given footprint (used while moving a footprint).
Definition: class_board.h:251
void SetColorsSettings(COLORS_DESIGN_SETTINGS *aColorsSettings)
Function SetColorsSettings.
Definition: class_board.h:567
Definition: colors.h:57
DHEAD * GetList() const
Definition: base_struct.h:209
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:639
CITER next(CITER it)
Definition: ptree.cpp:130
COLOR4D GetLayerColor(PCB_LAYER_ID aLayer) const
Function GetLayerColor gets a layer color for any valid layer, including non-copper ones...
KICAD_T Type() const
Function Type()
Definition: base_struct.h:198
#define DIM(x)
of elements in an array
Definition: macros.h:98
Wrapper class, so you can iterate through NETINFO_ITEM*s, not std::pair
const wxString & GetPinName() const
Definition: pcb_netlist.h:61
void SetCopperLayerCount(int aNewLayerCount)
Function SetCopperLayerCount do what its name says...
void BuildListOfNets()
Definition: class_board.h:764
void Draw(EDA_DRAW_PANEL *panel, wxDC *DC, GR_DRAWMODE aDrawMode, const wxPoint &offset=ZeroOffset) override
Function Draw Draws the zone outline.
Definition: class_zone.cpp:179
void SetLayerColor(PCB_LAYER_ID aLayer, COLOR4D aColor)
Function SetLayerColor changes a layer color for any valid layer, including non-copper ones...
void SetEnabledLayers(LSET aMask)
Function SetEnabledLayers changes the bit-mask of enabled layers.
Class ZONE_CONTAINER handles a list of polygons defining a copper zone.
Definition: class_zone.h:78
to draw blind/buried vias
static SEARCH_RESULT IterateForward(EDA_ITEM *listStart, INSPECTOR inspector, void *testData, const KICAD_T scanTypes[])
Function IterateForward walks through the object tree calling the inspector() on each object type req...
TRACK * CreateLockPoint(wxPoint &aPosition, TRACK *aSegment, PICKED_ITEMS_LIST *aList)
Function CreateLockPoint creates an intermediate point on aSegment and break it into two segments at ...
TRACK * GetTrack(TRACK *aStartTrace, const TRACK *aEndTrace, const wxPoint &aPosition, LSET aLayerMask)
Function GetTrack is a helper function to locate a trace segment having an end point at aPosition on ...
Definition: class_track.cpp:68
bool IsElementVisible(GAL_LAYER_ID LAYER_aPCB) const
Function IsElementVisible tests whether a given element category is visible.
TEXTE_MODULE & Reference()
Definition: class_module.h:455
bool empty() const
Function empty.
Definition: lib_id.h:199
Class that draws missing connections on a PCB.
int GetCurrentViaDrill() const
Function GetCurrentViaDrill.
void DeleteZONEOutlines()
Function DeleteZONEOutlines deletes ALL zone outlines from the board.
int GetVisibleElements() const
Function GetVisibleElements returns a bit-mask of all the element categories that are visible...
Definition: typeinfo.h:97
const LIB_ID & GetFPID() const
Definition: pcb_netlist.h:164
PCB_TARGET class definition.
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:79
NETCLASSPTR GetDefault() const
Function GetDefault.
int GetNodesCount() const
Function GetNodesCount.
void Merge(const EDA_RECT &aRect)
Function Merge modifies the position and size of the rectangle in order to contain aRect...
T * Remove(T *aElement)
Function Remove removes aElement from the list, but does not delete it.
Definition: dlist.h:211
void SetItemColor(int aItemIdx, COLOR4D aColor)
Function SetItemColor sets the color for an item which is one of the item indices given in enum PCB_L...
static wxString FROM_UTF8(const char *cstring)
function FROM_UTF8 converts a UTF8 encoded C string to a wxString for all wxWidgets build modes...
Definition: macros.h:53
TEXTE_PCB class definition.
static const KICAD_T Tracks[]
A scan list for only TRACKS.
Definition: collectors.h:294
#define END_ONPAD
Pcbnew: flag set for track segment ending on a pad.
Definition: base_struct.h:133
unsigned GetUnconnectedNetCount() const
Function GetUnconnectedNetCount.
Definition: class_board.h:727
virtual LSET GetLayerSet() const override
Function GetLayerSet returns a "layer mask", which is a bitmap of all layers on which the TRACK segme...
static int KiROUND(double v)
KiROUND rounds a floating point number to an int using "round halfway cases away from zero"...
Definition: common.h:107
wxString m_name
The name of the layer, there should be no spaces in this name.
Definition: class_board.h:108
const D_PADS & GetPads()
Function GetPads returns a reference to a list of all the pads.
Definition: class_board.h:762
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...
void PushFront(T *aNewElement)
Function PushFront puts aNewElement at front of list sequence.
Definition: dlist.h:240
void SetVisibleElements(int aMask)
Function SetVisibleElements is a proxy function that calls the correspondent function in m_BoardSetti...
Class RN_DATA.
virtual void SetLayer(PCB_LAYER_ID aLayer)
Function SetLayer sets the layer this item is on.
Implementation of conversion functions that require both schematic and board internal units...
Class BOARD_ITEM is a base class for any item which can be embedded within the BOARD container class...
static void removeTrack(TRACKS *aList, TRACK *aOneToRemove)
Function removeTrack removes aOneToRemove from aList, which is a non-owning std::vector.
void SetEnd(const wxPoint &aEnd)
Definition: class_track.h:117
bool GetBoardPolygonOutlines(SHAPE_POLY_SET &aOutlines, wxString *aErrorText=NULL)
Function GetBoardPolygonOutlines Extracts the board outlines and build a closed polygon from lines...
const EDA_RECT GetBoundingBox() const override
Function GetBoundingBox (virtual)
Definition: class_zone.cpp:349
D_PAD * GetPadFast(const wxPoint &aPosition, LSET aLayerMask)
Function GetPadFast return pad found at aPosition on aLayerMask using the fast search method...
virtual EDA_ITEM * Clone() const
Function Clone creates a duplicate of this item with linked list members set to NULL.
static void otherEnd(const TRACK &aTrack, const wxPoint &aNotThisEnd, wxPoint *aOtherEnd)
PAGE_INFO m_paper
Definition: class_board.h:194
void SetStatus(UNDO_REDO_T aStatus)
EDA_RECT ComputeBoundingBox(bool aBoardEdgesOnly=false) const
Function ComputeBoundingBox calculates the bounding box containing all board items (or board edge seg...
anchor of items having an anchor point (texts, footprints)
TRACKS TracksInNetBetweenPoints(const wxPoint &aStartPos, const wxPoint &aGoalPos, int aNetCode)
Function TrackInNetBetweenPoints collects all the TRACKs and VIAs that are members of a net given by ...
MODULE * GetModule(bool aRelease=false)
Definition: pcb_netlist.h:177
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.
int GetPadToDieLength() const
Definition: class_pad.h:241
Class BOARD to handle a board.
void DrawFilledArea(EDA_DRAW_PANEL *panel, wxDC *DC, GR_DRAWMODE aDrawMode, const wxPoint &offset=ZeroOffset)
Function DrawDrawFilledArea Draws the filled area for this zone (polygon list .m_FilledPolysList) ...
Definition: class_zone.cpp:240
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:428
Class that computes missing connections on a PCB.
LAYER_T m_type
The type of the layer.
Definition: class_board.h:110
D_PAD * FindPadByName(const wxString &aPadName) const
Function FindPadByName returns a D_PAD* with a matching name.
MODULE * Next() const
Definition: class_module.h:99
void GetSortedPadListByXthenYCoord(std::vector< D_PAD * > &aVector, int aNetCode=-1)
Function GetSortedPadListByXthenYCoord first empties then fills the vector with all pads and sorts th...
NETINFO_ITEM * GetNetItem(int aNetCode) const
Function GetItem.
MODULE * GetParent() const
Definition: class_pad.h:108
int NormalizeAreaOutlines()
Function NormalizeAreaOutlines Convert a self-intersecting polygon to one (or more) non self-intersec...
int GetCopperLayerCount() const
Function GetCopperLayerCount.
class ZONE_CONTAINER, a zone area
Definition: typeinfo.h:114
static const int dist[10][10]
Definition: dist.cpp:57
ZONE_CONTAINER * m_CurrentZoneContour
zone contour currently in progress
Definition: class_board.h:254
show modules on back
time_t GetNewTimeStamp()
Definition: common.cpp:166
unsigned GetNetCount() const
Function GetNetCount.
int GetHeight() const
SHAPE_POLY_SET * Outline()
Definition: class_zone.h:247
void DeleteStructure()
Function DeleteStructure deletes this object after UnLink()ing it from its owner if it has one...
GAL_LAYER_ID
GAL layers are "virtual" layers, i.e.
void SetCopperLayerCount(int aCount)
virtual EDA_ITEM * Clone() const override
Function Clone creates a duplicate of this item with linked list members set to NULL.
class TEXTE_PCB, text on a layer
Definition: typeinfo.h:104
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) ...
MODULE * FindModuleByReference(const wxString &aReference) const
Function FindModuleByReference searches for a MODULE within this board with the given reference desig...
Classes to handle copper zones.
const wxString & GetValue() const
Function GetValue.
Definition: class_module.h:439
DLIST< SEGZONE > m_Zone
Definition: class_board.h:245
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:102
void SetLayerColor(LAYER_NUM aLayer, COLOR4D aColor)
Function SetLayerColor sets the color for aLayer which is one of the layer indices given in pcbstruct...
#define BUSY
Pcbnew: flag indicating that the structure has.
Definition: base_struct.h:134
virtual void SetPosition(const wxPoint &aPos) override
int m_unconnectedNetCount
Number of unconnected nets in the current rats nest.
Definition: class_board.h:202
bool IsValid() const
Definition: pcb_netlist.h:65
COLOR4D GetVisibleElementColor(GAL_LAYER_ID LAYER_aPCB)
Function GetVisibleElementColor returns the color of a pcb visible element.
This is the end of the layers used for visibility bitmasks in Pcbnew There can be at most 32 layers a...
MODULE * FindModule(const wxString &aRefOrTimeStamp, bool aSearchByTimeStamp=false) const
Function FindModule searches for a module matching aRefOrTimeStamp depending on the state of aSearchB...
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:183
NETINFO_LIST m_NetInfo
net info list (name, design constraints ..
Definition: class_board.h:188
bool IsLayerVisible(PCB_LAYER_ID aLayerId) const
Function IsLayerVisible tests whether a given layer is visible.
Class REPORTER is a pure virtual class used to derive REPORTER objects from.
Definition: reporter.h:61
HIGH_LIGHT_INFO m_highLightPrevious
Definition: class_board.h:184
int GetVisibleElements() const
Function GetVisibleElements is a proxy function that calls the correspondent function in m_BoardSetti...
virtual void UnLink()
Function UnLink detaches this object from its owner.
int GetState(int type) const
Definition: base_struct.h:237
#define cu(a)
Definition: auxiliary.h:88
#define BEGIN_ONPAD
Pcbnew: flag set for track segment starting on a pad.
Definition: base_struct.h:132
D_PADS m_PadInNetList
List of pads connected to this net.
int GetCurrentViaSize() const
Function GetCurrentViaSize.
Class BOARD_CONNECTED_ITEM is a base class derived from BOARD_ITEM for items that can be connected an...
LSET GetEnabledLayers() const
Function GetEnabledLayers is a proxy function that calls the corresponding function in m_BoardSetting...
void SetLink(EDA_ITEM *aItem)
smd pads, back layer
wxString GetLayerName() const
Function GetLayerName returns the name of the PCB layer on which the item resides.
class EDGE_MODULE, a footprint edge
Definition: typeinfo.h:106
void SetOutline(SHAPE_POLY_SET *aOutline)
Definition: class_zone.h:250
BOARD_CONNECTED_ITEM * GetLockPoint(const wxPoint &aPosition, LSET aLayerMask)
Function GetLockPoint returns the item at the "attachment" point at the end of a trace at aPosition o...
static const int delta[8][2]
Definition: solve.cpp:112
const wxPoint & GetEnd() const
Definition: class_track.h:118
void SetCustomViaSize(int aSize)
Function SetCustomViaSize Sets custom size for via diameter (i.e.
static int find_vias_and_tracks_at(TRACKS &at_next, TRACKS &in_net, LSET &lset, const wxPoint &next)
Function find_vias_and_tracks_at collects TRACKs and VIAs at aPos and returns the track_count which e...
search types array terminator (End Of Types)
Definition: typeinfo.h:94
KICAD_T
Enum KICAD_T is the set of class identification values, stored in EDA_ITEM::m_StructType.
Definition: typeinfo.h:90
static wxPoint ZeroOffset
A value of wxPoint(0,0) which can be passed to the Draw() functions.
static std::string FormatInternalUnits(int aValue)
Function FormatInternalUnits converts aValue from board internal units to a string appropriate for wr...
void SetTimeStamp(time_t aNewTimeStamp)
Definition: base_struct.h:203
Functions relatives to tracks, vias and segments used to fill zones.
class TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:107
ENDPOINT_T
Flag used in locate routines (from which endpoint work)
Definition: pcbnew.h:54
static const char * ShowType(LAYER_T aType)
Function ShowType converts a LAYER_T enum to a const char*.
ZONE_CONTAINER * HitTestForAnyFilledArea(const wxPoint &aRefPos, PCB_LAYER_ID aStartLayer, PCB_LAYER_ID aEndLayer, int aNetCode)
Function HitTestForAnyFilledArea tests if the given wxPoint is within the bounds of a filled area of ...
void SetVisibleLayers(LSET aMask)
Function SetVisibleLayers changes the bit-mask of visible layers.
void PushBack(T *aNewElement)
Function PushBack puts aNewElement at the end of the list sequence.
Definition: dlist.h:250
SEGZONE * Next() const
Definition: class_track.h:363
const EDA_RECT GetBoardEdgesBoundingBox() const
Function GetBoardEdgesBoundingBox Returns the board bounding box calculated using exclusively the boa...
Definition: class_board.h:839
void AppendNet(NETINFO_ITEM *aNewElement)
Function AppendNet adds aNewElement to the end of the net list.
bool Remove(const BOARD_ITEM *aItem)
Function Remove() Removes an item from the ratsnest data.
bool GetIsKeepout() const
Accessors to parameters used in Keepout zones:
Definition: class_zone.h:654
show modules on front
int StrPrintf(std::string *result, const char *format,...)
Function StrPrintf is like sprintf() but the output is appended to a std::string instead of to a char...
Definition: richio.cpp:75
const wxString & GetReference() const
Definition: pcb_netlist.h:149
BOARD_ITEM * Next() const
COLOR4D GetItemColor(int aItemIdx) const
Function GetItemColor.
Class that handles properties and drawing of worksheet layout.
Class COMPONENT_NET is used to store the component pin name to net name associations stored in a netl...
Definition: pcb_netlist.h:48
const INSPECTOR_FUNC & INSPECTOR
Definition: base_struct.h:104
const LIB_ID & GetFPID() const
Definition: class_module.h:151
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...
const wxString & GetValue() const
Definition: pcb_netlist.h:151
std::vector< RATSNEST_ITEM > m_FullRatsnest
Ratsnest list for the BOARD.
Definition: class_board.h:248
DIMENSION class definition.
VIA * GetVia(const wxPoint &aPosition, PCB_LAYER_ID aLayer=UNDEFINED_LAYER)
Function GetVia finds the first VIA object at aPosition on aLayer starting at the trace...
ZONE_CONTAINER * InsertArea(int netcode, int iarea, PCB_LAYER_ID layer, int x, int y, int hatch)
Function InsertArea add empty copper area to net, inserting after m_ZoneDescriptorList[iarea].
class MODULE, a footprint
Definition: typeinfo.h:101
Markers used to show a drc problem on boards.
PCB_LAYER_ID
A quick note on layer IDs:
bool GetDeleteExtraFootprints() const
Definition: pcb_netlist.h:296
void RemoveNet(NETINFO_ITEM *aNet)
Function RemoveNet Removes a new from the net list.
Class LSET is a set of PCB_LAYER_IDs.
void PopHighLight()
Function PopHighLight retrieve a previously saved high light info.
int GetCopperLayerCount() const
Function GetCopperLayerCount.
unsigned GetRatsnestsCount() const
Function GetNumRatsnests.
Definition: class_board.h:704
void ReplaceNetlist(NETLIST &aNetlist, bool aDeleteSinglePadNets, std::vector< MODULE * > *aNewFootprints, REPORTER *aReporter=NULL)
Function ReplaceNetlist updates the BOARD according to aNetlist.
Classes used in Pcbnew, CvPcb and GerbView.
bool GetReplaceFootprints() const
Definition: pcb_netlist.h:311
Class NETLIST stores all of information read from a netlist along with the flags used to update the N...
Definition: pcb_netlist.h:205
virtual const wxString Problem() const
what was the problem?
Definition: exceptions.cpp:49
bool NormalizeAreaPolygon(PICKED_ITEMS_LIST *aNewZonesList, ZONE_CONTAINER *aCurrArea)
Function NormalizeAreaPolygon Process an area that has been modified, by normalizing its polygon agai...
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, int aHatch)
Function AddArea Add an empty copper area to board areas list.
void SetParent(EDA_ITEM *aParent)
Definition: base_struct.h:213
#define GAL_LAYER_INDEX(x)
Use this macro to convert a GAL layer to a 0-indexed offset from LAYER_VIAS.
GR_DRAWMODE
Drawmode. Compositing mode plus a flag or two.
Definition: gr_basic.h:41
virtual void Move(const wxPoint &aMoveVector)
Function Move move this object.
Class SHAPE_POLY_SET.
TEXTE_MODULE & Value()
read/write accessors:
Definition: class_module.h:454
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
EDA_RECT GetFootprintRect() const
Function GetFootprintRect() Returns the area of the module footprint excluding any text...
#define IS_DELETED
Definition: base_struct.h:116
const UTF8 & GetLibItemName() const
Function GetLibItemName.
Definition: lib_id.h:129
Class PAGE_INFO describes the page size and margins of a paper page on which to eventually print or p...
bool IsEmpty() const
Definition: class_board.h:263
const wxPoint & GetStart() const
Definition: class_track.h:121
const wxPoint & GetPosition() const override
Definition: class_pad.h:170
STATUS_FLAGS m_Status
Definition: base_struct.h:161
void AppendCorner(wxPoint position, bool aAllowDuplication=false)
Function AppendCorner.
Definition: class_zone.h:546
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:68
to draw usual through hole vias
D_PAD * GetPad(unsigned aIdx) const
Function GetPad.
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:235
bool SetLayerName(PCB_LAYER_ID aLayer, const wxString &aLayerName)
Function SetLayerName changes the name of the layer given by aLayer.
const wxPoint & GetEndPoint(ENDPOINT_T aEndPoint) const
Return the selected endpoint (start or end)
Definition: class_track.h:125
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_INSERT) override
>
COLORS_DESIGN_SETTINGS * GetColorsSettings() const
Function GetColorSettings.
Definition: class_board.h:561
void SetElementVisibility(GAL_LAYER_ID LAYER_aPCB, bool aNewState)
Function SetElementVisibility changes the visibility of an element category.
const wxString & GetNetName() const
Definition: pcb_netlist.h:63
bool SetLayerDescr(PCB_LAYER_ID aIndex, const LAYER &aLayer)
Function SetLayerDescr returns the type of the copper layer given by aLayer.
bool IsFindByTimeStamp() const
Definition: pcb_netlist.h:304
virtual LSET GetLayerSet() const
Function GetLayerSet returns a "layer mask", which is a bitmap of all layers on which the TRACK segme...
D_PAD * Next() const
Definition: class_pad.h:106
int SortedNetnamesList(wxArrayString &aNames, bool aSortbyPadsCount)
Function SortedNetnamesList.
DLIST< BOARD_ITEM > m_Drawings
Definition: class_board.h:242
#define CH_VISIBLE
Definition: class_netinfo.h:57
bool SetNetCode(int aNetCode, bool aNoAssert=false)
Function SetNetCode sets net using a net code.
Definition: colors.h:60
TRACK * GetVisibleTrack(TRACK *aStartingTrace, const wxPoint &aPosition, LSET aLayerSet) const
Function GetVisibleTrack finds the neighboring visible segment of aTrace at aPosition that is on a la...
void Simplify(POLYGON_MODE aFastMode)
Simplifies the polyset (merges overlapping polys, eliminates degeneracy/self-intersections) For aFast...
void SetReference(const wxString &aReference)
Function SetReference.
Definition: class_module.h:421
bool DeletePad(D_PAD *aPad)
class SEGZONE, a segment used to fill a zone area (segment on a copper layer)
Definition: typeinfo.h:109
int SetAreasNetCodesFromNetNames(void)
Function SetAreasNetCodesFromNetNames Set the .m_NetCode member of all copper areas, according to the area Net Name The SetNetCodesFromNetNames is an equivalent to net name, for fast comparisons.
int GetAreaCount() const
Function GetAreaCount.
Definition: class_board.h:1051
#define THROW_IO_ERROR(x)
Definition: utf8.cpp:60
bool IsModuleLayerVisible(PCB_LAYER_ID layer)
Function IsModuleLayerVisible expects either of the two layers on which a module can reside...
const wxString & GetTimeStamp() const
Definition: pcb_netlist.h:168
MARKERS m_markers
MARKER_PCBs for clearance problems, owned by pointer.
Definition: class_board.h:175
int GetBottom() const
HATCH_STYLE
Zone hatch styles.
Definition: class_zone.h:85
wxPoint Centre() const
TRACK * MarkTrace(TRACK *aTrace, int *aCount, double *aTraceLength, double *aInPackageLength, bool aReorder)
Function MarkTrace marks a chain of trace segments, connected to aTrace.
void SetPosition(const wxPoint &aPos) override
Class PICKED_ITEMS_LIST is a holder to handle information on schematic or board items.
int GetNet() const
Function GetNet.
static LAYER_T ParseType(const char *aType)
Function ParseType converts a string to a LAYER_T.
void SetItem(EDA_ITEM *aItem)
D_PAD * GetPad(unsigned aIndex) const
Function GetPad.
Definition: class_board.h:750
COLORS_DESIGN_SETTINGS g_ColorsSettings
Definition: pcbnew.cpp:68
class DIMENSION, a dimension (graphic item)
Definition: typeinfo.h:112
bool IsLocked() const override
Function IsLocked.
Definition: class_module.h:223
unsigned GetPadCount() const
Function GetPadCount.
Definition: class_board.h:741
bool IsElementVisible(GAL_LAYER_ID aElementCategory) const
Function IsElementVisible tests whether a given element category is visible.
int GetNumSegmTrack() const
Functions to get some items count.
void SetCustomTrackWidth(int aWidth)
Function SetCustomTrackWidth Sets custom width for track (i.e.
Class LSEQ is a sequence (and therefore also a set) of PCB_LAYER_IDs.
const PCB_LAYER_ID GetLayerID(const wxString &aLayerName) const
Function GetLayerID returns the ID of a layer given by aLayerName.
class PCB_TARGET, a target (graphic item)
Definition: typeinfo.h:113
int LAYER_NUM
Type LAYER_NUM can be replaced with int and removed.
Class COMPONENT is used to store components and all of their related information found in a netlist...
Definition: pcb_netlist.h:83
static bool sortNetsByNames(const NETINFO_ITEM *a, const NETINFO_ITEM *b)
TRACKS TracksInNet(int aNetCode)
Function TrackInNet collects all the TRACKs and VIAs that are members of a net given by aNetCode...
int GetNetCode() const
Function GetNetCode.
class TEXTE_MODULE, text in a footprint
Definition: typeinfo.h:105
COMPONENT * GetComponent(unsigned aIndex)
Function GetComponent returns the COMPONENT at aIndex.
Definition: pcb_netlist.h:256
Definition: seg.h:37
void Move(const wxPoint &aMoveVector) override
Function Move move this object.
VIA * GetViaByPosition(const wxPoint &aPosition, PCB_LAYER_ID aLayer=PCB_LAYER_ID(-1)) const
Function GetViaByPosition finds the first via at aPosition on aLayer.
Class NETINFO_ITEM handles the data for a net.
PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
bool IsOnCopperLayer() const
Function IsOnCopperLayer.
Definition: class_zone.h:179
iterator begin() const
TRACK * GetBestInsertPoint(BOARD *aPcb)
Function GetBestInsertPoint searches the "best" insertion point within the track linked list...
class MARKER_PCB, a marker used to show something
Definition: typeinfo.h:111
bool SetCurrentNetClass(const wxString &aNetClassName)
Function SetCurrentNetClass Must be called after a netclass selection (or after a netclass parameter ...
TRACK * Next() const
Definition: class_track.h:98
static const wxChar * GetChars(const wxString &s)
Function GetChars returns a wxChar* to the actual wxChar* data within a wxString, and is helpful for ...
Definition: macros.h:92
smd pads, front layer
const wxString & GetNetname() const
Function GetNetname.
void SetState(int type, int state)
Definition: base_struct.h:242
ZONE_CONTAINER * GetArea(int index) const
Function GetArea returns the Area (Zone Container) at a given index.
Definition: class_board.h:1022
void SetVisibleElementColor(GAL_LAYER_ID LAYER_aPCB, COLOR4D aColor)
void UnHatch()
Function UnHatch clears the zone's hatch.
Definition: class_zone.cpp:905
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
handle color for not plated holes
int m_fileFormatVersionAtLoad
the version loaded from the file
Definition: class_board.h:186
iterator end() const
static NETINFO_ITEM ORPHANED_ITEM
NETINFO_ITEM meaning that there was no net assigned for an item, as there was no board storing net li...
Class LAYER holds information pertinent to a layer of a BOARD.
Definition: class_board.h:82
Class BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:166
const wxString & GetReference() const
Function GetReference.
Definition: class_module.h:411
unsigned GetNodesCount() const
Function GetNodesCount.
DLIST< MODULE > m_Modules
Definition: class_board.h:243
void RedrawFilledAreas(EDA_DRAW_PANEL *aPanel, wxDC *aDC, GR_DRAWMODE aDrawMode, PCB_LAYER_ID aLayer)
Function RedrawFilledAreas Redraw all filled areas on layer aLayer ( redraw all if aLayer < 0 ) ...
LSET GetVisibleLayers() const
Function GetVisibleLayers is a proxy function that calls the correspondent function in m_BoardSetting...
ZONE_CONTAINERS m_ZoneDescriptorList
edge zone descriptors, owned by pointer.
Definition: class_board.h:178
class NETINFO_ITEM, a description of a net
Definition: typeinfo.h:116
LAYER m_Layer[PCB_LAYER_ID_COUNT]
Definition: class_board.h:180
bool HitTestFilledArea(const wxPoint &aRefPos) const
Function HitTestFilledArea tests if the given wxPoint is within the bounds of a filled area of this z...
Definition: class_zone.cpp:623
int GetNumSegmZone() const
Calculate the zone segment count.
Class EDA_RECT handles the component boundary box.
void SetValue(const wxString &aValue)
Function SetValue.
Definition: class_module.h:448
int GetX() const
HATCH_STYLE GetHatchStyle() const
Definition: class_zone.h:554
void Hatch()
Function Hatch computes the hatch lines depending on the hatch parameters and stores it in the zone's...
Definition: class_zone.cpp:919
void chainMarkedSegments(wxPoint aPosition, const LSET &aLayerSet, TRACKS *aList)
Function chainMarkedSegments is used by MarkTrace() to set the BUSY flag of connected segments of the...
void PushHighLight()
Function PushHighLight save current high light info for later use.
NETINFO_ITEM * FindNet(int aNetcode) const
Function FindNet searches for a net with the given netcode.
void SetHatchStyle(HATCH_STYLE aStyle)
Definition: class_zone.h:559
Class EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boa...
Definition: base_struct.h:151
static bool sortNetsByNodes(const NETINFO_ITEM *a, const NETINFO_ITEM *b)
void SetLocalFlags(int aFlags)
Definition: class_zone.h:242
The common library.
int GetWidth() const
wxString GetClass() const override
Function GetClass returns the class name.
Definition: class_board.h:958
COLOR4D GetLayerColor(LAYER_NUM aLayer) const
Function GetLayerColor.
void SetElementVisibility(GAL_LAYER_ID aElementCategory, bool aNewState)
Function SetElementVisibility changes the visibility of an element category.
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_UNDEFINED)=0
Function Report is a pure virtual function to override in the derived object.
bool Add(const BOARD_ITEM *aItem)
Function Add() Adds an item to the ratsnest data.
UTF8 Format() const
Function Format.
Definition: lib_id.cpp:263
int GetY() const
#define FIRST_COPPER_LAYER
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 containter and deletes it.
virtual const wxPoint & GetPosition() const override
unsigned GetCount() const
Function GetCount returns the number of elements in the list.
Definition: dlist.h:126
void SetEffects(const TEXTE_MODULE &aSrc)
Function SetEffects sets the text effects from another instance.
void SetStart(const wxPoint &aStart)
Definition: class_track.h:120
RN_DATA * m_ratsnest
Definition: class_board.h:189
COMPONENT * GetComponentByReference(const wxString &aReference)
Function GetComponentByReference returns a COMPONENT by aReference.
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:108
const COMPONENT_NET & GetNet(unsigned aIndex) const
Definition: pcb_netlist.h:137
wxString GetPadName() const
Definition: class_pad.cpp:382
#define DBG(x)
Definition: fctsys.h:33
void CopyNetlistSettings(MODULE *aModule, bool aCopyLocalSettings)
Function CopyNetlistSettings copies the netlist settings to aModule.
bool BuildBoardPolygonOutlines(BOARD *aBoard, SHAPE_POLY_SET &aOutlines, wxString *aErrorText)
void RedrawAreasOutlines(EDA_DRAW_PANEL *aPanel, wxDC *aDC, GR_DRAWMODE aDrawMode, PCB_LAYER_ID aLayer)
Function RedrawAreasOutlines Redraw all areas outlines on layer aLayer ( redraw all if aLayer < 0 ) ...
DLIST< D_PAD > & Pads()
Definition: class_module.h:133
DLIST< TRACK > m_Track
Definition: class_board.h:244
bool IsDryRun() const
Definition: pcb_netlist.h:300
BOARD_DESIGN_SETTINGS m_designSettings
Definition: class_board.h:191
Module description (excepted pads)
const wxString & GetNetname() const
Function GetNetname.
Abstract interface for BOARD_ITEMs capable of storing other items inside.
LSET GetEnabledLayers() const
Function GetEnabledLayers returns a bit-mask of all the layers that are enabled.
static void checkConnectedTo(BOARD *aBoard, TRACKS *aList, const TRACKS &aTracksInNet, const wxPoint &aGoal, const wxPoint &aStart, TRACK *aFirstTrack)
Function checkConnectedTo returns if aTracksInNet contains a copper pathway to aGoal when starting wi...
Class EDA_MSG_ITEM is used EDA_MSG_PANEL as the item type for displaying messages.
Definition: msgpanel.h:53
const wxString & GetPath() const
Definition: class_module.h:160
SEARCH_RESULT
Definition: base_struct.h:68
int GetCurrentTrackWidth() const
Function GetCurrentTrackWidth.
class DRAWSEGMENT, a segment not on copper layers
Definition: typeinfo.h:103
Message panel definition file.
bool IsSelfIntersecting()
Function IsSelfIntersecting Checks whether any of the polygons in the set is self intersecting...
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.
unsigned GetCount() const
Function GetCount.
Definition: pcb_netlist.h:247
int m_nodeCount
Number of pads connected to the current net.
Definition: class_board.h:199
LSET GetVisibleLayers() const
Function GetVisibleLayers returns a bit-mask of all the layers that are visible.
BOARD_CONNECTED_ITEM * end
Definition: class_track.h:90
static const int UNCONNECTED
Constant that holds the "unconnected net" number (typically 0) all items "connected" to this net are ...
unsigned GetNetCount() const
Definition: pcb_netlist.h:135
Struct IO_ERROR is a class used to hold an error message and may be used when throwing exceptions con...
Definition: ki_exception.h:47
BOARD_CONNECTED_ITEM * start
Definition: class_track.h:89
LAYER_T GetLayerType(PCB_LAYER_ID aLayer) const
Function GetLayerType returns the type of the copper layer given by aLayer.
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:767
void SetEnabledLayers(LSET aLayerMask)
Function SetEnabledLayers is a proxy function that calls the correspondent function in m_BoardSetting...
void GetMsgPanelInfo(std::vector< MSG_PANEL_ITEM > &aList) override
Function GetMsgPanelInfo populates aList of MSG_PANEL_ITEM objects with it's internal state for displ...
void SetPath(const wxString &aPath)
Definition: class_module.h:161
void Remove(BOARD_ITEM *aBoardItem) override
>
NETINFO_ITEM * GetNet() const
Function GetNet Returns NET_INFO object for a given item.
void UseCustomTrackViaSize(bool aEnabled)
Function UseCustomTrackViaSize Enables/disables custom track/via size settings.
void Insert(T *aNewElement, T *aElementAfterMe)
Function Insert puts aNewElement just in front of aElementAfterMe in the list sequence.
Definition: dlist.h:200
COMPONENT * GetComponentByTimeStamp(const wxString &aTimeStamp)
Function GetComponentByTimeStamp returns a COMPONENT by aTimeStamp.
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:646
D_PADS m_PadsFullList
contains all pads, sorted by pad's netname.
int m_Status_Pcb
Flags used in ratsnest calculation and update.
Definition: class_board.h:240
Class COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:39
BOARD_ITEM * Duplicate(const BOARD_ITEM *aItem, bool aAddToBoard=false)
bool HitTest(const wxPoint &aPosition) const override
Function HitTest tests if aPosition is contained within or on the bounding area of an item...
VIA * GetFirstVia(TRACK *aTrk, const TRACK *aStopPoint=NULL)
Scan a track list for the first VIA o NULL if not found (or NULL passed)
Definition: class_track.h:497