KiCad PCB EDA Suite
editrack.cpp File Reference
#include <fctsys.h>
#include <class_drawpanel.h>
#include <trigo.h>
#include <pcb_edit_frame.h>
#include <pcbnew.h>
#include <drc.h>
#include <protos.h>
#include <class_board.h>
#include <class_track.h>
#include <class_zone.h>
#include <connectivity_data.h>

Go to the source code of this file.

Functions

static void Abort_Create_Track (EDA_DRAW_PANEL *panel, wxDC *DC)
 
void ShowNewTrackWhenMovingCursor (EDA_DRAW_PANEL *aPanel, wxDC *aDC, const wxPoint &aPosition, bool aErase)
 
static void ComputeBreakPoint (TRACK *track, int SegmentCount, wxPoint end)
 Compute new track angle based on previous track. More...
 
static void DeleteNullTrackSegments (BOARD *pcb, DLIST< TRACK > &aTrackList)
 
static void EnsureEndTrackOnPad (D_PAD *Pad)
 
TRACKLocateIntrusion (TRACK *listStart, TRACK *aTrack, LAYER_NUM aLayer, const wxPoint &aRef)
 
static void PushTrack (EDA_DRAW_PANEL *panel)
 Function PushTrack detects if the mouse is pointing into a conflicting track. More...
 
void DrawViaCirclesWhenEditingNewTrack (EDA_RECT *aPanelClipBox, wxDC *aDC, const wxPoint &aPos, int aViaRadius, int aViaRadiusWithClearence, COLOR4D aColor)
 
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 origin aOrigin and aPosition. More...
 

Variables

static PICKED_ITEMS_LIST s_ItemsListPicker
 

Function Documentation

static void Abort_Create_Track ( EDA_DRAW_PANEL panel,
wxDC *  DC 
)
static

Definition at line 60 of file editrack.cpp.

References PICKED_ITEMS_LIST::ClearListAndDeleteItems(), EDA_DRAW_FRAME::ClearMsgPanel(), DHEAD::DeleteAll(), BOARD::DrawHighLight(), dyn_cast(), g_CurrentTrackList, PCB_BASE_FRAME::GetBoard(), PCB_BASE_FRAME::GetCurItem(), BOARD::GetHighLightNetCode(), EDA_DRAW_PANEL::GetParent(), PCB_EDIT_FRAME::HighLight(), BOARD::IsHighLightNetON(), BOARD::PopHighLight(), PCB_BASE_EDIT_FRAME::PutDataInPreviousState(), PCB_BASE_FRAME::SetCurItem(), and ShowNewTrackWhenMovingCursor().

Referenced by PCB_EDIT_FRAME::Begin_Route().

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 );
85 
86  // Delete current (new) track
88  }
89 
90  frame->SetCurItem( NULL );
91 }
DLIST< TRACK > g_CurrentTrackList
Definition: pcbnew.cpp:89
void SetCurItem(BOARD_ITEM *aItem, bool aDisplayInfo=true)
Function SetCurItem sets the currently selected item and displays it in the MsgPanel.
BOARD * GetBoard() const
void DeleteAll()
Function DeleteAll deletes all items on the list and leaves the list empty.
Definition: dlist.cpp:41
Casted dyn_cast(From aObject)
Function dyn_cast()
Definition: typeinfo.h:61
void PopHighLight()
Function PopHighLight retrieve a previously saved high light info.
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 HighLight(wxDC *DC)
Function HighLight.
Definition: highlight.cpp:101
Class BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:169
void ShowNewTrackWhenMovingCursor(EDA_DRAW_PANEL *aPanel, wxDC *aDC, const wxPoint &aPosition, bool aErase)
Definition: editrack.cpp:666
static PICKED_ITEMS_LIST s_ItemsListPicker
Definition: editrack.cpp:55
bool IsHighLightNetON() const
Function IsHighLightNetON.
Definition: class_board.h:381
int GetHighLightNetCode() const
Function GetHighLightNetCode.
Definition: class_board.h:366
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...
BOARD_ITEM * GetCurItem()
void ClearMsgPanel(void)
Clear all messages from the message panel.
Definition: draw_frame.cpp:823
void ClearListAndDeleteItems()
Function ClearListAndDeleteItems deletes the list of pickers, AND the data pointed by m_PickedItem or...
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 origin aOrigin and aPosition.

Definition at line 826 of file editrack.cpp.

