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