KiCad PCB EDA Suite
class_track.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
5  * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
6  * Copyright (C) 2012 Wayne Stambaugh <stambaughw@verizon.net>
7  * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, you may find one here:
21  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
22  * or you may search the http://www.gnu.org website for the version 2 license,
23  * or you may write to the Free Software Foundation, Inc.,
24  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
25  */
26 
33 #include <fctsys.h>
34 #include <gr_basic.h>
35 #include <common.h>
36 #include <trigo.h>
37 #include <macros.h>
38 #include <class_drawpanel.h>
39 #include <pcb_screen.h>
40 #include <draw_graphic_text.h>
41 #include <pcb_base_frame.h>
42 #include <class_board.h>
43 #include <class_track.h>
44 #include <pcbnew.h>
45 #include <base_units.h>
46 #include <msgpanel.h>
47 #include <bitmaps.h>
48 #include <view/view.h>
49 
55 static bool ShowClearance( PCB_DISPLAY_OPTIONS* aDisplOpts, const TRACK* aTrack )
56 {
57  // maybe return true for tracks and vias, not for zone segments
58  return IsCopperLayer( aTrack->GetLayer() )
59  && ( aTrack->Type() == PCB_TRACE_T || aTrack->Type() == PCB_VIA_T )
61  && ( aTrack->IsDragging() || aTrack->IsMoving() || aTrack->IsNew() ) )
63  );
64 
65 }
66 
67 
68 TRACK* GetTrack( TRACK* aStartTrace, const TRACK* aEndTrace,
69  const wxPoint& aPosition, LSET aLayerMask )
70 {
71  for( TRACK* seg = aStartTrace; seg; seg = seg->Next() )
72  {
73  if( seg->GetState( IS_DELETED | BUSY ) == 0 )
74  {
75  if( aPosition == seg->GetStart() )
76  {
77  if( ( aLayerMask & seg->GetLayerSet() ).any() )
78  return seg;
79  }
80 
81  if( aPosition == seg->GetEnd() )
82  {
83  if( ( aLayerMask & seg->GetLayerSet() ).any() )
84  return seg;
85  }
86  }
87 
88  if( seg == aEndTrace )
89  break;
90  }
91 
92  return NULL;
93 }
94 
95 
96 TRACK::TRACK( BOARD_ITEM* aParent, KICAD_T idtype ) :
97  BOARD_CONNECTED_ITEM( aParent, idtype )
98 {
99  m_Width = Millimeter2iu( 0.2 );
100  start = end = NULL;
101  m_Param = 0;
102 }
103 
104 
106 {
107  return new TRACK( *this );
108 }
109 
110 
112  TRACK( aParent, PCB_SEGZONE_T )
113 {
114 }
115 
116 
118 {
119  return new SEGZONE( *this );
120 }
121 
122 
123 wxString SEGZONE::GetSelectMenuText( EDA_UNITS_T aUnits ) const
124 {
125  return wxString::Format( _( "Zone [%s] on %s" ), GetNetnameMsg(), GetLayerName() );
126 }
127 
128 
130 {
131  return add_zone_xpm;
132 }
133 
134 
135 VIA::VIA( BOARD_ITEM* aParent ) :
136  TRACK( aParent, PCB_VIA_T )
137 {
140  SetDrillDefault();
141 }
142 
143 
145 {
146  return new VIA( *this );
147 }
148 
149 
150 wxString VIA::GetSelectMenuText( EDA_UNITS_T aUnits ) const
151 {
152  wxString format;
153  BOARD* board = GetBoard();
154 
155  switch( GetViaType() )
156  {
157  case VIA_BLIND_BURIED:
158  format = _( "Blind/Buried Via %s %s on %s - %s" );
159  break;
160  case VIA_MICROVIA:
161  format = _( "Micro Via %s %s on %s - %s" );
162  break;
163  // else say nothing about normal (through) vias
164  default:
165  format = _( "Via %s %s on %s - %s" );
166  break;
167  }
168 
169  if( board )
170  {
171  // say which layers, only two for now
172  PCB_LAYER_ID topLayer;
173  PCB_LAYER_ID botLayer;
174  LayerPair( &topLayer, &botLayer );
175  return wxString::Format( format.GetData(),
176  MessageTextFromValue( aUnits, m_Width ),
177  GetNetnameMsg(),
178  board->GetLayerName( topLayer ),
179  board->GetLayerName( botLayer ) );
180 
181  }
182  else
183  {
184  return wxString::Format( format.GetData(),
185  MessageTextFromValue( aUnits, m_Width ),
186  GetNetnameMsg(),
187  wxT( "??" ),
188  wxT( "??" ) );
189  }
190 }
191 
192 
194 {
195  return via_xpm;
196 }
197 
198 
200 {
201  // Currently tracks have no specific clearance parameter on a per track or per
202  // segment basis. The NETCLASS clearance is used.
203  return BOARD_CONNECTED_ITEM::GetClearance( aItem );
204 }
205 
206 
208 {
209  if( m_Drill > 0 ) // Use the specific value.
210  return m_Drill;
211 
212  // Use the default value from the Netclass
213  NETCLASSPTR netclass = GetNetClass();
214 
215  if( GetViaType() == VIA_MICROVIA )
216  return netclass->GetuViaDrill();
217 
218  return netclass->GetViaDrill();
219 }
220 
221 
223 {
224  if( ( Type() != PCB_VIA_T ) && ( m_Start == m_End ) )
225  return true;
226  else
227  return false;
228 }
229 
230 
231 STATUS_FLAGS TRACK::IsPointOnEnds( const wxPoint& point, int min_dist )
232 {
233  STATUS_FLAGS result = 0;
234 
235  if( min_dist < 0 )
236  min_dist = m_Width / 2;
237 
238  if( min_dist == 0 )
239  {
240  if( m_Start == point )
241  result |= STARTPOINT;
242 
243  if( m_End == point )
244  result |= ENDPOINT;
245  }
246  else
247  {
248  double dist = GetLineLength( m_Start, point );
249 
250  if( min_dist >= KiROUND( dist ) )
251  result |= STARTPOINT;
252 
253  dist = GetLineLength( m_End, point );
254 
255  if( min_dist >= KiROUND( dist ) )
256  result |= ENDPOINT;
257  }
258 
259  return result;
260 }
261 
262 
264 {
265  // end of track is round, this is its radius, rounded up
266  int radius = ( m_Width + 1 ) / 2;
267  int ymax, xmax, ymin, xmin;
268 
269  if( Type() == PCB_VIA_T )
270  {
271  ymax = m_Start.y;
272  xmax = m_Start.x;
273 
274  ymin = m_Start.y;
275  xmin = m_Start.x;
276  }
277  else
278  {
279  ymax = std::max( m_Start.y, m_End.y );
280  xmax = std::max( m_Start.x, m_End.x );
281 
282  ymin = std::min( m_Start.y, m_End.y );
283  xmin = std::min( m_Start.x, m_End.x );
284  }
285 
286  ymax += radius;
287  xmax += radius;
288 
289  ymin -= radius;
290  xmin -= radius;
291 
292  // return a rectangle which is [pos,dim) in nature. therefore the +1
293  EDA_RECT ret( wxPoint( xmin, ymin ), wxSize( xmax - xmin + 1, ymax - ymin + 1 ) );
294 
295  return ret;
296 }
297 
298 
299 void TRACK::Rotate( const wxPoint& aRotCentre, double aAngle )
300 {
301  RotatePoint( &m_Start, aRotCentre, aAngle );
302  RotatePoint( &m_End, aRotCentre, aAngle );
303 }
304 
305 
306 void TRACK::Flip( const wxPoint& aCentre )
307 {
308  m_Start.y = aCentre.y - (m_Start.y - aCentre.y);
309  m_End.y = aCentre.y - (m_End.y - aCentre.y);
310  int copperLayerCount = GetBoard()->GetCopperLayerCount();
311  SetLayer( FlipLayer( GetLayer(), copperLayerCount ) );
312 }
313 
314 
315 void VIA::Flip( const wxPoint& aCentre )
316 {
317  m_Start.y = aCentre.y - (m_Start.y - aCentre.y);
318  m_End.y = aCentre.y - (m_End.y - aCentre.y);
319 
320  if( GetViaType() != VIA_THROUGH )
321  {
322  int copperLayerCount = GetBoard()->GetCopperLayerCount();
323  PCB_LAYER_ID top_layer;
324  PCB_LAYER_ID bottom_layer;
325  LayerPair( &top_layer, &bottom_layer );
326  top_layer = FlipLayer( top_layer, copperLayerCount );
327  bottom_layer = FlipLayer( bottom_layer, copperLayerCount );
328  SetLayerPair( top_layer, bottom_layer );
329  }
330 }
331 
332 
333 // see class_track.h
334 SEARCH_RESULT TRACK::Visit( INSPECTOR inspector, void* testData, const KICAD_T scanTypes[] )
335 {
336  KICAD_T stype = *scanTypes;
337 
338  // If caller wants to inspect my type
339  if( stype == Type() )
340  {
341  if( SEARCH_QUIT == inspector( this, testData ) )
342  return SEARCH_QUIT;
343  }
344 
345  return SEARCH_CONTINUE;
346 }
347 
348 
349 bool VIA::IsOnLayer( PCB_LAYER_ID layer_number ) const
350 {
351  PCB_LAYER_ID bottom_layer, top_layer;
352 
353  LayerPair( &top_layer, &bottom_layer );
354 
355  wxASSERT( top_layer <= bottom_layer );
356 
357  if( top_layer <= layer_number && layer_number <= bottom_layer )
358  return true;
359  else
360  return false;
361 }
362 
363 
365 {
366  if( GetViaType() == VIA_THROUGH )
367  return LSET::AllCuMask();
368 
369  // VIA_BLIND_BURIED or VIA_MICRVIA:
370 
371  LSET layermask;
372 
373  wxASSERT( m_Layer <= m_BottomLayer );
374 
375  // PCB_LAYER_IDs are numbered from front to back, this is top to bottom.
376  for( LAYER_NUM id = m_Layer; id <= m_BottomLayer; ++id )
377  {
378  layermask.set( id );
379  }
380 
381  return layermask;
382 }
383 
384 
385 void VIA::SetLayerPair( PCB_LAYER_ID aTopLayer, PCB_LAYER_ID aBottomLayer )
386 {
387 
388  m_Layer = aTopLayer;
389  m_BottomLayer = aBottomLayer;
390  SanitizeLayers();
391 }
392 
393 
395 {
396  m_Layer = aLayer;
397 }
398 
399 
401 {
402  m_BottomLayer = aLayer;
403 }
404 
405 
406 void VIA::LayerPair( PCB_LAYER_ID* top_layer, PCB_LAYER_ID* bottom_layer ) const
407 {
408  PCB_LAYER_ID t_layer = F_Cu;
409  PCB_LAYER_ID b_layer = B_Cu;
410 
411  if( GetViaType() != VIA_THROUGH )
412  {
413  b_layer = m_BottomLayer;
414  t_layer = m_Layer;
415 
416  if( b_layer < t_layer )
417  std::swap( b_layer, t_layer );
418  }
419 
420  if( top_layer )
421  *top_layer = t_layer;
422 
423  if( bottom_layer )
424  *bottom_layer = b_layer;
425 }
426 
427 
429 {
430  return m_Layer;
431 }
432 
433 
435 {
436  return m_BottomLayer;
437 }
438 
439 
441 {
442  if( GetViaType() == VIA_THROUGH )
443  {
444  m_Layer = F_Cu;
446  }
447 
448  if( m_BottomLayer < m_Layer )
449  std::swap( m_BottomLayer, m_Layer );
450 }
451 
452 
454 {
455  TRACK* track;
456 
457  // When reading from a file most of the items will already be in the correct order.
458  // Searching from the back therefore takes us from n^2 to essentially 0.
459 
460  if( Type() == PCB_SEGZONE_T ) // Deprecated items, only found in very old boards
461  track = aPcb->m_SegZoneDeprecated.GetLast();
462  else
463  track = aPcb->m_Track.GetLast();
464 
465  for( ; track; track = track->Back() )
466  {
467  if( GetNetCode() >= track->GetNetCode() )
468  return track->Next();
469  }
470 
471  if( Type() == PCB_SEGZONE_T ) // Deprecated
472  return aPcb->m_SegZoneDeprecated.GetFirst();
473  else
474  return aPcb->m_Track.GetFirst();
475 }
476 
477 
479 {
480  TRACK* Track = this;
481  int ii = 0;
482 
483  if( NetCode == -1 )
484  NetCode = GetNetCode();
485 
486  while( Track != NULL )
487  {
488  if( Track->GetNetCode() > NetCode )
489  break;
490 
491  if( Track->GetNetCode() == NetCode )
492  {
493  ii++;
494  break;
495  }
496 
497  Track = (TRACK*) Track->Pnext;
498  }
499 
500  if( ii )
501  return Track;
502  else
503  return NULL;
504 }
505 
506 
508 {
509  TRACK* NextS, * Track = this;
510  int ii = 0;
511 
512  if( Track == NULL )
513  return NULL;
514 
515  if( NetCode == -1 )
516  NetCode = GetNetCode();
517 
518  while( Track != NULL )
519  {
520  NextS = (TRACK*) Track->Pnext;
521 
522  if( Track->GetNetCode() == NetCode )
523  ii++;
524 
525  if( NextS == NULL )
526  break;
527 
528  if( NextS->GetNetCode() > NetCode )
529  break;
530 
531  Track = NextS;
532  }
533 
534  if( ii )
535  return Track;
536  else
537  return NULL;
538 }
539 
541  wxDC* aDC, GR_DRAWMODE aDrawMode, COLOR4D aBgColor )
542 {
543  if( ! panel )
544  return;
545 
546  /* we must filter tracks, to avoid a lot of texts.
547  * - only tracks with a length > 10 * thickness are eligible
548  * and, of course, if we are not printing the board
549  */
550  auto displ_opts = (PCB_DISPLAY_OPTIONS*)( panel->GetDisplayOptions() );
551 
552  if( displ_opts->m_DisplayNetNamesMode == 0 || displ_opts->m_DisplayNetNamesMode == 1 )
553  return;
554 
555  #define THRESHOLD 10
556 
557  int len = KiROUND( GetLineLength( m_Start, m_End ) );
558 
559  if( len < THRESHOLD * m_Width )
560  return;
561 
562  // no room to display a text inside track
563  if( aDC->LogicalToDeviceXRel( m_Width ) < MIN_TEXT_SIZE )
564  return;
565 
567  return;
568 
569  NETINFO_ITEM* net = GetNet();
570 
571  if( net == NULL )
572  return;
573 
574  int textlen = net->GetShortNetname().Len();
575 
576  if( textlen > 0 )
577  {
578  // calculate a good size for the text
579  int tsize = std::min( m_Width, len / textlen );
580  int dx = m_End.x - m_Start.x ;
581  int dy = m_End.y - m_Start.y ;
582  wxPoint tpos = m_Start + m_End;
583  tpos.x /= 2;
584  tpos.y /= 2;
585 
586  // Calculate angle: if the track segment is vertical, angle = 90 degrees
587  // If horizontal 0 degrees, otherwise compute it
588  double angle; // angle is in 0.1 degree
589 
590  if( dy == 0 ) // Horizontal segment
591  {
592  angle = 0;
593  }
594  else
595  {
596  if( dx == 0 ) // Vertical segment
597  {
598  angle = 900;
599  }
600  else
601  {
602  /* atan2 is *not* the solution here, since it can give upside
603  down text. We want to work only in the first and fourth quadrant */
604  angle = RAD2DECIDEG( -atan( double( dy ) / double( dx ) ) );
605  }
606  }
607 
608  PCB_LAYER_ID curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer;
609 
610  if( ( aDC->LogicalToDeviceXRel( tsize ) >= MIN_TEXT_SIZE )
611  && ( !(!IsOnLayer( curr_layer )&& displ_opts->m_ContrastModeDisplay) ) )
612  {
613  if( (aDrawMode & GR_XOR) == 0 )
614  GRSetDrawMode( aDC, GR_COPY );
615 
616  tsize = (tsize * 7) / 10; // small reduction to give a better look
617  DrawGraphicHaloText( panel->GetClipBox(), aDC, tpos,
618  aBgColor, BLACK, WHITE, net->GetShortNetname(), angle,
619  wxSize( tsize, tsize ),
621  tsize / 7,
622  false, false );
623  }
624  }
625 }
626 
627 
628 void TRACK::Draw( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode,
629  const wxPoint& aOffset )
630 {
631  BOARD* brd = GetBoard();
632 
633  auto frame = static_cast<PCB_BASE_FRAME*> ( panel->GetParent() );
634  auto color = frame->Settings().Colors().GetLayerColor( m_Layer );
635 
636  if( ( !brd->IsLayerVisible( m_Layer ) || !brd->IsElementVisible( LAYER_TRACKS ) )
637  && !( aDrawMode & GR_HIGHLIGHT ) )
638  return;
639 
640 #ifdef USE_WX_OVERLAY
641  // If dragged not draw in OnPaint otherwise remains impressed in wxOverlay
642  if( (m_Flags & IS_DRAGGED) && aDC->IsKindOf(wxCLASSINFO(wxPaintDC)))
643  return;
644 #endif
645 
646  auto displ_opts = (PCB_DISPLAY_OPTIONS*)( panel->GetDisplayOptions() );
647 
648  if( ( aDrawMode & GR_ALLOW_HIGHCONTRAST ) && displ_opts->m_ContrastModeDisplay )
649  {
650  PCB_LAYER_ID curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer;
651 
652  if( !IsOnLayer( curr_layer ) )
654  }
655 
656  if( ( aDrawMode & GR_HIGHLIGHT ) && !( aDrawMode & GR_AND ) )
657  color.SetToLegacyHighlightColor();
658 
659  color.a = 0.588;
660 
661  GRSetDrawMode( aDC, aDrawMode );
662 
663  // Draw track as line if width <= 1pixel:
664  if( aDC->LogicalToDeviceXRel( m_Width ) <= 1 )
665  {
666  GRLine( panel->GetClipBox(), aDC, m_Start + aOffset, m_End + aOffset, m_Width, color );
667  return;
668  }
669 
670  if( !displ_opts->m_DisplayPcbTrackFill || GetState( FORCE_SKETCH ) )
671  {
672  GRCSegm( panel->GetClipBox(), aDC, m_Start + aOffset, m_End + aOffset, m_Width, color );
673  }
674  else
675  {
676  GRFillCSegm( panel->GetClipBox(), aDC, m_Start.x + aOffset.x,
677  m_Start.y + aOffset.y,
678  m_End.x + aOffset.x, m_End.y + aOffset.y, m_Width, color );
679  }
680 
681  if( panel->GetScreen()->m_IsPrinting )
682  return;
683 
684  // Show clearance for tracks, not for zone segments
685  if( ShowClearance( displ_opts, this ) )
686  {
687  GRCSegm( panel->GetClipBox(), aDC, m_Start + aOffset, m_End + aOffset,
688  m_Width + (GetClearance() * 2), color );
689  }
690 
691  DrawShortNetname( panel, aDC, aDrawMode, color );
692 }
693 
694 
695 void SEGZONE::Draw( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode,
696  const wxPoint& aOffset )
697 {
698  auto displ_opts = (PCB_DISPLAY_OPTIONS*)( panel->GetDisplayOptions() );
699 
700  if( displ_opts->m_DisplayZonesMode != 0 )
701  return;
702 
703  BOARD* brd = GetBoard();
704 
705  auto frame = static_cast<PCB_BASE_FRAME*> ( panel->GetParent() );
706  auto color = frame->Settings().Colors().GetLayerColor( m_Layer );
707 
708  if( brd->IsLayerVisible( m_Layer ) == false && !( aDrawMode & GR_HIGHLIGHT ) )
709  return;
710 
711 #ifdef USE_WX_OVERLAY
712  // If dragged not draw in OnPaint otherwise remains impressed in wxOverlay
713  if( (m_Flags & IS_DRAGGED) && aDC->IsKindOf(wxCLASSINFO(wxPaintDC)))
714  return;
715 #endif
716 
717  if( ( aDrawMode & GR_ALLOW_HIGHCONTRAST ) && displ_opts->m_ContrastModeDisplay )
718  {
719  PCB_LAYER_ID curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer;
720 
721  if( !IsOnLayer( curr_layer ) )
723  }
724 
725  if( ( aDrawMode & GR_HIGHLIGHT ) && !( aDrawMode & GR_AND ) )
726  color.SetToLegacyHighlightColor();
727 
728  color.a = 0.588;
729 
730  GRSetDrawMode( aDC, aDrawMode );
731 
732  // Draw track as line if width <= 1pixel:
733  if( aDC->LogicalToDeviceXRel( m_Width ) <= 1 )
734  {
735  GRLine( panel->GetClipBox(), aDC, m_Start + aOffset, m_End + aOffset, m_Width, color );
736  return;
737  }
738 
739  if( !displ_opts->m_DisplayPcbTrackFill || GetState( FORCE_SKETCH ) )
740  {
741  GRCSegm( panel->GetClipBox(), aDC, m_Start + aOffset, m_End + aOffset, m_Width, color );
742  }
743  else
744  {
745  GRFillCSegm( panel->GetClipBox(), aDC, m_Start.x + aOffset.x,
746  m_Start.y + aOffset.y,
747  m_End.x + aOffset.x, m_End.y + aOffset.y, m_Width, color );
748  }
749 
750  // No clearance or netnames for zones
751 }
752 
753 
754 void TRACK::ViewGetLayers( int aLayers[], int& aCount ) const
755 {
756  // Show the track and its netname on different layers
757  aLayers[0] = GetLayer();
758  aLayers[1] = GetNetnameLayer( aLayers[0] );
759  aCount = 2;
760 }
761 
762 
763 unsigned int TRACK::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const
764 {
765  const int HIDE = std::numeric_limits<unsigned int>::max();
766 
767  if( !aView->IsLayerVisible( LAYER_TRACKS ) )
768  return HIDE;
769 
770  // Netnames will be shown only if zoom is appropriate
771  if( IsNetnameLayer( aLayer ) )
772  {
773  return ( Millimeter2iu( 4 ) / ( m_Width + 1 ) );
774  }
775 
776  // Other layers are shown without any conditions
777  return 0;
778 }
779 
780 
781 const BOX2I TRACK::ViewBBox() const
782 {
783  BOX2I bbox = GetBoundingBox();
784  bbox.Inflate( 2 * GetClearance() );
785  return bbox;
786 }
787 
788 
789 void VIA::Draw( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode, const wxPoint& aOffset )
790 {
791  wxCHECK_RET( panel != NULL, wxT( "VIA::Draw panel cannot be NULL." ) );
792 
793  int radius;
794  PCB_LAYER_ID curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer;
795 
796  int fillvia = 0;
797  PCB_BASE_FRAME* frame = (PCB_BASE_FRAME*) panel->GetParent();
798  PCB_SCREEN* screen = frame->GetScreen();
799  auto displ_opts = (PCB_DISPLAY_OPTIONS*)( frame->GetDisplayOptions() );
800 
801  if( displ_opts->m_DisplayViaFill == FILLED )
802  fillvia = 1;
803 
804  GRSetDrawMode( aDC, aDrawMode );
805 
806  BOARD * brd = GetBoard();
808 
809  if( brd->IsElementVisible( LAYER_VIAS + GetViaType() ) == false
810  && !( aDrawMode & GR_HIGHLIGHT ) )
811  return;
812 
813  // Only draw the via if at least one of the layers it crosses is being displayed
814  if( !( brd->GetVisibleLayers() & GetLayerSet() ).any() )
815  return;
816 
817  if( displ_opts->m_ContrastModeDisplay )
818  {
819  if( !IsOnLayer( curr_layer ) )
820  color = COLOR4D( DARKDARKGRAY );
821  }
822 
823  if( ( aDrawMode & GR_HIGHLIGHT ) && !( aDrawMode & GR_AND ) )
824  color.SetToLegacyHighlightColor();
825 
826  color.a = 0.588;
827 
828 
829  radius = m_Width >> 1;
830  // for small via size on screen (radius < 4 pixels) draw a simplified shape
831 
832  int radius_in_pixels = aDC->LogicalToDeviceXRel( radius );
833 
834  bool fast_draw = false;
835 
836  // Vias are drawn as a filled circle or a double circle. The hole will be drawn later
837  int drill_radius = GetDrillValue() / 2;
838 
839  int inner_radius = radius - aDC->DeviceToLogicalXRel( 2 );
840 
841  if( radius_in_pixels < MIN_VIA_DRAW_SIZE )
842  {
843  fast_draw = true;
844  fillvia = false;
845  }
846 
847  if( fillvia )
848  {
849  GRFilledCircle( panel->GetClipBox(), aDC, m_Start + aOffset, radius, color );
850  }
851  else
852  {
853  GRCircle( panel->GetClipBox(), aDC, m_Start + aOffset, radius, 0, color );
854 
855  if ( fast_draw )
856  return;
857 
858  GRCircle( panel->GetClipBox(), aDC, m_Start + aOffset, inner_radius, 0, color );
859  }
860 
861  if( fillvia )
862  {
863  bool blackpenstate = false;
864 
865  if( screen->m_IsPrinting )
866  {
867  blackpenstate = GetGRForceBlackPenState();
868  GRForceBlackPen( false );
869  color = WHITE;
870  }
871  else
872  {
873  color = BLACK; // or DARKGRAY;
874  }
875 
876  if( (aDrawMode & GR_XOR) == 0)
877  GRSetDrawMode( aDC, GR_COPY );
878 
879  // Draw hole if the radius is > 1pixel.
880  if( aDC->LogicalToDeviceXRel( drill_radius ) > 1 )
881  GRFilledCircle( panel->GetClipBox(), aDC, m_Start.x + aOffset.x,
882  m_Start.y + aOffset.y, drill_radius, 0, color, color );
883 
884  if( screen->m_IsPrinting )
885  GRForceBlackPen( blackpenstate );
886  }
887  else
888  {
889  if( drill_radius < inner_radius ) // We can show the via hole
890  GRCircle( panel->GetClipBox(), aDC, m_Start + aOffset, drill_radius, 0, color );
891  }
892 
893  if( ShowClearance( displ_opts, this ) )
894  {
895  GRCircle( panel->GetClipBox(), aDC, m_Start + aOffset, radius + GetClearance(), 0, color );
896  }
897 
898  // for Micro Vias, draw a partial cross : X on component layer, or + on copper layer
899  // (so we can see 2 superimposed microvias ):
900  if( GetViaType() == VIA_MICROVIA )
901  {
902  int ax, ay, bx, by;
903 
904  if( IsOnLayer( B_Cu ) )
905  {
906  ax = radius; ay = 0;
907  bx = drill_radius; by = 0;
908  }
909  else
910  {
911  ax = ay = (radius * 707) / 1000;
912  bx = by = (drill_radius * 707) / 1000;
913  }
914 
915  // lines '|' or '\'
916  GRLine( panel->GetClipBox(), aDC, m_Start.x + aOffset.x - ax,
917  m_Start.y + aOffset.y - ay,
918  m_Start.x + aOffset.x - bx,
919  m_Start.y + aOffset.y - by, 0, color );
920  GRLine( panel->GetClipBox(), aDC, m_Start.x + aOffset.x + bx,
921  m_Start.y + aOffset.y + by,
922  m_Start.x + aOffset.x + ax,
923  m_Start.y + aOffset.y + ay, 0, color );
924 
925  // lines - or '/'
926  GRLine( panel->GetClipBox(), aDC, m_Start.x + aOffset.x + ay,
927  m_Start.y + aOffset.y - ax,
928  m_Start.x + aOffset.x + by,
929  m_Start.y + aOffset.y - bx, 0, color );
930  GRLine( panel->GetClipBox(), aDC, m_Start.x + aOffset.x - by,
931  m_Start.y + aOffset.y + bx,
932  m_Start.x + aOffset.x - ay,
933  m_Start.y + aOffset.y + ax, 0, color );
934  }
935 
936  // for Buried Vias, draw a partial line : orient depending on layer pair
937  // (so we can see superimposed buried vias ):
938  if( GetViaType() == VIA_BLIND_BURIED )
939  {
940  int ax = 0, ay = radius, bx = 0, by = drill_radius;
941  PCB_LAYER_ID layer_top, layer_bottom;
942 
943  LayerPair( &layer_top, &layer_bottom );
944 
945  // lines for the top layer
946  RotatePoint( &ax, &ay, layer_top * 3600.0 / brd->GetCopperLayerCount( ) );
947  RotatePoint( &bx, &by, layer_top * 3600.0 / brd->GetCopperLayerCount( ) );
948  GRLine( panel->GetClipBox(), aDC, m_Start.x + aOffset.x - ax,
949  m_Start.y + aOffset.y - ay,
950  m_Start.x + aOffset.x - bx,
951  m_Start.y + aOffset.y - by, 0, color );
952 
953  // lines for the bottom layer
954  ax = 0; ay = radius; bx = 0; by = drill_radius;
955  RotatePoint( &ax, &ay, layer_bottom * 3600.0 / brd->GetCopperLayerCount( ) );
956  RotatePoint( &bx, &by, layer_bottom * 3600.0 / brd->GetCopperLayerCount( ) );
957  GRLine( panel->GetClipBox(), aDC, m_Start.x + aOffset.x - ax,
958  m_Start.y + aOffset.y - ay,
959  m_Start.x + aOffset.x - bx,
960  m_Start.y + aOffset.y - by, 0, color );
961  }
962 
963  // Display the short netname:
965  return;
966 
967  if( displ_opts->m_DisplayNetNamesMode == 0 || displ_opts->m_DisplayNetNamesMode == 1 )
968  return;
969 
970  NETINFO_ITEM* net = GetNet();
971 
972  if( net == NULL )
973  return;
974 
975  int len = net->GetShortNetname().Len();
976 
977  if( len > 0 )
978  {
979  // calculate a good size for the text
980  int tsize = m_Width / len;
981 
982  if( aDC->LogicalToDeviceXRel( tsize ) >= MIN_TEXT_SIZE )
983  {
984  tsize = (tsize * 7) / 10; // small reduction to give a better look, inside via
985 
986  if( (aDrawMode & GR_XOR) == 0 )
987  GRSetDrawMode( aDC, GR_COPY );
988 
989  EDA_RECT* clipbox = panel->GetClipBox();
990  DrawGraphicHaloText( clipbox, aDC, m_Start,
991  color, WHITE, BLACK, net->GetShortNetname(), 0,
992  wxSize( tsize, tsize ),
994  tsize / 7, false, false );
995  }
996  }
997 }
998 
999 
1000 void VIA::ViewGetLayers( int aLayers[], int& aCount ) const
1001 {
1002  aLayers[0] = LAYER_VIAS_HOLES;
1003  aLayers[1] = LAYER_VIAS_NETNAMES;
1004  aCount = 3;
1005 
1006  // Just show it on common via & via holes layers
1007  switch( GetViaType() )
1008  {
1009  case VIA_THROUGH:
1010  aLayers[2] = LAYER_VIA_THROUGH;
1011  break;
1012 
1013  case VIA_BLIND_BURIED:
1014  aLayers[2] = LAYER_VIA_BBLIND;
1015  aLayers[3] = m_Layer;
1016  aLayers[4] = m_BottomLayer;
1017  aCount += 2;
1018  break;
1019 
1020  case VIA_MICROVIA:
1021  aLayers[2] = LAYER_VIA_MICROVIA;
1022  break;
1023 
1024  default:
1025  aLayers[2] = LAYER_GP_OVERLAY;
1026  wxASSERT( false );
1027  break;
1028  }
1029 }
1030 
1031 
1032 unsigned int VIA::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const
1033 {
1034  constexpr unsigned int HIDE = std::numeric_limits<unsigned int>::max();
1035 
1036  // Netnames will be shown only if zoom is appropriate
1037  if( IsNetnameLayer( aLayer ) )
1038  return m_Width == 0 ? HIDE : ( Millimeter2iu( 10 ) / m_Width );
1039 
1040 
1041  BOARD* board = GetBoard();
1042 
1043  // Only draw the via if at least one of the layers it crosses is being displayed
1044  if( board && ( board->GetVisibleLayers() & GetLayerSet() ).any() )
1045  return 0;
1046 
1047  return HIDE;
1048 }
1049 
1050 
1051 // see class_track.h
1052 void TRACK::GetMsgPanelInfo( EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM >& aList )
1053 {
1054  wxString msg;
1055  BOARD* board = GetBoard();
1056 
1057  // Display basic infos
1058  GetMsgPanelInfoBase( aUnits, aList );
1059 
1060  // Display full track length (in Pcbnew)
1061  if( board )
1062  {
1063  double trackLen = 0;
1064  double lenPadToDie = 0;
1065 
1066  // Find the beginning of the track buffer containing this, because it is not
1067  // always the track list on board, but can be a "private" list
1068  TRACK* track_buffer_start = this;
1069 
1070  while( track_buffer_start->Back() )
1071  track_buffer_start = track_buffer_start->Back();
1072 
1073  board->MarkTrace( track_buffer_start, this, NULL, &trackLen, &lenPadToDie, false );
1074  msg = MessageTextFromValue( aUnits, trackLen );
1075  aList.push_back( MSG_PANEL_ITEM( _( "Length" ), msg, DARKCYAN ) );
1076 
1077  if( lenPadToDie != 0 )
1078  {
1079  msg = MessageTextFromValue( aUnits, trackLen + lenPadToDie );
1080  aList.push_back( MSG_PANEL_ITEM( _( "Full Length" ), msg, DARKCYAN ) );
1081 
1082  msg = MessageTextFromValue( aUnits, lenPadToDie, true );
1083  aList.push_back( MSG_PANEL_ITEM( _( "Pad To Die Length" ), msg, DARKCYAN ) );
1084  }
1085  }
1086 
1087  NETCLASSPTR netclass = GetNetClass();
1088 
1089  if( netclass )
1090  {
1091  aList.push_back( MSG_PANEL_ITEM( _( "NC Name" ), netclass->GetName(), DARKMAGENTA ) );
1092 
1093  msg = MessageTextFromValue( aUnits, netclass->GetClearance(), true );
1094  aList.push_back( MSG_PANEL_ITEM( _( "NC Clearance" ), msg, DARKMAGENTA ) );
1095 
1096  msg = MessageTextFromValue( aUnits, netclass->GetTrackWidth(), true );
1097  aList.push_back( MSG_PANEL_ITEM( _( "NC Width" ), msg, DARKMAGENTA ) );
1098 
1099  msg = MessageTextFromValue( aUnits, netclass->GetViaDiameter(), true );
1100  aList.push_back( MSG_PANEL_ITEM( _( "NC Via Size" ), msg, DARKMAGENTA ) );
1101 
1102  msg = MessageTextFromValue( aUnits, netclass->GetViaDrill(), true );
1103  aList.push_back( MSG_PANEL_ITEM( _( "NC Via Drill"), msg, DARKMAGENTA ) );
1104  }
1105 }
1106 
1107 void TRACK::GetMsgPanelInfoBase_Common( EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM >& aList )
1108 {
1109  wxString msg;
1110 
1111  // Display Net Name
1112  if( GetBoard() )
1113  {
1114  NETINFO_ITEM* net = GetNet();
1115 
1116  if( net )
1117  msg = net->GetNetname();
1118  else
1119  msg = wxT( "<noname>" );
1120 
1121  aList.push_back( MSG_PANEL_ITEM( _( "NetName" ), msg, RED ) );
1122 
1123  // Display net code : (useful in test or debug)
1124  msg.Printf( wxT( "%d" ), GetNetCode() );
1125  aList.push_back( MSG_PANEL_ITEM( _( "NetCode" ), msg, RED ) );
1126  }
1127 
1128 #if defined(DEBUG)
1129 
1130  // Display the flags
1131  msg.Printf( wxT( "0x%08X" ), m_Flags );
1132  aList.push_back( MSG_PANEL_ITEM( wxT( "Flags" ), msg, BLUE ) );
1133 
1134 #if 0
1135  // Display start and end pointers:
1136  msg.Printf( wxT( "%p" ), start );
1137  aList.push_back( MSG_PANEL_ITEM( wxT( "start ptr" ), msg, BLUE ) );
1138  msg.Printf( wxT( "%p" ), end );
1139  aList.push_back( MSG_PANEL_ITEM( wxT( "end ptr" ), msg, BLUE ) );
1140  // Display this ptr
1141  msg.Printf( wxT( "%p" ), this );
1142  aList.push_back( MSG_PANEL_ITEM( wxT( "this" ), msg, BLUE ) );
1143 #endif
1144 
1145 #if 0
1146  // Display start and end positions:
1147  msg.Printf( wxT( "%d %d" ), m_Start.x, m_Start.y );
1148  aList.push_back( MSG_PANEL_ITEM( wxT( "Start pos" ), msg, BLUE ) );
1149  msg.Printf( wxT( "%d %d" ), m_End.x, m_End.y );
1150  aList.push_back( MSG_PANEL_ITEM( wxT( "End pos" ), msg, BLUE ) );
1151 #endif
1152 
1153 #endif // defined(DEBUG)
1154 
1155  // Display the State member
1156  msg = wxT( ". . " );
1157 
1158  if( GetState( TRACK_LOCKED ) )
1159  msg[0] = 'L';
1160 
1161  if( GetState( TRACK_AR ) )
1162  msg[2] = 'A';
1163 
1164  aList.push_back( MSG_PANEL_ITEM( _( "Status" ), msg, MAGENTA ) );
1165 }
1166 
1167 void TRACK::GetMsgPanelInfoBase( EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM >& aList )
1168 {
1169  wxString msg;
1170  BOARD* board = GetBoard();
1171 
1172  aList.push_back( MSG_PANEL_ITEM( _( "Type" ), _( "Track" ), DARKCYAN ) );
1173 
1174  GetMsgPanelInfoBase_Common( aUnits, aList );
1175 
1176  // Display layer
1177  if( board )
1178  msg = board->GetLayerName( m_Layer );
1179  else
1180  msg.Printf(wxT("%d"), m_Layer );
1181 
1182  aList.push_back( MSG_PANEL_ITEM( _( "Layer" ), msg, BROWN ) );
1183 
1184  // Display width
1185  msg = MessageTextFromValue( aUnits, m_Width, true );
1186 
1187  aList.push_back( MSG_PANEL_ITEM( _( "Width" ), msg, DARKCYAN ) );
1188 
1189  // Display segment length
1190  msg = ::MessageTextFromValue( aUnits, GetLength() );
1191  aList.push_back( MSG_PANEL_ITEM( _( "Segment Length" ), msg, DARKCYAN ) );
1192 }
1193 
1194 void SEGZONE::GetMsgPanelInfoBase( EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM >& aList )
1195 {
1196  wxString msg;
1197  BOARD* board = GetBoard();
1198 
1199  aList.push_back( MSG_PANEL_ITEM( _( "Type" ), _( "Zone " ), DARKCYAN ) );
1200 
1201  GetMsgPanelInfoBase_Common( aUnits, aList );
1202 
1203  // Display layer
1204  if( board )
1205  msg = board->GetLayerName( m_Layer );
1206  else
1207  msg.Printf( wxT( "%d" ), m_Layer );
1208 
1209  aList.push_back( MSG_PANEL_ITEM( _( "Layer" ), msg, BROWN ) );
1210 
1211  // Display width
1212  msg = MessageTextFromValue( aUnits, m_Width );
1213 
1214  aList.push_back( MSG_PANEL_ITEM( _( "Width" ), msg, DARKCYAN ) );
1215 
1216  // Display segment length
1217  msg = MessageTextFromValue( aUnits, GetLength() );
1218  aList.push_back( MSG_PANEL_ITEM( _( "Segment Length" ), msg, DARKCYAN ) );
1219 }
1220 
1221 void VIA::GetMsgPanelInfoBase( EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM >& aList )
1222 {
1223  wxString msg;
1224  BOARD* board = GetBoard();
1225 
1226  switch( GetViaType() )
1227  {
1228  default:
1229  case VIA_NOT_DEFINED:
1230  msg = wxT( "???" ); // Not used yet, does not exist currently
1231  break;
1232 
1233  case VIA_MICROVIA:
1234  msg = _( "Micro Via" ); // from external layer (TOP or BOTTOM) from
1235  // the near neighbor inner layer only
1236  break;
1237 
1238  case VIA_BLIND_BURIED:
1239  msg = _( "Blind/Buried Via" ); // from inner or external to inner
1240  // or external layer (no restriction)
1241  break;
1242 
1243  case VIA_THROUGH:
1244  msg = _( "Through Via" ); // Usual via (from TOP to BOTTOM layer only )
1245  break;
1246  }
1247 
1248  aList.push_back( MSG_PANEL_ITEM( _( "Type" ), msg, DARKCYAN ) );
1249 
1250  GetMsgPanelInfoBase_Common( aUnits, aList );
1251 
1252 
1253  // Display layer pair
1254  PCB_LAYER_ID top_layer, bottom_layer;
1255 
1256  LayerPair( &top_layer, &bottom_layer );
1257 
1258  if( board )
1259  msg = board->GetLayerName( top_layer ) + wxT( "/" )
1260  + board->GetLayerName( bottom_layer );
1261  else
1262  msg.Printf( wxT( "%d/%d" ), top_layer, bottom_layer );
1263 
1264  aList.push_back( MSG_PANEL_ITEM( _( "Layers" ), msg, BROWN ) );
1265 
1266  // Display width
1267  msg = MessageTextFromValue( aUnits, m_Width, true );
1268 
1269  // Display diameter value:
1270  aList.push_back( MSG_PANEL_ITEM( _( "Diameter" ), msg, DARKCYAN ) );
1271 
1272  // Display drill value
1273  msg = MessageTextFromValue( aUnits, GetDrillValue() );
1274 
1275  wxString title = _( "Drill" );
1276  title += wxT( " " );
1277 
1278  bool drl_specific = true;
1279 
1280  if( GetBoard() )
1281  {
1282  NETINFO_ITEM* net = GetNet();
1283  int drill_class_value = 0;
1284 
1285  if( net )
1286  {
1287  if( GetViaType() == VIA_MICROVIA )
1288  drill_class_value = net->GetMicroViaDrillSize();
1289  else
1290  drill_class_value = net->GetViaDrillSize();
1291  }
1292 
1293  drl_specific = GetDrillValue() != drill_class_value;
1294  }
1295 
1296 
1297  if( drl_specific )
1298  title += _( "(Specific)" );
1299  else
1300  title += _( "(NetClass)" );
1301 
1302  aList.push_back( MSG_PANEL_ITEM( title, msg, RED ) );
1303 }
1304 
1305 
1306 bool TRACK::HitTest( const wxPoint& aPosition ) const
1307 {
1308  return TestSegmentHit( aPosition, m_Start, m_End, m_Width / 2 );
1309 }
1310 
1311 bool VIA::HitTest( const wxPoint& aPosition ) const
1312 {
1313  int max_dist = m_Width / 2;
1314 
1315  // rel_pos is aPosition relative to m_Start (or the center of the via)
1316  wxPoint rel_pos = aPosition - m_Start;
1317  double dist = (double) rel_pos.x * rel_pos.x + (double) rel_pos.y * rel_pos.y;
1318  return dist <= (double) max_dist * max_dist;
1319 }
1320 
1321 
1322 bool TRACK::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
1323 {
1324  EDA_RECT arect = aRect;
1325  arect.Inflate( aAccuracy );
1326 
1327  if( aContained )
1328  /* Tracks are a special case:
1329  * they are considered inside the rect if one end is inside the rect */
1330  return arect.Contains( GetStart() ) || arect.Contains( GetEnd() );
1331  else
1332  return arect.Intersects( GetStart(), GetEnd() );
1333 }
1334 
1335 bool VIA::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
1336 {
1337  EDA_RECT box;
1338  EDA_RECT arect = aRect;
1339  arect.Inflate( aAccuracy );
1340 
1341  box.SetOrigin( GetStart() );
1342  box.Inflate( GetWidth() / 2 );
1343 
1344  if( aContained )
1345  {
1346  return arect.Contains( box );
1347  }
1348  else
1349  {
1350  return arect.IntersectsCircle( GetStart(), GetWidth() / 2 );
1351  }
1352 }
1353 
1354 
1355 VIA* TRACK::GetVia( const wxPoint& aPosition, PCB_LAYER_ID aLayer)
1356 {
1357  for( VIA* via = GetFirstVia( this ); via; via = GetFirstVia( via->Next() ) )
1358  {
1359  if( via->HitTest( aPosition ) &&
1360  !via->GetState( BUSY | IS_DELETED ) &&
1361  ((aLayer == UNDEFINED_LAYER) || (via->IsOnLayer( aLayer ))) )
1362  return via;
1363  }
1364 
1365  return NULL;
1366 }
1367 
1368 
1369 VIA* TRACK::GetVia( TRACK* aEndTrace, const wxPoint& aPosition, LSET aLayerMask )
1370 {
1371  for( VIA* via = GetFirstVia( this, aEndTrace ); via; via = GetFirstVia( via->Next() ) )
1372  {
1373  if( via->HitTest( aPosition ) &&
1374  !via->GetState( BUSY | IS_DELETED ) &&
1375  ( aLayerMask & via->GetLayerSet() ).any()
1376  )
1377  {
1378  return via;
1379  }
1380  }
1381 
1382  return NULL;
1383 }
1384 
1385 
1386 TRACK* TRACK::GetTrack( TRACK* aStartTrace, TRACK* aEndTrace, ENDPOINT_T aEndPoint,
1387  bool aSameNetOnly, bool aSequential )
1388 {
1389  const wxPoint& position = GetEndPoint( aEndPoint );
1390  LSET refLayers = GetLayerSet();
1391  TRACK* previousSegment;
1392  TRACK* nextSegment;
1393 
1394  if( aSequential )
1395  {
1396  // Simple sequential search: from aStartTrace forward to aEndTrace
1397  previousSegment = NULL;
1398  nextSegment = aStartTrace;
1399  }
1400  else
1401  {
1402  /* Local bidirectional search: from this backward to aStartTrace
1403  * AND forward to aEndTrace. The idea is that nearest segments
1404  * are found (on average) faster in this way. In fact same-net
1405  * segments are almost guaranteed to be found faster, in a global
1406  * search, since they are grouped together in the track list */
1407  previousSegment = this;
1408  nextSegment = this;
1409  }
1410 
1411  while( nextSegment || previousSegment )
1412  {
1413  // Terminate the search in the direction if the netcode mis-matches
1414  if( aSameNetOnly )
1415  {
1416  if( nextSegment && (nextSegment->GetNetCode() != GetNetCode()) )
1417  nextSegment = NULL;
1418  if( previousSegment && (previousSegment->GetNetCode() != GetNetCode()) )
1419  previousSegment = NULL;
1420  }
1421 
1422  if( nextSegment )
1423  {
1424  if ( (nextSegment != this) &&
1425  !nextSegment->GetState( BUSY | IS_DELETED ) &&
1426  ( refLayers & nextSegment->GetLayerSet() ).any() )
1427  {
1428  if( (position == nextSegment->m_Start) ||
1429  (position == nextSegment->m_End) )
1430  return nextSegment;
1431  }
1432 
1433  // Keep looking forward
1434  if( nextSegment == aEndTrace )
1435  nextSegment = NULL;
1436  else
1437  nextSegment = nextSegment->Next();
1438  }
1439 
1440  // Same as above, looking back. During sequential search this branch is inactive
1441  if( previousSegment )
1442  {
1443  if( (previousSegment != this) &&
1444  !previousSegment->GetState( BUSY | IS_DELETED ) &&
1445  ( refLayers & previousSegment->GetLayerSet() ).any()
1446  )
1447  {
1448  if( (position == previousSegment->m_Start) ||
1449  (position == previousSegment->m_End) )
1450  return previousSegment;
1451  }
1452 
1453  if( previousSegment == aStartTrace )
1454  previousSegment = NULL;
1455  else
1456  previousSegment = previousSegment->Back();
1457  }
1458  }
1459 
1460  return NULL;
1461 }
1462 
1463 
1464 int TRACK::GetEndSegments( int aCount, TRACK** aStartTrace, TRACK** aEndTrace )
1465 {
1466  TRACK* Track, * via, * segm, * TrackListEnd;
1467  int NbEnds, ii, ok = 0;
1468  LSET layerMask;
1469 
1470  if( aCount <= 1 )
1471  {
1472  *aStartTrace = *aEndTrace = this;
1473  return 1;
1474  }
1475 
1476  // Calculation of the limit analysis.
1477  *aStartTrace = *aEndTrace = NULL;
1478  TrackListEnd = Track = this;
1479  ii = 0;
1480 
1481  for( ; ( Track != NULL ) && ( ii < aCount ); ii++, Track = Track->Next() )
1482  {
1483  TrackListEnd = Track;
1484  Track->m_Param = 0;
1485  }
1486 
1487  // Calculate the extremes.
1488  NbEnds = 0;
1489  Track = this;
1490  ii = 0;
1491 
1492  for( ; ( Track != NULL ) && ( ii < aCount ); ii++, Track = Track->Next() )
1493  {
1494  if( Track->Type() == PCB_VIA_T )
1495  continue;
1496 
1497  layerMask = Track->GetLayerSet();
1498  via = GetVia( TrackListEnd, Track->m_Start, layerMask );
1499 
1500  if( via )
1501  {
1502  layerMask |= via->GetLayerSet();
1503  via->SetState( BUSY, true );
1504  }
1505 
1506  Track->SetState( BUSY, true );
1507  segm = ::GetTrack( this, TrackListEnd, Track->m_Start, layerMask );
1508  Track->SetState( BUSY, false );
1509 
1510  if( via )
1511  via->SetState( BUSY, false );
1512 
1513  if( segm == NULL )
1514  {
1515  switch( NbEnds )
1516  {
1517  case 0:
1518  *aStartTrace = Track; NbEnds++;
1519  break;
1520 
1521  case 1:
1522  int BeginPad, EndPad;
1523  *aEndTrace = Track;
1524 
1525  // Swap ox, oy with fx, fy
1526  BeginPad = Track->GetState( BEGIN_ONPAD );
1527  EndPad = Track->GetState( END_ONPAD );
1528 
1529  Track->SetState( BEGIN_ONPAD | END_ONPAD, false );
1530 
1531  if( BeginPad )
1532  Track->SetState( END_ONPAD, true );
1533 
1534  if( EndPad )
1535  Track->SetState( BEGIN_ONPAD, true );
1536 
1537  std::swap( Track->m_Start, Track->m_End );
1538  std::swap( Track->start, Track->end );
1539  ok = 1;
1540  return ok;
1541  }
1542  }
1543 
1544  layerMask = Track->GetLayerSet();
1545  via = GetVia( TrackListEnd, Track->m_End, layerMask );
1546 
1547  if( via )
1548  {
1549  layerMask |= via->GetLayerSet();
1550  via->SetState( BUSY, true );
1551  }
1552 
1553  Track->SetState( BUSY, true );
1554  segm = ::GetTrack( this, TrackListEnd, Track->m_End, layerMask );
1555  Track->SetState( BUSY, false );
1556 
1557  if( via )
1558  via->SetState( BUSY, false );
1559 
1560  if( segm == NULL )
1561  {
1562  switch( NbEnds )
1563  {
1564  case 0:
1565  int BeginPad, EndPad;
1566  *aStartTrace = Track;
1567  NbEnds++;
1568 
1569  // Swap ox, oy with fx, fy
1570  BeginPad = Track->GetState( BEGIN_ONPAD );
1571  EndPad = Track->GetState( END_ONPAD );
1572 
1573  Track->SetState( BEGIN_ONPAD | END_ONPAD, false );
1574 
1575  if( BeginPad )
1576  Track->SetState( END_ONPAD, true );
1577 
1578  if( EndPad )
1579  Track->SetState( BEGIN_ONPAD, true );
1580 
1581  std::swap( Track->m_Start, Track->m_End );
1582  std::swap( Track->start, Track->end );
1583  break;
1584 
1585  case 1:
1586  *aEndTrace = Track;
1587  ok = 1;
1588  return ok;
1589  }
1590  }
1591  }
1592 
1593  return ok;
1594 }
1595 
1596 
1597 wxString TRACK::GetSelectMenuText( EDA_UNITS_T aUnits ) const
1598 {
1599  return wxString::Format( _("Track %s %s on %s, length: %s" ),
1600  MessageTextFromValue( aUnits, m_Width ),
1601  GetNetnameMsg(),
1602  GetLayerName(),
1603  MessageTextFromValue( aUnits, GetLength() ) );
1604 }
1605 
1606 
1608 {
1609  return add_tracks_xpm;
1610 }
1611 
1613 {
1614  assert( aImage->Type() == PCB_TRACE_T );
1615 
1616  std::swap( *((TRACK*) this), *((TRACK*) aImage) );
1617 }
1618 
1619 void VIA::SwapData( BOARD_ITEM* aImage )
1620 {
1621  assert( aImage->Type() == PCB_VIA_T );
1622 
1623  std::swap( *((VIA*) this), *((VIA*) aImage) );
1624 }
1625 
1626 #if defined(DEBUG)
1627 
1628 wxString TRACK::ShowState( int stateBits )
1629 {
1630  wxString ret;
1631 
1632  if( stateBits & IS_LINKED )
1633  ret << wxT( " | IS_LINKED" );
1634 
1635  if( stateBits & TRACK_AR )
1636  ret << wxT( " | TRACK_AR" );
1637 
1638  if( stateBits & TRACK_LOCKED )
1639  ret << wxT( " | TRACK_LOCKED" );
1640 
1641  if( stateBits & IN_EDIT )
1642  ret << wxT( " | IN_EDIT" );
1643 
1644  if( stateBits & IS_DRAGGED )
1645  ret << wxT( " | IS_DRAGGED" );
1646 
1647  if( stateBits & DO_NOT_DRAW )
1648  ret << wxT( " | DO_NOT_DRAW" );
1649 
1650  if( stateBits & IS_DELETED )
1651  ret << wxT( " | IS_DELETED" );
1652 
1653  if( stateBits & BUSY )
1654  ret << wxT( " | BUSY" );
1655 
1656  if( stateBits & END_ONPAD )
1657  ret << wxT( " | END_ONPAD" );
1658 
1659  if( stateBits & BEGIN_ONPAD )
1660  ret << wxT( " | BEGIN_ONPAD" );
1661 
1662  if( stateBits & FLAG0 )
1663  ret << wxT( " | FLAG0" );
1664 
1665  if( stateBits & FLAG1 )
1666  ret << wxT( " | FLAG1" );
1667 
1668  return ret;
1669 }
1670 
1671 #endif
virtual BASE_SCREEN * GetScreen()=0
#define MIN_VIA_DRAW_SIZE
Definition: class_track.h:61
Definition: colors.h:57
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:676
#define IS_LINKED
Used in calculation to mark linked items (temporary use)
Definition: base_struct.h:111
#define FLAG1
Pcbnew: flag used in local computations.
Definition: base_struct.h:131
KICAD_T Type() const
Function Type()
Definition: base_struct.h:201
void GetMsgPanelInfoBase_Common(EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM > &aList)
Helper function for the common panel info.
to draw blind/buried vias
TRACK * GetTrack(TRACK *aStartTrace, TRACK *aEndTrace, ENDPOINT_T aEndPoint, bool aSameNetOnly, bool aSequential)
Function GetTrack returns the trace segment connected to the segment at aEndPoint from aStartTrace to...
bool IsNull()
Function IsNull returns true if segment length is zero.
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 IsMoving() const
Definition: base_struct.h:221
#define IN_EDIT
Item currently edited.
Definition: base_struct.h:112
wxPoint m_Start
Line start point.
Definition: class_track.h:343
double GetLineLength(const wxPoint &aPointA, const wxPoint &aPointB)
Function GetLineLength returns the length of a line segment defined by aPointA and aPointB...
Definition: trigo.h:191
virtual void SwapData(BOARD_ITEM *aImage) override
Swap data between aItem and aImage.
wxString GetNetnameMsg() const
Function GetNetnameMsg.
PNG memory record (file in memory).
Definition: bitmap_types.h:43
PCB_LAYER_ID BottomLayer() const
static const int dist[10][10]
Definition: ar_matrix.cpp:320
#define END_ONPAD
Pcbnew: flag set for track segment ending on a pad.
Definition: base_struct.h:134
void GRSetDrawMode(wxDC *DC, GR_DRAWMODE draw_mode)
Definition: gr_basic.cpp:223
virtual LSET GetLayerSet() const override
Function GetLayerSet returns a "layer mask", which is a bitmap of all layers on which the TRACK segme...
void SetViaType(VIATYPE_T aViaType)
Definition: class_track.h:462
static int KiROUND(double v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: common.h:120
bool IsLayerVisible(int aLayer) const
Function IsLayerVisible() Returns information about visibility of a particular layer.
Definition: view.h:427
int GetNetnameLayer(int aLayer)
Returns a netname layer corresponding to the given layer.
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...
bool IsNew() const
Definition: base_struct.h:219
Class BOARD_ITEM is a base class for any item which can be embedded within the BOARD container class...
wxString GetSelectMenuText(EDA_UNITS_T aUnits) const override
Function GetSelectMenuText returns the text to display to be used in the selection clarification cont...
virtual PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
bool Contains(const wxPoint &aPoint) const
Function Contains.
virtual void Flip(const wxPoint &aCentre) override
Function Flip Flip this object, i.e.
void GetMsgPanelInfo(EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM > &aList) override
Function GetMsgPanelInfo populates aList of MSG_PANEL_ITEM objects with it&#39;s internal state for displ...
bool IntersectsCircle(const wxPoint &aCenter, const int aRadius) const
Function IntersectsCircle tests for a common area between a circle and this rectangle.
Class BOARD to handle a board.
Definition: colors.h:61
STATUS_FLAGS IsPointOnEnds(const wxPoint &point, int min_dist=0)
Function IsPointOnEnds returns STARTPOINT if point if near (dist = min_dist) start point...
int color
Definition: DXF_plotter.cpp:62
PCB_LAYER_ID FlipLayer(PCB_LAYER_ID aLayerId, int aCopperLayersCount)
Function FlippedLayerNumber.
Definition: lset.cpp:475
int GetCopperLayerCount() const
Function GetCopperLayerCount.
const EDA_RECT GetBoundingBox() const override
Function GetBoundingBox returns the orthogonal, bounding box of this object for display purposes...
virtual void ViewGetLayers(int aLayers[], int &aCount) const override
Function ViewGetLayers() Returns the all the layers within the VIEW the object is painted on...
virtual EDA_ITEM * Clone() const override
Function Clone creates a duplicate of this item with linked list members set to NULL.
to draw via holes (pad holes do not use this layer)
double RAD2DECIDEG(double rad)
Definition: trigo.h:204
void SetOrigin(const wxPoint &pos)
Definition: eda_rect.h:124
void GRCSegm(EDA_RECT *ClipBox, wxDC *DC, int x1, int y1, int x2, int y2, int width, int aPenSize, COLOR4D Color)
Definition: gr_basic.cpp:415
int GetEndSegments(int NbSegm, TRACK **StartTrack, TRACK **EndTrack)
Function GetEndSegments get the segments connected to the end point of the track. ...
static bool ShowClearance(PCB_DISPLAY_OPTIONS *aDisplOpts, const TRACK *aTrack)
Function ShowClearance tests to see if the clearance border is drawn on the given track...
Definition: class_track.cpp:55
#define BUSY
Pcbnew: flag indicating that the structure has.
Definition: base_struct.h:135
virtual EDA_RECT * GetClipBox()
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:216
void GetMsgPanelInfoBase(EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM > &aList) override
Function GetMsgPanelInfoBase Display info about the track segment only, and does not calculate the fu...
VIA(BOARD_ITEM *aParent)
virtual void Rotate(const wxPoint &aRotCentre, double aAngle) override
Function Rotate Rotate this object.
int GetState(int type) const
Definition: base_struct.h:240
void GRFilledCircle(EDA_RECT *ClipBox, wxDC *DC, int x, int y, int r, int width, COLOR4D Color, COLOR4D BgColor)
Definition: gr_basic.cpp:778
void DrawGraphicHaloText(EDA_RECT *aClipBox, wxDC *aDC, const wxPoint &aPos, const COLOR4D aBgColor, COLOR4D aColor1, COLOR4D aColor2, const wxString &aText, double aOrient, const wxSize &aSize, enum EDA_TEXT_HJUSTIFY_T aH_justify, enum EDA_TEXT_VJUSTIFY_T aV_justify, int aWidth, bool aItalic, bool aBold, void(*aCallback)(int x0, int y0, int xf, int yf, void *aData), void *aCallbackData, PLOTTER *aPlotter)
Draw graphic text with a border, so that it can be read on different backgrounds. ...
#define BEGIN_ONPAD
Pcbnew: flag set for track segment starting on a pad.
Definition: base_struct.h:133
Class BOARD_CONNECTED_ITEM is a base class derived from BOARD_ITEM for items that can be connected an...
TRACK * Back() const
Definition: class_track.h:104
wxString GetLayerName() const
Function GetLayerName returns the name of the PCB layer on which the item resides.
const wxPoint & GetEnd() const
Definition: class_track.h:123
KICAD_T
Enum KICAD_T is the set of class identification values, stored in EDA_ITEM::m_StructType.
Definition: typeinfo.h:78
Functions relatives to tracks, vias and segments used to fill zones.
class TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:95
void * GetDisplayOptions() override
Function GetDisplayOptions returns the display options current in use Display options are relative to...
#define MIN_TEXT_SIZE
double m_Param
Definition: class_track.h:97
TRACE_CLEARANCE_DISPLAY_MODE_T m_ShowTrackClearanceMode
How trace clearances are displayed.
int m_Width
Thickness of track, or via diameter.
Definition: class_track.h:342
This file contains miscellaneous commonly used macros and functions.
ENDPOINT_T
Flag used in locate routines (from which endpoint work)
Definition: pcbnew.h:58
Classes used in Pcbnew, CvPcb and GerbView.
virtual unsigned int ViewGetLOD(int aLayer, KIGFX::VIEW *aView) const override
Function ViewGetLOD() Returns the level of detail (LOD) of the item.
#define THRESHOLD
wxString MessageTextFromValue(EDA_UNITS_T aUnits, int aValue, bool aUseMils)
Definition: base_units.cpp:125
COLOR4D GetItemColor(int aItemIdx) const
Function GetItemColor.
virtual EDA_DRAW_FRAME * GetParent() const =0
const INSPECTOR_FUNC & INSPECTOR
Definition: base_struct.h:102
#define IS_DRAGGED
Item being dragged.
Definition: base_struct.h:116
PCB_LAYER_ID m_Layer
const wxString & GetShortNetname() const
Function GetShortNetname.
Definition: netinfo.h:245
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...
Class PCB_DISPLAY_OPTIONS handles display options like enable/disable some optional drawings...
PCB_LAYER_ID
A quick note on layer IDs:
virtual bool HitTest(const wxPoint &aPosition) const override
Function HitTest tests if aPosition is contained within or on the bounding area of an item...
double a
Alpha component.
Definition: color4d.h:290
BITMAP_DEF GetMenuImage() const override
Function GetMenuImage returns a pointer to an image to be used in menus.
Class LSET is a set of PCB_LAYER_IDs.
VIATYPE_T GetViaType() const
Definition: class_track.h:461
std::shared_ptr< NETCLASS > GetNetClass() const
Function GetNetClass returns the NETCLASS for this item.
BITMAP_DEF GetMenuImage() const override
Function GetMenuImage returns a pointer to an image to be used in menus.
void GRForceBlackPen(bool flagforce)
Function GRForceBlackPen.
Definition: gr_basic.cpp:204
T * GetLast() const
Function GetLast returns the last T* in the list without removing it, or NULL if the list is empty...
Definition: dlist.h:170
GR_DRAWMODE
Drawmode. Compositing mode plus a flag or two.
Definition: gr_basic.h:37
void GRFillCSegm(EDA_RECT *ClipBox, wxDC *DC, int x1, int y1, int x2, int y2, int width, COLOR4D Color)
Definition: gr_basic.cpp:518
#define IS_DELETED
Definition: base_struct.h:117
PCB_GENERAL_SETTINGS & Settings()
virtual bool HitTest(const wxPoint &aPosition) const override
Function HitTest tests if aPosition is contained within or on the bounding area of an item...
const wxPoint & GetStart() const
Definition: class_track.h:126
DLIST< SEGZONE > m_SegZoneDeprecated
Definition: class_board.h:251
virtual void Flip(const wxPoint &aCentre) override
Function Flip Flip this object, i.e.
wxPoint m_End
Line end point.
Definition: class_track.h:344
to draw usual through hole vias
int m_Drill
Definition: class_track.h:509
void DrawShortNetname(EDA_DRAW_PANEL *panel, wxDC *aDC, GR_DRAWMODE aDrawMode, COLOR4D aBgColor)
Helper for drawing the short netname in tracks.
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Function GetLayerName returns the name of a layer given by aLayer.
const wxPoint & GetEndPoint(ENDPOINT_T aEndPoint) const
Return the selected endpoint (start or end)
Definition: class_track.h:130
T * GetFirst() const
Function GetFirst returns the first T* in the list without removing it, or NULL if the list is empty...
Definition: dlist.h:163
virtual LSET GetLayerSet() const
Function GetLayerSet returns a "layer mask", which is a bitmap of all layers on which the TRACK segme...
unsigned STATUS_FLAGS
Definition: base_struct.h:147
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...
PCB_LAYER_ID m_BottomLayer
The bottom layer of the via (the top layer is in m_Layer)
Definition: class_track.h:505
virtual unsigned int ViewGetLOD(int aLayer, KIGFX::VIEW *aView) const override
Function ViewGetLOD() Returns the level of detail (LOD) of the item.
TRACK * GetEndNetCode(int NetCode)
general purpose overlay
#define TRACK_LOCKED
Pcbnew: track locked: protected from global deletion.
Definition: base_struct.h:129
Definition: colors.h:60
void SetLayerPair(PCB_LAYER_ID aTopLayer, PCB_LAYER_ID aBottomLayer)
Function SetLayerPair For a via m_Layer contains the top layer, the other layer is in m_BottomLayer...
wxString GetSelectMenuText(EDA_UNITS_T aUnits) const override
Function GetSelectMenuText returns the text to display to be used in the selection clarification cont...
const BOX2I ViewBBox() const override
Function ViewBBox() returns the bounding box of the item covering all its layers. ...
virtual int GetClearance(BOARD_CONNECTED_ITEM *aItem=NULL) const
Function GetClearance returns the clearance in internal units.
virtual int GetClearance(BOARD_CONNECTED_ITEM *aItem=NULL) const override
Function GetClearance returns the clearance in internal units.
void GRLine(EDA_RECT *ClipBox, wxDC *DC, int x1, int y1, int x2, int y2, int width, COLOR4D Color, wxPenStyle aStyle)
Definition: gr_basic.cpp:285
virtual void SwapData(BOARD_ITEM *aImage) override
Swap data between aItem and aImage.
bool m_IsPrinting
Definition: base_screen.h:220
#define FLAG0
Pcbnew: flag used in local computations.
Definition: base_struct.h:132
SEGZONE(BOARD_ITEM *aParent)
void Draw(EDA_DRAW_PANEL *panel, wxDC *DC, GR_DRAWMODE aDrawMode, const wxPoint &aOffset=ZeroOffset) override
Function Draw BOARD_ITEMs have their own color information.
void SetDrillDefault()
Function SetDrillDefault sets the drill value for vias to the default value UNDEFINED_DRILL_DIAMETER...
Definition: class_track.h:490
COLORS_DESIGN_SETTINGS & Colors()
#define TRACK_AR
Pcbnew: autorouted track.
Definition: base_struct.h:130
void LayerPair(PCB_LAYER_ID *top_layer, PCB_LAYER_ID *bottom_layer) const
Function LayerPair Return the 2 layers used by the via (the via actually uses all layers between thes...
int LAYER_NUM
Type LAYER_NUM can be replaced with int and removed.
virtual void GetMsgPanelInfoBase(EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM > &aList)
Function GetMsgPanelInfoBase Display info about the track segment only, and does not calculate the fu...
int GetNetCode() const
Function GetNetCode.
void Draw(EDA_DRAW_PANEL *panel, wxDC *DC, GR_DRAWMODE aDrawMode, const wxPoint &aOffset=ZeroOffset) override
Function Draw BOARD_ITEMs have their own color information.
void Draw(EDA_DRAW_PANEL *panel, wxDC *DC, GR_DRAWMODE aDrawMode, const wxPoint &aOffset=ZeroOffset) override
Function Draw BOARD_ITEMs have their own color information.
virtual void ViewGetLayers(int aLayers[], int &aCount) const override
Function ViewGetLayers() Returns the all the layers within the VIEW the object is painted on...
bool Intersects(const EDA_RECT &aRect) const
Function Intersects tests for a common area between rectangles.
Class NETINFO_ITEM handles the data for a net.
Definition: netinfo.h:69
bool IsElementVisible(GAL_LAYER_ID aLayer) const
Function IsElementVisible tests whether a given element category is visible.
BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Function Inflate inflates the rectangle horizontally by dx and vertically by dy.
Definition: box2.h:300
TRACK * GetBestInsertPoint(BOARD *aPcb)
Function GetBestInsertPoint searches the "best" insertion point within the track linked list...
BITMAP_DEF GetMenuImage() const override
Function GetMenuImage returns a pointer to an image to be used in menus.
TRACK * Next() const
Definition: class_track.h:103
void SetState(int type, int state)
Definition: base_struct.h:245
EDA_ITEM * Clone() const override
Function Clone creates a duplicate of this item with linked list members set to NULL.
TRACK * GetStartNetCode(int NetCode)
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
int GetDrillValue() const
Function GetDrillValue "calculates" the drill value for vias (m-Drill if > 0, or default drill value ...
#define max(a, b)
Definition: auxiliary.h:86
Class BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:171
PCB_LAYER_ID TopLayer() const
int GetWidth() const
Definition: class_track.h:120
void SetTopLayer(PCB_LAYER_ID aLayer)
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
LSET GetVisibleLayers() const
Function GetVisibleLayers is a proxy function that calls the correspondent function in m_BoardSetting...
void GRCircle(EDA_RECT *ClipBox, wxDC *DC, int xc, int yc, int r, int width, COLOR4D Color)
Definition: gr_basic.cpp:755
STATUS_FLAGS m_Flags
Flag bits for editing and other uses.
Definition: base_struct.h:178
#define ENDPOINT
Definition: base_struct.h:120
Class EDA_RECT handles the component boundary box.
Definition: eda_rect.h:44
void GetMsgPanelInfoBase(EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM > &aList) override
Function GetMsgPanelInfoBase Display info about the track segment only, and does not calculate the fu...
Class EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boa...
Definition: base_struct.h:154
The common library.
PCB_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
Definition: colors.h:49
int GetMicroViaDrillSize()
Function GetViaDrillSize returns the size of via drills used to route this net.
Definition: netinfo.h:186
void SetBottomLayer(PCB_LAYER_ID aLayer)
double GetLength() const
Function GetLength returns the length of the track using the hypotenuse calculation.
Definition: class_track.h:179
virtual BOARD * GetBoard() const
Function GetBoard returns the BOARD in which this BOARD_ITEM resides, or NULL if none.
bool IsCopperLayer(LAYER_NUM aLayerId)
Function IsCopperLayer tests whether a layer is a copper layer.
virtual wxString GetSelectMenuText(EDA_UNITS_T aUnits) const override
Function GetSelectMenuText returns the text to display to be used in the selection clarification cont...
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:96
TRACK(BOARD_ITEM *aParent, KICAD_T idtype=PCB_TRACE_T)
Definition: class_track.cpp:96
DLIST< TRACK > m_Track
Definition: class_board.h:250
bool IsOnLayer(PCB_LAYER_ID aLayer) const override
Function IsOnLayer tests to see if this object is on the given layer.
Definition: colors.h:45
const wxString & GetNetname() const
Function GetNetname.
Definition: netinfo.h:239
virtual void * GetDisplayOptions()
Function GetDisplayOptions A way to pass info to draw functions.
Class EDA_MSG_ITEM is used EDA_MSG_PANEL as the item type for displaying messages.
Definition: msgpanel.h:53
Class VIEW.
Definition: view.h:61
bool TestSegmentHit(const wxPoint &aRefPoint, wxPoint aStart, wxPoint aEnd, int aDist)
Function TestSegmentHit test for hit on line segment i.e.
Definition: trigo.cpp:122
SEARCH_RESULT
Definition: base_struct.h:66
bool GetGRForceBlackPenState(void)
Function GetGRForceBlackPenState.
Definition: gr_basic.cpp:214
void SanitizeLayers()
Function SanitizeLayers Check so that the layers are correct dependin on the type of via...
TRACK * MarkTrace(TRACK *aTrackList, TRACK *aTrace, int *aCount, double *aTraceLength, double *aInPackageLength, bool aReorder)
Function MarkTrace marks a chain of trace segments, connected to aTrace.
int GetViaDrillSize()
Function GetViaDrillSize returns the size of via drills used to route this net.
Definition: netinfo.h:176
Message panel definition file.
class SEGZONE, a segment used to fill a zone area (segment on a
Definition: typeinfo.h:97
#define FORCE_SKETCH
Definition: pcbnew.h:73
BOARD_CONNECTED_ITEM * end
Definition: class_track.h:95
static const int UNCONNECTED
Constant that holds the "unconnected net" number (typically 0) all items "connected" to this net are ...
Definition: netinfo.h:469
BOARD_CONNECTED_ITEM * start
Definition: class_track.h:94
EDA_ITEM * Pnext
next in linked list
Definition: base_struct.h:167
class PCB_BASE_FRAME basic PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer...
EDA_UNITS_T
Definition: common.h:159
NETINFO_ITEM * GetNet() const
Function GetNet Returns NET_INFO object for a given item.
#define DO_NOT_DRAW
Used to disable draw function.
Definition: base_struct.h:126
EDA_RECT & Inflate(wxCoord dx, wxCoord dy)
Function Inflate inflates the rectangle horizontally by dx and vertically by dy.
EDA_ITEM * Clone() const override
Function Clone creates a duplicate of this item with linked list members set to NULL.
bool IsNetnameLayer(LAYER_NUM aLayer)
Function IsNetnameLayer tests whether a layer is a netname layer.
#define min(a, b)
Definition: auxiliary.h:85
#define STARTPOINT
Definition: base_struct.h:119
bool IsLayerVisible(PCB_LAYER_ID aLayer) const
Function IsLayerVisible is a proxy function that calls the correspondent function in m_BoardSettings ...
Definition: class_board.h:458
bool IsDragging() const
Definition: base_struct.h:222
Class COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:39
Definition: colors.h:62
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:514