References abs, PNS::angle(), min, wxPoint::x, and wxPoint::y.

Referenced by DrawSegment(), Show_New_Edge_While_Move_Mouse(), and ShowNewTrackWhenMovingCursor().

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 }
#define abs(a)
Definition: auxiliary.h:84
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
#define min(a, b)
Definition: auxiliary.h:85
void ComputeBreakPoint ( TRACK track,
int  n,
wxPoint  end 
)
static

Compute new track angle based on previous track.

Definition at line 891 of file editrack.cpp.

References abs, TRACK::Back(), g_Alternate_Track_Posture, TRACK::GetEnd(), TRACK::GetStart(), TRACK::IsNull(), min, TRACK::SetEnd(), TRACK::SetStart(), wxPoint::x, and wxPoint::y.

Referenced by ShowNewTrackWhenMovingCursor().

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 }
bool IsNull()
Function IsNull returns true if segment length is zero.
bool g_Alternate_Track_Posture
Definition: pcbnew.cpp:71
void SetEnd(const wxPoint &aEnd)
Definition: class_track.h:118
#define abs(a)
Definition: auxiliary.h:84
TRACK * Back() const
Definition: class_track.h:100
const wxPoint & GetEnd() const
Definition: class_track.h:119
const wxPoint & GetStart() const
Definition: class_track.h:122
void SetStart(const wxPoint &aStart)
Definition: class_track.h:121
#define min(a, b)
Definition: auxiliary.h:85
void DeleteNullTrackSegments ( BOARD pcb,
DLIST< TRACK > &  aTrackList 
)
static

Definition at line 995 of file editrack.cpp.

References BEGIN_ONPAD, TRACK::end, END_ONPAD, ENDPOINT_END, DHEAD::GetCount(), DLIST< T >::GetFirst(), BOARD::GetPad(), TRACK::IsNull(), TRACK::Next(), PCB_PAD_T, DLIST< T >::Remove(), EDA_ITEM::SetState(), EDA_ITEM::SetStatus(), TRACK::start, and EDA_ITEM::Type().

Referenced by PCB_EDIT_FRAME::End_Route().

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 }
KICAD_T Type() const
Function Type()
Definition: base_struct.h:209
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
#define END_ONPAD
Pcbnew: flag set for track segment ending on a pad.
Definition: base_struct.h:129
class D_PAD, a pad in a footprint
Definition: typeinfo.h:90
D_PAD * GetPad(unsigned aIndex) const
Function GetPad.
#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...
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
TRACK * Next() const
Definition: class_track.h:99
void SetState(int type, int state)
Definition: base_struct.h:253
void SetStatus(STATUS_FLAGS aStatus)
Definition: base_struct.h:262
unsigned GetCount() const
Function GetCount returns the number of elements in the list.
Definition: dlist.h:126
BOARD_CONNECTED_ITEM * end
Definition: class_track.h:91
BOARD_CONNECTED_ITEM * start
Definition: class_track.h:90
void DrawViaCirclesWhenEditingNewTrack ( EDA_RECT aPanelClipBox,
wxDC *  aDC,
const wxPoint aPos,
int  aViaRadius,
int  aViaRadiusWithClearence,
COLOR4D  aColor 
)
inline

Definition at line 652 of file editrack.cpp.

References GRCircle(), wxPoint::x, and wxPoint::y.

Referenced by ShowNewTrackWhenMovingCursor().

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 }
void GRCircle(EDA_RECT *ClipBox, wxDC *DC, int xc, int yc, int r, int width, COLOR4D Color)
Definition: gr_basic.cpp:850
void EnsureEndTrackOnPad ( D_PAD Pad)
static

Definition at line 1075 of file editrack.cpp.

References TRACK::Clone(), TRACK::end, END_ONPAD, g_CurrentTrackList, g_CurrentTrackSegment, D_PAD::GetPosition(), and DLIST< T >::PushBack().

Referenced by PCB_EDIT_FRAME::End_Route().

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_CurrentTrackSegment
most recently created segment
Definition: pcbnew.h:99
#define END_ONPAD
Pcbnew: flag set for track segment ending on a pad.
Definition: base_struct.h:129
DLIST< TRACK > g_CurrentTrackList
Definition: pcbnew.cpp:89
virtual EDA_ITEM * Clone() const override
Function Clone creates a duplicate of this item with linked list members set to NULL.
void PushBack(T *aNewElement)
Function PushBack puts aNewElement at the end of the list sequence.
Definition: dlist.h:250
BOARD_CONNECTED_ITEM * end
Definition: class_track.h:91
TRACK* LocateIntrusion ( TRACK listStart,
TRACK aTrack,
LAYER_NUM  aLayer,
const wxPoint aRef 
)

