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