KiCad PCB EDA Suite
editrack.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-2012 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 
31 #include <fctsys.h>
32 #include <class_drawpanel.h>
33 #include <trigo.h>
34 #include <wxPcbStruct.h>
35 #include <colors_selection.h>
36 
37 #include <pcbnew.h>
38 #include <drc_stuff.h>
39 #include <protos.h>
40 
41 #include <class_board.h>
42 #include <class_track.h>
43 #include <class_zone.h>
44 #include <connectivity.h>
45 
46 
47 static void Abort_Create_Track( EDA_DRAW_PANEL* panel, wxDC* DC );
48 void ShowNewTrackWhenMovingCursor( EDA_DRAW_PANEL* aPanel, wxDC* aDC,
49  const wxPoint& aPosition, bool aErase );
50 static void ComputeBreakPoint( TRACK* track, int n, wxPoint end );
51 static void DeleteNullTrackSegments( BOARD* pcb, DLIST<TRACK>& aTrackList );
52 static void EnsureEndTrackOnPad( D_PAD* Pad );
53 
54 // A PICKED_ITEMS_LIST to store tracks which are modified/added/deleted
55 // during a track edition:
57 
58 
59 /* Function called to abort a track creation
60  */
61 static void Abort_Create_Track( EDA_DRAW_PANEL* Panel, wxDC* DC )
62 {
63  PCB_EDIT_FRAME* frame = (PCB_EDIT_FRAME*) Panel->GetParent();
64  BOARD* pcb = frame->GetBoard();
65  TRACK* track = dyn_cast<TRACK*>( frame->GetCurItem() );
66 
67  if( track )
68  {
69  // Erase the current drawing
70  ShowNewTrackWhenMovingCursor( Panel, DC, wxDefaultPosition, false );
71 
72  if( pcb->IsHighLightNetON() )
73  frame->HighLight( DC );
74 
75  pcb->PopHighLight();
76 
77  if( pcb->IsHighLightNetON() )
78  pcb->DrawHighLight( Panel, DC, pcb->GetHighLightNetCode() );
79 
80  frame->ClearMsgPanel();
81 
82  // Undo pending changes (mainly a lock point creation) and clear the
83  // undo picker list:
84  frame->PutDataInPreviousState( &s_ItemsListPicker, false, false );
85  s_ItemsListPicker.ClearListAndDeleteItems();
86 
87  // Delete current (new) track
89  }
90 
91  frame->SetCurItem( NULL );
92 }
93 
94 /*
95  * This function starts a new track segment.
96  * If a new track segment is in progress, ends this current new segment,
97  * and created a new one.
98  */
99 TRACK* PCB_EDIT_FRAME::Begin_Route( TRACK* aTrack, wxDC* aDC )
100 {
101  TRACK* trackOnStartPoint = NULL;
102  LSET layerMask( GetScreen()->m_Active_Layer );
104 
105  BOARD_CONNECTED_ITEM* lockPoint;
106 
107  if( aTrack == NULL ) // Starting a new track segment
108  {
110 
111  // Prepare the undo command info
112  s_ItemsListPicker.ClearListAndDeleteItems(); // Should not be necessary, but...
113 
114  GetBoard()->PushHighLight();
115 
116  // erase old highlight
117  if( GetBoard()->IsHighLightNetON() )
118  HighLight( aDC );
119 
121  g_CurrentTrackSegment->SetFlags( IS_NEW );
122 
123  GetBoard()->SetHighLightNet( 0 );
124 
125  // Search for a starting point of the new track, a track or pad
126  lockPoint = GetBoard()->GetLockPoint( pos, layerMask );
127 
128  D_PAD* pad = NULL;
129  if( lockPoint ) // An item (pad or track) is found
130  {
131  if( lockPoint->Type() == PCB_PAD_T )
132  {
133  pad = (D_PAD*) lockPoint;
134 
135  // A pad is found: put the starting point on pad center
136  pos = pad->GetPosition();
137  GetBoard()->SetHighLightNet( pad->GetNetCode() );
138  }
139  else // A track segment is found
140  {
141  trackOnStartPoint = (TRACK*) lockPoint;
142  GetBoard()->SetHighLightNet( trackOnStartPoint->GetNetCode() );
143  GetBoard()->CreateLockPoint( pos, trackOnStartPoint, &s_ItemsListPicker );
144  }
145  }
146  else
147  {
148  // Not a starting point, but a filled zone area can exist. This is also a
149  // good starting point.
150  ZONE_CONTAINER* zone;
151  zone = GetBoard()->HitTestForAnyFilledArea( pos,
152  GetScreen()-> m_Active_Layer,
153  GetScreen()-> m_Active_Layer,
154  -1 );
155 
156  if( zone )
157  GetBoard()->SetHighLightNet( zone->GetNetCode() );
158  }
159 
160  DBG( g_CurrentTrackList.VerifyListIntegrity() );
161 
162  int net = -1;
163 
164  if( lockPoint )
165  net = lockPoint->GetNetCode();
166 
167  BuildAirWiresTargetsList( lockPoint, wxPoint( 0, 0 ), net );
168 
169  DBG( g_CurrentTrackList.VerifyListIntegrity() );
170 
171  GetBoard()->HighLightON();
172  GetBoard()->DrawHighLight( m_canvas, aDC, GetBoard()->GetHighLightNetCode() );
173 
174  // Display info about track Net class, and init track and vias sizes:
175  g_CurrentTrackSegment->SetNetCode( GetBoard()->GetHighLightNetCode() );
176  SetCurrentNetClass( g_CurrentTrackSegment->GetNetClassName() );
177 
178  g_CurrentTrackSegment->SetLayer( GetScreen()->m_Active_Layer );
179  g_CurrentTrackSegment->SetWidth( GetDesignSettings().GetCurrentTrackWidth() );
180 
181  if( GetDesignSettings().m_UseConnectedTrackWidth )
182  {
183  if( trackOnStartPoint && trackOnStartPoint->Type() == PCB_TRACE_T )
184  g_CurrentTrackSegment->SetWidth( trackOnStartPoint->GetWidth());
185  }
186 
187  g_CurrentTrackSegment->SetStart( pos );
188  g_CurrentTrackSegment->SetEnd( pos );
189 
190  if( pad )
191  {
192  // Useful to display track length, if the pad has a die length:
193  g_CurrentTrackSegment->SetState( BEGIN_ONPAD, true );
194  g_CurrentTrackSegment->start = pad;
195  }
196 
198  {
199  // Create 2nd segment
201 
202  DBG( g_CurrentTrackList.VerifyListIntegrity(); );
203 
206 
207  g_FirstTrackSegment->SetState( BEGIN_ONPAD | END_ONPAD, false );
208  }
209 
210  DBG( g_CurrentTrackList.VerifyListIntegrity(); );
211 
214  m_canvas->CallMouseCapture( aDC, wxDefaultPosition, false );
215 
216  if( g_Drc_On )
217  {
218  if( BAD_DRC == m_drc->Drc( g_CurrentTrackSegment, GetBoard()->m_Track ) )
219  {
220  return g_CurrentTrackSegment;
221  }
222  }
223  }
224  else // Track in progress : segment coordinates are updated by ShowNewTrackWhenMovingCursor.
225  {
226  // Test for a D.R.C. error:
227  if( g_Drc_On )
228  {
229  if( BAD_DRC == m_drc->Drc( g_CurrentTrackSegment, GetBoard()->m_Track ) )
230  return NULL;
231 
232  // We must handle 2 segments
234  {
235  if( BAD_DRC == m_drc->Drc( g_CurrentTrackSegment->Back(), GetBoard()->m_Track ) )
236  return NULL;
237  }
238  }
239 
240  /* Current track is Ok: current segment is kept, and a new one is
241  * created unless the current segment is null, or 2 last are null
242  * if this is a 2 segments track build.
243  */
244  bool CanCreateNewSegment = true;
245 
247  CanCreateNewSegment = false;
248 
250  && g_CurrentTrackSegment->Back()
251  && g_CurrentTrackSegment->Back()->IsNull() )
252  CanCreateNewSegment = false;
253 
254  if( CanCreateNewSegment )
255  {
256  // Erase old track on screen
257  DBG( g_CurrentTrackList.VerifyListIntegrity(); );
258 
259  ShowNewTrackWhenMovingCursor( m_canvas, aDC, wxDefaultPosition, false );
260 
261  DBG( g_CurrentTrackList.VerifyListIntegrity(); );
262 
263  if( g_Raccord_45_Auto )
264  Add45DegreeSegment( aDC );
265 
266  TRACK* previousTrack = g_CurrentTrackSegment;
267 
268  TRACK* newTrack = (TRACK*)g_CurrentTrackSegment->Clone();
269  g_CurrentTrackList.PushBack( newTrack );
270  newTrack->SetFlags( IS_NEW );
271 
272  newTrack->SetState( BEGIN_ONPAD | END_ONPAD, false );
273  newTrack->start = previousTrack->end;
274 
275  DBG( g_CurrentTrackList.VerifyListIntegrity(); );
276 
277  newTrack->SetStart( newTrack->GetEnd() );
278 
279  newTrack->SetLayer( GetScreen()->m_Active_Layer );
280 
281  if( !GetDesignSettings().m_UseConnectedTrackWidth )
282  newTrack->SetWidth( GetDesignSettings().GetCurrentTrackWidth() );
283 
284  DBG( g_CurrentTrackList.VerifyListIntegrity(); );
285 
286  // Show the new position
287  ShowNewTrackWhenMovingCursor( m_canvas, aDC, wxDefaultPosition, false );
288  }
289  }
290 
292  return g_CurrentTrackSegment;
293 }
294 
295 
297 {
298  int dx0, dy0, dx1, dy1;
299 
300  if( g_CurrentTrackList.GetCount() < 2 )
301  return false; // There must be 2 segments.
302 
303  TRACK* curTrack = g_CurrentTrackSegment;
304  TRACK* prevTrack = curTrack->Back();
305 
306  // Test if we have 2 consecutive track segments ( not via ) to connect.
307  if( curTrack->Type() != PCB_TRACE_T || prevTrack->Type() != PCB_TRACE_T )
308  {
309  return false;
310  }
311 
312  int segm_step_45 = KiROUND( GetScreen()->GetGridSize().x / 2 );
313 
314  if( segm_step_45 < ( curTrack->GetWidth() * 2 ) )
315  segm_step_45 = curTrack->GetWidth() * 2;
316 
317  // Test if the segments are horizontal or vertical.
318  dx0 = prevTrack->GetEnd().x - prevTrack->GetStart().x;
319  dy0 = prevTrack->GetEnd().y - prevTrack->GetStart().y;
320 
321  dx1 = curTrack->GetEnd().x - curTrack->GetStart().x;
322  dy1 = curTrack->GetEnd().y - curTrack->GetStart().y;
323 
324  // Segments should have a min length.
325  if( std::max( abs( dx0 ), abs( dy0 ) ) < ( segm_step_45 * 2 ) )
326  return false;
327 
328  if( std::max( abs( dx1 ), abs( dy1 ) ) < ( segm_step_45 * 2 ) )
329  return false;
330 
331  // Create a new segment and connect it with the previous 2 segments.
332  TRACK* newTrack = (TRACK*)curTrack->Clone();
333 
334  newTrack->SetStart( prevTrack->GetEnd() );
335  newTrack->SetEnd( curTrack->GetStart() );
336 
337  if( dx0 == 0 ) // Previous segment is Vertical
338  {
339  if( dy1 != 0 ) // 2 segments are not 90 degrees.
340  {
341  delete newTrack;
342  return false;
343  }
344 
345  /* Calculate coordinates the connection point.
346  * The new segment connects the 1st vertical segment and the 2nd
347  * horizontal segment.
348  */
349  if( dy0 > 0 )
350  newTrack->SetStart( wxPoint(newTrack->GetStart().x, newTrack->GetStart().y -segm_step_45) );
351  else
352  newTrack->SetStart( wxPoint(newTrack->GetStart().x, newTrack->GetStart().y + segm_step_45) );
353 
354  if( dx1 > 0 )
355  newTrack->SetEnd( wxPoint(newTrack->GetEnd().x + segm_step_45, newTrack->GetEnd().y) );
356  else
357  newTrack->SetEnd( wxPoint(newTrack->GetEnd().x - segm_step_45, newTrack->GetEnd().y) );
358 
359  if( g_Drc_On && BAD_DRC == m_drc->Drc( curTrack, GetBoard()->m_Track ) )
360  {
361  delete newTrack;
362  return false;
363  }
364 
365  prevTrack->SetEnd( newTrack->GetStart());
366  curTrack->SetStart( newTrack->GetEnd());
367 
368  g_CurrentTrackList.Insert( newTrack, curTrack );
369  return true;
370  }
371 
372  if( dy0 == 0 ) // Previous segment is horizontal
373  {
374  if( dx1 != 0 ) // 2 segments are not 90 degrees
375  {
376  delete newTrack;
377  return false;
378  }
379 
380  /* Calculate the coordinates of the point of connection:
381  * A new segment has been created, connecting segment 1
382  * (horizontal) and segment 2 (vertical)
383  */
384  if( dx0 > 0 )
385  newTrack->SetStart( wxPoint(newTrack->GetStart().x - segm_step_45 , newTrack->GetStart().y));
386  else
387  newTrack->SetStart( wxPoint(newTrack->GetStart().x + segm_step_45, newTrack->GetStart().y) );
388 
389  if( dy1 > 0 )
390  newTrack->SetEnd( wxPoint(newTrack->GetEnd().x, newTrack->GetEnd().y + segm_step_45) );
391  else
392  newTrack->SetEnd( wxPoint(newTrack->GetEnd().x, newTrack->GetEnd().y - segm_step_45) );
393 
394  if( g_Drc_On && BAD_DRC==m_drc->Drc( newTrack, GetBoard()->m_Track ) )
395  {
396  delete newTrack;
397  return false;
398  }
399 
400  prevTrack->SetEnd( newTrack->GetStart());
401  curTrack->SetStart( newTrack->GetEnd());
402 
403  g_CurrentTrackList.Insert( newTrack, curTrack );
404  return true;
405  }
406 
407  return false;
408 }
409 
410 
411 bool PCB_EDIT_FRAME::End_Route( TRACK* aTrack, wxDC* aDC )
412 {
413  LSET layerMask( GetScreen()->m_Active_Layer );
414 
415  if( aTrack == NULL )
416  return false;
417 
418  if( g_Drc_On && BAD_DRC == m_drc->Drc( g_CurrentTrackSegment, GetBoard()->m_Track ) )
419  return false;
420 
421  // Saving the coordinate of end point of the trace
422  wxPoint pos = g_CurrentTrackSegment->GetEnd();
423 
424  DBG( g_CurrentTrackList.VerifyListIntegrity(); );
425 
426  if( Begin_Route( aTrack, aDC ) == NULL )
427  return false;
428 
429  ShowNewTrackWhenMovingCursor( m_canvas, aDC, wxDefaultPosition, true );
430  ShowNewTrackWhenMovingCursor( m_canvas, aDC, wxDefaultPosition, false );
431  TraceAirWiresToTargets( aDC );
432 
433  /* cleanup
434  * if( g_CurrentTrackSegment->Next() != NULL )
435  * {
436  * delete g_CurrentTrackSegment->Next();
437  * g_CurrentTrackSegment->SetNext( NULL );
438  * }
439  */
440 
441  DBG( g_CurrentTrackList.VerifyListIntegrity(); );
442 
443 
444  /* The track here is now chained to the list of track segments.
445  * It must be seen in the area of net
446  * As close as possible to the segment base (or end), because
447  * This helps to reduce the computing time */
448 
449  // Attaching the end point of the new track to a pad or a track
450  BOARD_CONNECTED_ITEM* lockPoint = GetBoard()->GetLockPoint( pos, layerMask );
451 
452  if( lockPoint )
453  {
454  if( lockPoint->Type() == PCB_PAD_T ) // End of track is on a pad.
455  {
456  EnsureEndTrackOnPad( (D_PAD*) lockPoint );
457  }
458  else // If end point of is on a different track,
459  // creates a lock point if not exists
460  {
461  // Creates a lock point, if not already exists:
462  wxPoint hp = g_CurrentTrackSegment->GetEnd();
463  lockPoint = GetBoard()->CreateLockPoint( hp, (TRACK*) lockPoint, &s_ItemsListPicker );
464  g_CurrentTrackSegment->SetEnd(hp);
465  }
466  }
467 
468  // Delete null length segments:
470 
471  // Insert new segments if they exist.
472  // g_FirstTrackSegment can be NULL on a double click on the starting point
473  if( g_FirstTrackSegment != NULL )
474  {
475  int netcode = g_FirstTrackSegment->GetNetCode();
476  TRACK* firstTrack = g_FirstTrackSegment;
477  int newCount = g_CurrentTrackList.GetCount();
478 
479  // Put entire new current segment list in BOARD, and prepare undo command
480  TRACK* track;
481  TRACK* insertBeforeMe = g_CurrentTrackSegment->GetBestInsertPoint( GetBoard() );
482 
483  while( ( track = g_CurrentTrackList.PopFront() ) != NULL )
484  {
485  ITEM_PICKER picker( track, UR_NEW );
486  s_ItemsListPicker.PushItem( picker );
487  GetBoard()->m_Track.Insert( track, insertBeforeMe );
488  GetBoard()->GetConnectivity()->Add( track );
489  }
490 
491  TraceAirWiresToTargets( aDC );
492 
493  int i = 0;
494 
495  for( track = firstTrack; track && i < newCount; ++i, track = track->Next() )
496  {
497  track->ClearFlags();
498  track->SetState( BUSY, false );
499  }
500 
501  // delete the old track, if it exists and is redundant
503  {
504  EraseRedundantTrack( aDC, firstTrack, newCount, &s_ItemsListPicker );
505  }
506 
507  SaveCopyInUndoList( s_ItemsListPicker, UR_UNSPECIFIED );
508  s_ItemsListPicker.ClearItemsList(); // s_ItemsListPicker is no more owner of picked items
509 
510  // compute the new ratsnest
511  TestNetConnection( aDC, netcode );
512  OnModify();
513  SetMsgPanel( GetBoard() );
514 
515  // Redraw the entire new track.
516  DrawTraces( m_canvas, aDC, firstTrack, newCount, GR_OR );
517  }
518 
519  wxASSERT( g_FirstTrackSegment == NULL );
520  wxASSERT( g_CurrentTrackSegment == NULL );
521  wxASSERT( g_CurrentTrackList.GetCount() == 0 );
522 
523  if( GetBoard()->IsHighLightNetON() )
524  HighLight( aDC );
525 
526  GetBoard()->PopHighLight();
527 
528  if( GetBoard()->IsHighLightNetON() )
529  GetBoard()->DrawHighLight( m_canvas, aDC, GetBoard()->GetHighLightNetCode() );
530 
531  m_canvas->SetMouseCapture( NULL, NULL );
532  SetCurItem( NULL );
533 
534  GetBoard()->GetConnectivity()->RecalculateRatsnest();
535 
536  return true;
537 }
538 
539 
540 TRACK* LocateIntrusion( TRACK* listStart, TRACK* aTrack, LAYER_NUM aLayer, const wxPoint& aRef )
541 {
542  int net = aTrack->GetNetCode();
543  int width = aTrack->GetWidth();
544 
545  TRACK* found = NULL;
546 
547  for( TRACK* track = listStart; track; track = track->Next() )
548  {
549  if( track->Type() == PCB_TRACE_T ) // skip vias
550  {
551  if( track->GetState( BUSY | IS_DELETED ) )
552  continue;
553 
554  if( aLayer != track->GetLayer() )
555  continue;
556 
557  if( track->GetNetCode() == net )
558  continue;
559 
560  // TRACK::HitTest
561  int dist = (width + track->GetWidth()) / 2 + aTrack->GetClearance( track );
562 
563  if( !TestSegmentHit( aRef, track->GetStart(), track->GetEnd(), dist ) )
564  continue;
565 
566  found = track;
567 
568  // prefer intrusions from the side, not the end
569  wxPoint pos = aRef - track->GetStart();
570  wxPoint vec = track->GetEnd() - track->GetStart();
571  double tmp = (double) pos.x * vec.x + (double) pos.y * vec.y;
572 
573  if( tmp >= 0 && tmp <= (double) vec.x * vec.x + (double) vec.y * vec.y )
574  break;
575  }
576  }
577 
578  return found;
579 }
580 
581 
598 static void PushTrack( EDA_DRAW_PANEL* panel )
599 {
600  PCB_SCREEN* screen = (PCB_SCREEN*) panel->GetParent()->GetScreen();
601  BOARD* pcb = ( (PCB_BASE_FRAME*) (panel->GetParent()) )->GetBoard();
602  wxPoint cursor = panel->GetParent()->GetCrossHairPosition();
603  wxPoint cv, vec, n;
604  TRACK* track = g_CurrentTrackSegment;
605  TRACK* other;
606  double det;
607  int dist;
608  double f;
609 
610  other = LocateIntrusion( pcb->m_Track, track, screen->m_Active_Layer, panel->GetParent()->RefPos( true ) );
611 
612  // are we currently pointing into a conflicting trace ?
613  if( !other )
614  return;
615 
616  if( other->GetNetCode() == track->GetNetCode() )
617  return;
618 
619  cv = cursor - other->GetStart();
620  vec = other->GetEnd() - other->GetStart();
621 
622  det = (double) cv.x * vec.y - (double) cv.y * vec.x;
623 
624  // cursor is right at the center of the old track
625  if( !det )
626  return;
627 
628  dist = (track->GetWidth() + 1) / 2 + (other->GetWidth() + 1) / 2 + track->GetClearance( other ) + 2;
629 
630  /*
631  * DRC wants >, so +1.
632  * We may have a quantization error of 1/sqrt(2), so +1 again.
633  */
634 
635  // Vector "n" is perpendicular to "other", pointing towards the cursor.
636  if( det > 0 )
637  {
638  n.x = vec.y;
639  n.y = -vec.x;
640  }
641  else
642  {
643  n.x = -vec.y;
644  n.y = vec.x;
645  }
646 
647  f = dist / hypot( double(n.x), double(n.y) );
648  n.x = KiROUND( f * n.x );
649  n.y = KiROUND( f * n.y );
650 
651  wxPoint hp = track->GetEnd();
652  FindBestGridPointOnTrack( &hp, cursor, other );
653  track->SetEnd( hp + n );
654 }
655 
656 
657 //Helper function: Draws Via circle and Via Clearance circle.
658 inline void DrawViaCirclesWhenEditingNewTrack( EDA_RECT* aPanelClipBox,
659  wxDC* aDC, const wxPoint& aPos,
660  int aViaRadius,
661  int aViaRadiusWithClearence,
662  COLOR4D aColor)
663 {
664  //Current viasize clearance circle
665  GRCircle( aPanelClipBox, aDC, aPos.x, aPos.y, aViaRadiusWithClearence, aColor );
666  //Current viasize circle
667  GRCircle( aPanelClipBox, aDC, aPos.x, aPos.y, aViaRadius, aColor );
668 }
669 
670 /* Redraw the current track being created when the mouse cursor is moved
671  */
672 void ShowNewTrackWhenMovingCursor( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
673  bool aErase )
674 {
675 // DBG( g_CurrentTrackList.VerifyListIntegrity(); );
676 
677  PCB_SCREEN* screen = (PCB_SCREEN*) aPanel->GetScreen();
678  PCB_BASE_FRAME* frame = (PCB_BASE_FRAME*) aPanel->GetParent();
679  DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*) aPanel->GetDisplayOptions();
680 
681  bool tmp = displ_opts->m_DisplayPcbTrackFill;
682  displ_opts->m_DisplayPcbTrackFill = true;
683  TRACE_CLEARANCE_DISPLAY_MODE_T showTrackClearanceMode = displ_opts->m_ShowTrackClearanceMode;
684 
685  if ( g_FirstTrackSegment == NULL )
686  return;
687 
688  NETCLASSPTR netclass = g_FirstTrackSegment->GetNetClass();
689 
690  if( showTrackClearanceMode != DO_NOT_SHOW_CLEARANCE )
692 
693  // Values to Via circle
694  int boardViaRadius = frame->GetDesignSettings().GetCurrentViaSize()/2;
695  int viaRadiusWithClearence = boardViaRadius+netclass->GetClearance();
696  EDA_RECT* panelClipBox=aPanel->GetClipBox();
697 
698 #ifndef USE_WX_OVERLAY
699  // Erase old track
700  if( aErase )
701  {
703 
704  frame->TraceAirWiresToTargets( aDC );
705 
706  if( showTrackClearanceMode >= SHOW_CLEARANCE_NEW_TRACKS_AND_VIA_AREAS )
707  {
709  DrawViaCirclesWhenEditingNewTrack( panelClipBox, aDC, g_CurrentTrackSegment->GetEnd(),
710  boardViaRadius, viaRadiusWithClearence, color);
711  }
712  }
713 #endif
714  // MacOSX seems to need this.
715  if( g_CurrentTrackList.GetCount() == 0 )
716  return;
717 
718  // Set track parameters, that can be modified while creating the track
719  g_CurrentTrackSegment->SetLayer( screen->m_Active_Layer );
720 
723 
725  {
726  TRACK* previous_track = g_CurrentTrackSegment->Back();
727 
728  if( previous_track && previous_track->Type()==PCB_TRACE_T )
729  {
730  previous_track->SetLayer( screen->m_Active_Layer );
731 
733  previous_track->SetWidth( frame->GetDesignSettings().GetCurrentTrackWidth() );
734  }
735  }
736 
738  {
740  {
741  g_CurrentTrackSegment->SetEnd( frame->GetCrossHairPosition() );
742 
743  if( g_Drc_On )
744  PushTrack( aPanel );
745 
748  g_CurrentTrackSegment->GetEnd() );
749  }
750  else
751  {
752  /* Calculate of the end of the path for the permitted directions:
753  * horizontal, vertical or 45 degrees.
754  */
755  wxPoint hp = g_CurrentTrackSegment->GetEnd();
757  g_CurrentTrackSegment->GetStart() );
758  g_CurrentTrackSegment->SetEnd(hp);
759  }
760  }
761  else // Here the angle is arbitrary
762  {
763  g_CurrentTrackSegment->SetEnd( frame->GetCrossHairPosition() );
764  }
765 
766  // Redraw the new track
767  DBG( g_CurrentTrackList.VerifyListIntegrity(); );
769 
770  if( showTrackClearanceMode >= SHOW_CLEARANCE_NEW_TRACKS_AND_VIA_AREAS )
771  {
773 
774  //Via diameter must have taken what we are using, rather than netclass value.
775  DrawViaCirclesWhenEditingNewTrack( panelClipBox, aDC, g_CurrentTrackSegment->GetEnd(),
776  boardViaRadius, viaRadiusWithClearence, color);
777 
778  }
779 
780  /* Display info about current segment and the full new track:
781  * Choose the interesting segment: because we are using a 2 segments step,
782  * the last segment can be null, and the previous segment can be the
783  * interesting segment.
784  */
785  TRACK* isegm = g_CurrentTrackSegment;
786 
787  if( isegm->GetLength() == 0 && g_CurrentTrackSegment->Back() )
788  isegm = g_CurrentTrackSegment->Back();
789 
790  // display interesting segment info only:
791  frame->SetMsgPanel( isegm );
792 
793  // Display current track length (on board) and the the actual track len
794  // if there is an extra len due to the len die on the starting pad (if any)
795  double trackLen = 0.0;
796  double lenPadToDie = 0.0;
797  wxString msg;
798 
799  // If the starting point is on a pad, add current track length+ length die
800  if( g_FirstTrackSegment->GetState( BEGIN_ONPAD ) )
801  {
802  D_PAD* pad = (D_PAD*) g_FirstTrackSegment->start;
803  lenPadToDie = (double) pad->GetPadToDieLength();
804  }
805 
806  // calculate track len on board:
807  for( TRACK* track = g_FirstTrackSegment; track; track = track->Next() )
808  trackLen += track->GetLength();
809 
810  msg = frame->LengthDoubleToString( trackLen );
811  frame->AppendMsgPanel( _( "Track Len" ), msg, DARKCYAN );
812 
813  if( lenPadToDie != 0 ) // display the track len on board and the actual track len
814  {
815  frame->AppendMsgPanel( _( "Full Len" ), msg, DARKCYAN );
816  msg = frame->LengthDoubleToString( trackLen+lenPadToDie );
817  frame->AppendMsgPanel( _( "Pad to die" ), msg, DARKCYAN );
818  }
819 
820  // Add current segments count (number of segments in this new track):
821  msg.Printf( wxT( "%d" ), g_CurrentTrackList.GetCount() );
822  frame->AppendMsgPanel( _( "Segs Count" ), msg, DARKCYAN );
823 
824  displ_opts->m_ShowTrackClearanceMode = showTrackClearanceMode;
825  displ_opts->m_DisplayPcbTrackFill = tmp;
826 
827  frame->BuildAirWiresTargetsList( NULL, g_CurrentTrackSegment->GetEnd(), g_CurrentTrackSegment->GetNetCode() );
828  frame->TraceAirWiresToTargets( aDC );
829 }
830 
831 
832 wxPoint CalculateSegmentEndPoint( const wxPoint& aPosition, const wxPoint& aOrigin )
833 {
834  // Determine end point for a segment direction 0, 90, or 45 degrees
835  // depending on it's position from the origin \a aOrigin and \a aPosition.
836  wxPoint endPoint;
837 
838  int deltax = aPosition.x - aOrigin.x;
839  int deltay = aPosition.y - aOrigin.y;
840 
841  deltax = abs( deltax );
842  deltay = abs( deltay );
843  int angle = 45;
844 
845  if( deltax >= deltay )
846  {
847  if( deltax == 0 )
848  angle = 0;
849  else if( ( (deltay << 6 ) / deltax ) < 26 )
850  angle = 0;
851  }
852  else
853  {
854  angle = 45;
855 
856  if( deltay == 0 )
857  angle = 90;
858  else if( ( (deltax << 6 ) / deltay ) < 26 )
859  angle = 90;
860  }
861 
862  switch( angle )
863  {
864  case 0:
865  endPoint.x = aPosition.x;
866  endPoint.y = aOrigin.y;
867  break;
868 
869  case 45:
870  deltax = std::min( deltax, deltay );
871  deltay = deltax;
872 
873  // Recalculate the signs for deltax and deltaY.
874  if( ( aPosition.x - aOrigin.x ) < 0 )
875  deltax = -deltax;
876 
877  if( ( aPosition.y - aOrigin.y ) < 0 )
878  deltay = -deltay;
879 
880  endPoint.x = aOrigin.x + deltax;
881  endPoint.y = aOrigin.y + deltay;
882  break;
883 
884  case 90:
885  endPoint.x = aOrigin.x;
886  endPoint.y = aPosition.y;
887  break;
888  }
889 
890  return endPoint;
891 }
892 
893 
897 void ComputeBreakPoint( TRACK* track, int SegmentCount, wxPoint end )
898 {
899  int iDx = 0;
900  int iDy = 0;
901  int iAngle = 0;
902 
903  if( SegmentCount <= 0 )
904  return;
905 
906  if( track == NULL )
907  return;
908 
909  TRACK* newTrack = track;
910  track = track->Back();
911  SegmentCount--;
912 
913  if( track )
914  {
915  iDx = end.x - track->GetStart().x;
916  iDy = end.y - track->GetStart().y;
917 
918  iDx = abs( iDx );
919  iDy = abs( iDy );
920  }
921 
922  TRACK* lastTrack = track ? track->Back() : NULL;
923 
924  if( lastTrack )
925  {
926  if(( (lastTrack->GetEnd().x == lastTrack->GetStart().x)
927  || (lastTrack->GetEnd().y == lastTrack->GetStart().y) )
929  {
930  iAngle = 45;
931  }
932  }
933  else
934  {
936  {
937  iAngle = 45;
938  }
939  }
940 
941  if( iAngle == 0 )
942  {
943  if( iDx >= iDy )
944  iAngle = 0;
945  else
946  iAngle = 90;
947  }
948 
949  if( track == NULL )
950  iAngle = -1;
951 
952  switch( iAngle )
953  {
954  case -1:
955  break;
956 
957  case 0:
958  if( ( end.x - track->GetStart().x ) < 0 )
959  track->SetEnd(wxPoint( end.x + iDy, track->GetStart().y));
960  else
961  track->SetEnd(wxPoint( end.x - iDy, track->GetStart().y));
962  break;
963 
964  case 45:
965  iDx = std::min( iDx, iDy );
966  iDy = iDx;
967 
968  // Recalculate the signs for deltax and deltaY.
969  if( ( end.x - track->GetStart().x ) < 0 )
970  iDx = -iDx;
971 
972  if( ( end.y - track->GetStart().y ) < 0 )
973  iDy = -iDy;
974 
975  track->SetEnd(wxPoint(track->GetStart().x + iDx, track->GetStart().y + iDy));
976  break;
977 
978  case 90:
979  if( ( end.y - track->GetStart().y ) < 0 )
980  track->SetEnd(wxPoint(track->GetStart().x , end.y + iDx));
981  else
982  track->SetEnd(wxPoint(track->GetStart().x , end.y - iDx));
983  break;
984  }
985 
986  if( track )
987  {
988  if( track->IsNull() )
989  track->SetEnd( end );
990 
991  newTrack->SetStart( track->GetEnd() );
992  }
993 
994  newTrack->SetEnd( end );
995 }
996 
997 
998 /* Delete track segments which have len = 0 after creating a new track
999  * return a pointer on the first segment (start of track list)
1000  */
1001 void DeleteNullTrackSegments( BOARD* pcb, DLIST<TRACK>& aTrackList )
1002 {
1003  if( aTrackList.GetCount() == 0 )
1004  return;
1005 
1006  TRACK* track = aTrackList.GetFirst();
1007  TRACK* firsttrack = track;
1008  TRACK* oldtrack;
1009 
1010  BOARD_CONNECTED_ITEM* lockPoint = track->start;
1011 
1012  while( track != NULL )
1013  {
1014  oldtrack = track;
1015  track = track->Next();
1016 
1017  if( !oldtrack->IsNull() )
1018  {
1019  continue;
1020  }
1021 
1022  // NULL segment, delete it
1023  if( firsttrack == oldtrack )
1024  firsttrack = track;
1025 
1026  delete aTrackList.Remove( oldtrack );
1027  }
1028 
1029  if( aTrackList.GetCount() == 0 )
1030  return; // all the new track segments have been deleted
1031 
1032  // we must set the pointers on connected items and the connection status
1033  oldtrack = track = firsttrack;
1034  firsttrack->start = NULL;
1035 
1036  while( track != NULL )
1037  {
1038  oldtrack = track;
1039  track = track->Next();
1040  oldtrack->end = track;
1041 
1042  if( track )
1043  track->start = oldtrack;
1044 
1045  oldtrack->SetStatus( 0 );
1046  }
1047 
1048  firsttrack->start = lockPoint;
1049 
1050  if( lockPoint && lockPoint->Type()==PCB_PAD_T )
1051  firsttrack->SetState( BEGIN_ONPAD, true );
1052 
1053  track = firsttrack;
1054 
1055  while( track != NULL )
1056  {
1057  TRACK* next_track = track->Next();
1058  lockPoint = pcb->GetPad( track, ENDPOINT_END );
1059 
1060  if( lockPoint )
1061  {
1062  track->end = lockPoint;
1063  track->SetState( END_ONPAD, true );
1064 
1065  if( next_track )
1066  {
1067  next_track->start = lockPoint;
1068  next_track->SetState( BEGIN_ONPAD, true );
1069  }
1070  }
1071 
1072  track = next_track;
1073  }
1074 }
1075 
1076 
1077 /* Ensure the end point of g_CurrentTrackSegment is on the pad "Pad"
1078  * if no, create a new track segment if necessary
1079  * and move current (or new) end segment on pad
1080  */
1082 {
1083  if( g_CurrentTrackSegment->GetEnd() == aPad->GetPosition() ) // Ok !
1084  {
1085  g_CurrentTrackSegment->end = aPad;
1086  g_CurrentTrackSegment->SetState( END_ONPAD, true );
1087  return;
1088  }
1089 
1090  TRACK* lasttrack = g_CurrentTrackSegment;
1091 
1092  if( !g_CurrentTrackSegment->IsNull() )
1093  {
1094  // Must create a new segment, from track end to pad center
1095  g_CurrentTrackList.PushBack( (TRACK*)lasttrack->Clone() );
1096 
1097  lasttrack->end = g_CurrentTrackSegment;
1098  }
1099 
1100  g_CurrentTrackSegment->SetEnd( aPad->GetPosition() );
1101  g_CurrentTrackSegment->SetState( END_ONPAD, false );
1102 
1103  g_CurrentTrackSegment->end = aPad;
1104  g_CurrentTrackSegment->SetState( END_ONPAD, true );
1105 }
#define g_FirstTrackSegment
first segment created
Definition: pcbnew.h:101
#define g_CurrentTrackSegment
most recently created segment
Definition: pcbnew.h:100
KICAD_T Type() const
Function Type()
Definition: base_struct.h:198
void TraceAirWiresToTargets(wxDC *aDC)
Function TraceAirWiresToTargets This functions shows airwires to nearest connecting points (pads) fro...
Definition: ratsnest.cpp:194
virtual void OnModify() override
Function OnModify must be called after a board change to set the modified flag.
Definition: pcbframe.cpp:993
Class ZONE_CONTAINER handles a list of polygons defining a copper zone.
Definition: class_zone.h:78
bool g_Drc_On
Definition: pcbnew.cpp:70
TRACK * CreateLockPoint(wxPoint &aPosition, TRACK *aSegment, PICKED_ITEMS_LIST *aList)
Function CreateLockPoint creates an intermediate point on aSegment and break it into two segments at ...
bool IsNull()
Function IsNull returns true if segment length is zero.
T * Remove(T *aElement)
Function Remove removes aElement from the list, but does not delete it.
Definition: dlist.h:211
static void DeleteNullTrackSegments(BOARD *pcb, DLIST< TRACK > &aTrackList)
Definition: editrack.cpp:1001
bool g_Alternate_Track_Posture
Definition: pcbnew.cpp:73
#define END_ONPAD
Pcbnew: flag set for track segment ending on a pad.
Definition: base_struct.h:133
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
bool g_AutoDeleteOldTrack
Definition: pcbnew.cpp:71
virtual void SetLayer(PCB_LAYER_ID aLayer)
Function SetLayer sets the layer this item is on.
void SetEnd(const wxPoint &aEnd)
Definition: class_track.h:117
static void EnsureEndTrackOnPad(D_PAD *Pad)
Definition: editrack.cpp:1081
DLIST< TRACK > g_CurrentTrackList
Definition: pcbnew.cpp:98
void TestNetConnection(wxDC *aDC, int aNetCode)
Function TestNetConnection tests the connections relative to aNetCode.
Definition: connect.cpp:40
int GetPadToDieLength() const
Definition: class_pad.h:241
Class BOARD to handle a board.
bool Add45DegreeSegment(wxDC *aDC)
Function Add45DegreeSegment adds a track segment between 2 tracks segments if these 2 segments make a...
Definition: editrack.cpp:296
static const int dist[10][10]
Definition: dist.cpp:57
void SetCurItem(BOARD_ITEM *aItem, bool aDisplayInfo=true)
Function SetCurItem sets the currently selected item and displays it in the MsgPanel.
virtual EDA_ITEM * Clone() const override
Function Clone creates a duplicate of this item with linked list members set to NULL.
BOARD * GetBoard() const
Classes to handle copper zones.
void PushItem(const ITEM_PICKER &aItem)
Function PushItem pushes aItem to the top of the list.
class D_PAD, a pad in a footprint
Definition: typeinfo.h:102
D_PAD * GetPad(unsigned aIndex) const
Function GetPad.
#define BUSY
Pcbnew: flag indicating that the structure has.
Definition: base_struct.h:134
DRC * m_drc
the DRC controller, see drc.cpp
Definition: wxPcbStruct.h:96
void BuildAirWiresTargetsList(BOARD_CONNECTED_ITEM *aItemRef, const wxPoint &aPosition, int aNet)
Function BuildAirWiresTargetsList Build a list of candidates that can be a coonection point when a tr...
Definition: ratsnest.cpp:171
void DeleteAll()
Function DeleteAll deletes all items on the list and leaves the list empty.
Definition: dlist.cpp:41
TRACK * Begin_Route(TRACK *aTrack, wxDC *aDC)
Function Begin_Route Starts a new track and/or establish of a new track point.
Definition: editrack.cpp:99
bool SetCurrentNetClass(const wxString &aNetClassName)
Function SetCurrentNetClass Must be called after a netclass selection (or after a netclass parameter ...
Definition: pcbframe.cpp:1112
#define BEGIN_ONPAD
Pcbnew: flag set for track segment starting on a pad.
Definition: base_struct.h:132
PCB_LAYER_ID m_Active_Layer
int GetCurrentViaSize() const
Function GetCurrentViaSize.
#define abs(a)
Definition: auxiliary.h:84
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:99
bool End_Route(TRACK *aTrack, wxDC *aDC)
Function End_Route Terminates a track currently being created.
Definition: editrack.cpp:411
bool m_UseConnectedTrackWidth
if true, when creating a new track starting on an existing track, use this track width ...
BOARD_CONNECTED_ITEM * GetLockPoint(const wxPoint &aPosition, LSET aLayerMask)
Function GetLockPoint returns the item at the "attachment" point at the end of a trace at aPosition o...
Casted dyn_cast(From aObject)
Function dyn_cast()
Definition: typeinfo.h:73
const wxPoint & GetEnd() const
Definition: class_track.h:118
Functions relatives to tracks, vias and segments used to fill zones.
class TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:107
bool g_Raccord_45_Auto
Definition: pcbnew.cpp:72
wxPoint CalculateSegmentEndPoint(const wxPoint &aPosition, const wxPoint &aOrigin)
Determine end point for a segment direction 0, 90, or 45 degrees depending on it's position from the ...
Definition: editrack.cpp:832
void SetWidth(int aWidth)
Definition: class_track.h:114
ZONE_CONTAINER * HitTestForAnyFilledArea(const wxPoint &aRefPos, PCB_LAYER_ID aStartLayer, PCB_LAYER_ID aEndLayer, int aNetCode)
Function HitTestForAnyFilledArea tests if the given wxPoint is within the bounds of a filled area of ...
#define BAD_DRC
Definition: drc_stuff.h:36
void PushBack(T *aNewElement)
Function PushBack puts aNewElement at the end of the list sequence.
Definition: dlist.h:250
#define IS_NEW
New item, just created.
Definition: base_struct.h:113
bool m_DisplayPcbTrackFill
Definition: pcbstruct.h:71
static void PushTrack(EDA_DRAW_PANEL *panel)
Function PushTrack detects if the mouse is pointing into a conflicting track.
Definition: editrack.cpp:598
virtual BASE_SCREEN * GetScreen() const
Function GetScreen returns a pointer to a BASE_SCREEN or one of its derivatives.
Definition: draw_frame.h:309
Class LSET is a set of PCB_LAYER_IDs.
void PopHighLight()
Function PopHighLight retrieve a previously saved high light info.
void SetFlags(STATUS_FLAGS aMask)
Definition: base_struct.h:253
void PutDataInPreviousState(PICKED_ITEMS_LIST *aList, bool aRedoCommand, bool aRebuildRatsnet=true)
Function PutDataInPreviousState Used in undo or redo command.
Definition: undo_redo.cpp:377
void SetMsgPanel(const std::vector< MSG_PANEL_ITEM > &aList)
Function SetMsgPanel clears the message panel and populates it with the contents of aList...
Definition: draw_frame.cpp:773
wxString LengthDoubleToString(double aValue, bool aConvertToMils=false) const
Function LengthDoubleToString is a helper to convert the double value aValue to a string in inches or...
Definition: draw_frame.cpp:817
int EraseRedundantTrack(wxDC *aDC, TRACK *aNewTrack, int aNewTrackSegmentsCount, PICKED_ITEMS_LIST *aItemsListPicker)
Function EraseRedundantTrack Called after creating a track Remove (if exists) the old track that have...
Definition: tr_modif.cpp:63
#define IS_DELETED
Definition: base_struct.h:116
const wxPoint & GetStart() const
Definition: class_track.h:121
const wxPoint & GetPosition() const override
Definition: class_pad.h:170
void CallMouseCapture(wxDC *aDC, const wxPoint &aPosition, bool aErase)
Function CallMouseCapture calls the mouse capture callback.
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
void HighLight(wxDC *DC)
Function HighLight.
Definition: highlight.cpp:101
EDA_RECT * GetClipBox()
virtual BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings returns the BOARD_DESIGN_SETTINGS for the BOARD owned by this frame...
EDA_DRAW_FRAME * GetParent() const
Definition: draw_panel.cpp:175
TRACK * LocateIntrusion(TRACK *listStart, TRACK *aTrack, LAYER_NUM aLayer, const wxPoint &aRef)
Definition: editrack.cpp:540
Class PICKED_ITEMS_LIST is a holder to handle information on schematic or board items.
virtual int GetClearance(BOARD_CONNECTED_ITEM *aItem=NULL) const override
Function GetClearance returns the clearance in internal units.
void SaveCopyInUndoList(BOARD_ITEM *aItemToCopy, UNDO_REDO_T aTypeCommand, const wxPoint &aTransformPoint=wxPoint(0, 0)) override
Function SaveCopyInUndoList Creates a new entry in undo list of commands.
Definition: undo_redo.cpp:172
COLORS_DESIGN_SETTINGS g_ColorsSettings
Definition: pcbnew.cpp:68
int LAYER_NUM
Type LAYER_NUM can be replaced with int and removed.
void HighLightON()
Function HighLightON Enable highlight.
Definition: class_board.h:386
Class DISPLAY_OPTIONS handles display options like enable/disable some optional drawings.
Definition: pcbstruct.h:62
Definition: gr_basic.h:42
bool FindBestGridPointOnTrack(wxPoint *aNearPos, wxPoint on_grid, const TRACK *track)
Finds the projection of a grid point on a track.
int GetNetCode() const
Function GetNetCode.
void SetHighLightNet(int aNetCode)
Function SetHighLightNet.
Definition: class_board.h:364
TRACE_CLEARANCE_DISPLAY_MODE_T m_ShowTrackClearanceMode
How trace clearances are displayed.
Definition: pcbstruct.h:74
wxPoint RefPos(bool useMouse) const
Function RefPos Return the reference position, coming from either the mouse position or the cursor po...
EDA_DRAW_PANEL * m_canvas
The area to draw on.
Definition: draw_frame.h:92
void AppendMsgPanel(const wxString &textUpper, const wxString &textLower, COLOR4D color, int pad=6)
Append a message to the message panel.
Definition: draw_frame.cpp:753
static void Abort_Create_Track(EDA_DRAW_PANEL *panel, wxDC *DC)
Definition: editrack.cpp:61
void DrawViaCirclesWhenEditingNewTrack(EDA_RECT *aPanelClipBox, wxDC *aDC, const wxPoint &aPos, int aViaRadius, int aViaRadiusWithClearence, COLOR4D aColor)
Definition: editrack.cpp:658
TRACK * Next() const
Definition: class_track.h:98
void SetState(int type, int state)
Definition: base_struct.h:242
#define max(a, b)
Definition: auxiliary.h:86
Class BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:169
int GetWidth() const
Definition: class_track.h:115
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
void GRCircle(EDA_RECT *ClipBox, wxDC *DC, int xc, int yc, int r, int width, COLOR4D Color)
Definition: gr_basic.cpp:791
bool g_Track_45_Only_Allowed
Definition: pcbnew.cpp:74
Class EDA_RECT handles the component boundary box.
static void ComputeBreakPoint(TRACK *track, int n, wxPoint end)
Compute new track angle based on previous track.
Definition: editrack.cpp:897
void ShowNewTrackWhenMovingCursor(EDA_DRAW_PANEL *aPanel, wxDC *aDC, const wxPoint &aPosition, bool aErase)
Definition: editrack.cpp:672
BASE_SCREEN * GetScreen()
Definition: draw_panel.cpp:188
void PushHighLight()
Function PushHighLight save current high light info for later use.
void ClearItemsList()
Function ClearItemsList deletes only the list of pickers, NOT the picked data itself.
PCB_SCREEN * GetScreen() const override
Function GetScreen returns a pointer to a BASE_SCREEN or one of its derivatives.
COLOR4D GetLayerColor(LAYER_NUM aLayer) const
Function GetLayerColor.
void SetStatus(STATUS_FLAGS aStatus)
Definition: base_struct.h:251
static PICKED_ITEMS_LIST s_ItemsListPicker
Definition: editrack.cpp:56
double GetLength() const
Function GetLength returns the length of the track using the hypotenuse calculation.
Definition: class_track.h:171
virtual BOARD * GetBoard() const
Function GetBoard returns the BOARD in which this BOARD_ITEM resides, or NULL if none.
unsigned GetCount() const
Function GetCount returns the number of elements in the list.
Definition: dlist.h:126
bool IsHighLightNetON() const
Function IsHighLightNetON.
Definition: class_board.h:373
void SetStart(const wxPoint &aStart)
Definition: class_track.h:120
int Drc(TRACK *aRefSeg, TRACK *aList)
Function Drc tests the current segment and returns the result and displays the error in the status pa...
Definition: drc.cpp:155
#define DBG(x)
Definition: fctsys.h:33
int GetHighLightNetCode() const
Function GetHighLightNetCode.
Definition: class_board.h:358
DLIST< TRACK > m_Track
Definition: class_board.h:246
void * GetDisplayOptions()
Function GetDisplayOptions A way to pass info to draw functions.
Definition: draw_panel.cpp:182
void DrawTraces(EDA_DRAW_PANEL *panel, wxDC *DC, TRACK *aStartTrace, int nbsegment, GR_DRAWMODE mode_color)
Function DrawTraces Draws n consecutive track segments in list.
Definition: tr_modif.cpp:49
bool TestSegmentHit(const wxPoint &aRefPoint, wxPoint aStart, wxPoint aEnd, int aDist)
Function TestSegmentHit test for hit on line segment i.e.
Definition: trigo.cpp:142
void SetMouseCapture(MOUSE_CAPTURE_CALLBACK aMouseCaptureCallback, END_MOUSE_CAPTURE_CALLBACK aEndMouseCaptureCallback)
Function SetMouseCapture sets the mouse capture and end mouse capture callbacks to aMouseCaptureCallb...
void DrawHighLight(EDA_DRAW_PANEL *aDrawPanel, wxDC *aDC, int aNetCode)
Function DrawHighLight redraws the objects in the board that are associated with the given aNetCode a...
Definition: tracepcb.cpp:247
int GetCurrentTrackWidth() const
Function GetCurrentTrackWidth.
BOARD_ITEM * GetCurItem()
BOARD_CONNECTED_ITEM * end
Definition: class_track.h:90
wxPoint GetCrossHairPosition(bool aInvertY=false) const
Function GetCrossHairPosition return the current cross hair position in logical (drawing) coordinates...
BOARD_CONNECTED_ITEM * start
Definition: class_track.h:89
bool g_TwoSegmentTrackBuild
Definition: pcbnew.cpp:76
std::shared_ptr< CONNECTIVITY_DATA > GetConnectivity() const
Function GetConnectivity() returns list of missing connections between components/tracks.
Definition: class_board.h:290
void ClearMsgPanel(void)
Clear all messages from the message panel.
Definition: draw_frame.cpp:764
class PCB_BASE_FRAME basic PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer...
void ClearListAndDeleteItems()
Function ClearListAndDeleteItems deletes the list of pickers, AND the data pointed by m_PickedItem or...
void Insert(T *aNewElement, T *aElementAfterMe)
Function Insert puts aNewElement just in front of aElementAfterMe in the list sequence.
Definition: dlist.h:200
T * PopFront()
Definition: dlist.h:221
#define min(a, b)
Definition: auxiliary.h:85
TRACE_CLEARANCE_DISPLAY_MODE_T
Enum TRACE_CLEARANCE_DISPLAY_MODE_T is the set of values for DISPLAY_OPTIONS.ShowTrackClearanceMode p...
Definition: pcbstruct.h:39
Class COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:39