Definition at line 534 of file editrack.cpp.

References BUSY, dist, TRACK::GetClearance(), BOARD_CONNECTED_ITEM::GetNetCode(), TRACK::GetWidth(), IS_DELETED, TRACK::Next(), PCB_TRACE_T, TestSegmentHit(), wxPoint::x, and wxPoint::y.

Referenced by PCB_EDIT_FRAME::GeneralControl(), and PushTrack().

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 }
static const int dist[10][10]
Definition: dist.cpp:57
#define BUSY
Pcbnew: flag indicating that the structure has.
Definition: base_struct.h:130
class TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:95
#define IS_DELETED
Definition: base_struct.h:112
virtual int GetClearance(BOARD_CONNECTED_ITEM *aItem=NULL) const override
Function GetClearance returns the clearance in internal units.
int GetNetCode() const
Function GetNetCode.
TRACK * Next() const
Definition: class_track.h:99
int GetWidth() const
Definition: class_track.h:116
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
static void PushTrack ( EDA_DRAW_PANEL panel)
static

Function PushTrack detects if the mouse is pointing into a conflicting track.

In this case, it tries to push the new track out of the conflicting track's clearance zone. This gives us a cheap mechanism for drawing tracks that tightly follow others, independent of grid settings.

KNOWN BUGS:

  • we do the same sort of search and calculation up to three times: 1) we search for magnetic hits (in controle.cpp) 2) we check if there's a DRC violation in the making (also controle.cpp) 3) we try to fix the DRC violation (here)
  • if we have a magnetic hit and a DRC violation at the same time, we choose the magnetic hit instead of solving the violation
  • should locate conflicting tracks also when we're crossing over them

Definition at line 592 of file editrack.cpp.

References dist, FindBestGridPointOnTrack(), g_CurrentTrackSegment, BOARD_ITEM::GetBoard(), TRACK::GetClearance(), EDA_DRAW_FRAME::GetCrossHairPosition(), TRACK::GetEnd(), BOARD_CONNECTED_ITEM::GetNetCode(), EDA_DRAW_PANEL::GetParent(), EDA_DRAW_FRAME::GetScreen(), TRACK::GetStart(), TRACK::GetWidth(), KiROUND(), LocateIntrusion(), PCB_SCREEN::m_Active_Layer, BOARD::m_Track, EDA_DRAW_FRAME::RefPos(), TRACK::SetEnd(), wxPoint::x, and wxPoint::y.

Referenced by ShowNewTrackWhenMovingCursor().

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 }
#define g_CurrentTrackSegment
most recently created segment
Definition: pcbnew.h:99
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
void SetEnd(const wxPoint &aEnd)
Definition: class_track.h:118
static const int dist[10][10]
Definition: dist.cpp:57
PCB_LAYER_ID m_Active_Layer
Definition: pcb_screen.h:44
const wxPoint & GetEnd() const
Definition: class_track.h:119
virtual BASE_SCREEN * GetScreen() const
Function GetScreen returns a pointer to a BASE_SCREEN or one of its derivatives.
Definition: draw_frame.h:361
const wxPoint & GetStart() const
Definition: class_track.h:122
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
virtual int GetClearance(BOARD_CONNECTED_ITEM *aItem=NULL) const override
Function GetClearance returns the clearance in internal units.
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.
wxPoint RefPos(bool useMouse) const
Function RefPos Return the reference position, coming from either the mouse position or the cursor po...
Class BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:169
int GetWidth() const
Definition: class_track.h:116
virtual BOARD * GetBoard() const
Function GetBoard returns the BOARD in which this BOARD_ITEM resides, or NULL if none.
DLIST< TRACK > m_Track
Definition: class_board.h:246
wxPoint GetCrossHairPosition(bool aInvertY=false) const
Function GetCrossHairPosition return the current cross hair position in logical (drawing) coordinates...
class PCB_BASE_FRAME basic PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer...
void ShowNewTrackWhenMovingCursor ( EDA_DRAW_PANEL aPanel,
wxDC *  aDC,
const wxPoint aPosition,
bool  aErase 
)

Definition at line 666 of file editrack.cpp.

References EDA_DRAW_FRAME::AppendMsgPanel(), BEGIN_ONPAD, PCB_BASE_FRAME::BuildAirWiresTargetsList(), CalculateSegmentEndPoint(), color, PCB_GENERAL_SETTINGS::Colors(), ComputeBreakPoint(), DARKCYAN, DBG, PCB_DISPLAY_OPTIONS::DO_NOT_SHOW_CLEARANCE, DrawTraces(), DrawViaCirclesWhenEditingNewTrack(), g_CurrentTrackList, g_CurrentTrackSegment, g_FirstTrackSegment, EDA_DRAW_PANEL::GetClipBox(), DHEAD::GetCount(), EDA_DRAW_FRAME::GetCrossHairPosition(), BOARD_DESIGN_SETTINGS::GetCurrentTrackWidth(), BOARD_DESIGN_SETTINGS::GetCurrentViaSize(), PCB_BASE_FRAME::GetDesignSettings(), PCB_BASE_FRAME::GetDisplayOptions(), COLORS_DESIGN_SETTINGS::GetLayerColor(), D_PAD::GetPadToDieLength(), EDA_DRAW_PANEL::GetParent(), EDA_DRAW_PANEL::GetScreen(), GR_XOR, EDA_DRAW_FRAME::LengthDoubleToString(), PCB_SCREEN::m_Active_Layer, PCB_GENERAL_SETTINGS::m_legacyDrcOn, PCB_GENERAL_SETTINGS::m_legacyUse45DegreeTracks, PCB_GENERAL_SETTINGS::m_legacyUseTwoSegmentTracks, BOARD_DESIGN_SETTINGS::m_UseConnectedTrackWidth, PCB_TRACE_T, PushTrack(), BOARD_ITEM::SetLayer(), EDA_DRAW_FRAME::SetMsgPanel(), PCB_BASE_FRAME::Settings(), TRACK::SetWidth(), PCB_DISPLAY_OPTIONS::SHOW_CLEARANCE_ALWAYS, PCB_DISPLAY_OPTIONS::SHOW_CLEARANCE_NEW_TRACKS_AND_VIA_AREAS, PCB_BASE_FRAME::TraceAirWiresToTargets(), and EDA_ITEM::Type().

Referenced by Abort_Create_Track(), PCB_EDIT_FRAME::Begin_Route(), PCB_EDIT_FRAME::Delete_Segment(), and PCB_EDIT_FRAME::End_Route().

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  {
766  COLOR4D color = frame->Settings().Colors().GetLayerColor(g_CurrentTrackSegment->GetLayer());
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 }
#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 SetLayer(PCB_LAYER_ID aLayer)
Function SetLayer sets the layer this item is on.
DLIST< TRACK > g_CurrentTrackList
Definition: pcbnew.cpp:89
int GetPadToDieLength() const
Definition: class_pad.h:408
int color
Definition: DXF_plotter.cpp:62
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
#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.
bool m_UseConnectedTrackWidth
if true, when creating a new track starting on an existing track, use this track width ...
class TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:95
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
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...
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
PCB_GENERAL_SETTINGS & Settings()
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.
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
COLORS_DESIGN_SETTINGS & Colors()
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
void DrawViaCirclesWhenEditingNewTrack(EDA_RECT *aPanelClipBox, wxDC *aDC, const wxPoint &aPos, int aViaRadius, int aViaRadiusWithClearence, COLOR4D aColor)
Definition: editrack.cpp:652
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
BASE_SCREEN * GetScreen()
Definition: draw_panel.cpp:193
COLOR4D GetLayerColor(LAYER_NUM aLayer) const
Function GetLayerColor.
unsigned GetCount() const
Function GetCount returns the number of elements in the list.
Definition: dlist.h:126
#define DBG(x)
Definition: fctsys.h:33
int GetCurrentTrackWidth() const
Function GetCurrentTrackWidth.
wxPoint GetCrossHairPosition(bool aInvertY=false) const
Function GetCrossHairPosition return the current cross hair position in logical (drawing) coordinates...
class PCB_BASE_FRAME basic PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer...
Class COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:39

Variable Documentation

PICKED_ITEMS_LIST s_ItemsListPicker
static

Definition at line 55 of file editrack.cpp.