@ -3466,11 +3466,21 @@ int DRAWING_TOOL::DrawVia( const TOOL_EVENT& aEvent )
{
}
PCB_TRACK * findTrack ( PCB_VIA * aVia )
/**
* Get the bounding box the via would have if placed at the given position
* ( the via ' s bounding box is relative to its own position ) .
*/
static BOX2I getEffectiveBoundingBox ( const PCB_VIA & aVia , const VECTOR2I & aPosition )
{
const LSET lset = aVia - > GetLayerSet ( ) ;
VECTOR2I position = aVia - > GetPosition ( ) ;
BOX2I bbox = aVia - > GetBoundingBox ( ) ;
BOX2I bbox = aVia . GetBoundingBox ( ) ;
bbox . Move ( aPosition - aVia . GetPosition ( ) ) ;
return bbox ;
}
PCB_TRACK * findTrack ( const PCB_VIA * aVia , const VECTOR2I & aPosition ) const
{
const LSET lset = aVia - > GetLayerSet ( ) ;
const BOX2I bbox = getEffectiveBoundingBox ( * aVia , aPosition ) ;
std : : vector < KIGFX : : VIEW : : LAYER_ITEM_PAIR > items ;
KIGFX : : PCB_VIEW * view = m_frame - > GetCanvas ( ) - > GetView ( ) ;
@ -3494,9 +3504,8 @@ int DRAWING_TOOL::DrawVia( const TOOL_EVENT& aEvent )
{
PCB_TRACK * track = static_cast < PCB_TRACK * > ( item ) ;
if ( TestSegmentHit ( position , track - > GetStart ( ) , track - > GetEnd ( ) ,
( track - > GetWidth ( )
+ aVia - > GetWidth ( track - > GetLayer ( ) ) ) / 2 ) )
if ( TestSegmentHit ( aPosition , track - > GetStart ( ) , track - > GetEnd ( ) ,
( track - > GetWidth ( ) + aVia - > GetWidth ( track - > GetLayer ( ) ) ) / 2 ) )
{
possible_tracks . push_back ( track ) ;
}
@ -3505,7 +3514,7 @@ int DRAWING_TOOL::DrawVia( const TOOL_EVENT& aEvent )
{
PCB_ARC * arc = static_cast < PCB_ARC * > ( item ) ;
if ( arc - > HitTest ( p osition, aVia - > GetWidth ( arc - > GetLayer ( ) ) / 2 ) )
if ( arc - > HitTest ( aP osition, aVia - > GetWidth ( arc - > GetLayer ( ) ) / 2 ) )
possible_tracks . push_back ( arc ) ;
}
}
@ -3516,7 +3525,7 @@ int DRAWING_TOOL::DrawVia( const TOOL_EVENT& aEvent )
for ( PCB_TRACK * track : possible_tracks )
{
SEG test ( track - > GetStart ( ) , track - > GetEnd ( ) ) ;
int dist = ( test . NearestPoint ( position ) - p osition ) . EuclideanNorm ( ) ;
int dist = ( test . NearestPoint ( aPosition ) - aP osition ) . EuclideanNorm ( ) ;
if ( dist < min_d )
{
@ -3657,11 +3666,10 @@ int DRAWING_TOOL::DrawVia( const TOOL_EVENT& aEvent )
return false ;
}
PAD * findPad ( PCB_VIA * aVia )
PAD * findPad ( const PCB_VIA * aVia , const VECTOR2I & aPosition ) const
{
const VECTOR2I position = aVia - > GetPosition ( ) ;
const LSET lset = aVia - > GetLayerSet ( ) ;
const BOX2I bbox = aVia - > GetBoundingBox ( ) ;
const LSET lset = aVia - > GetLayerSet ( ) ;
const BOX2I bbox = getEffectiveBoundingBox ( * aVia , aPosition ) ;
const KIGFX : : PCB_VIEW & view = * m_frame - > GetCanvas ( ) - > GetView ( ) ;
std : : vector < KIGFX : : VIEW : : LAYER_ITEM_PAIR > items ;
@ -3679,7 +3687,7 @@ int DRAWING_TOOL::DrawVia( const TOOL_EVENT& aEvent )
{
PAD & pad = static_cast < PAD & > ( item ) ;
if ( pad . HitTest ( p osition ) )
if ( pad . HitTest ( aP osition ) )
{
return & pad ;
}
@ -3689,11 +3697,10 @@ int DRAWING_TOOL::DrawVia( const TOOL_EVENT& aEvent )
return nullptr ;
}
PCB_SHAPE * findGraphic ( const PCB_VIA * aVia ) const
PCB_SHAPE * findGraphic ( const PCB_VIA * aVia , const VECTOR2I & aPosition ) const
{
const LSET lset = aVia - > GetLayerSet ( ) & LSET : : AllCuMask ( ) ;
VECTOR2I position = aVia - > GetPosition ( ) ;
BOX2I bbox = aVia - > GetBoundingBox ( ) ;
BOX2I bbox = getEffectiveBoundingBox ( * aVia , aPosition ) ;
std : : vector < KIGFX : : VIEW : : LAYER_ITEM_PAIR > items ;
KIGFX : : PCB_VIEW * view = m_frame - > GetCanvas ( ) - > GetView ( ) ;
@ -3716,7 +3723,7 @@ int DRAWING_TOOL::DrawVia( const TOOL_EVENT& aEvent )
{
PCB_SHAPE * shape = static_cast < PCB_SHAPE * > ( item ) ;
if ( shape - > HitTest ( p osition, aVia - > GetWidth ( activeLayer ) / 2 ) )
if ( shape - > HitTest ( aP osition, aVia - > GetWidth ( activeLayer ) / 2 ) )
possible_shapes . push_back ( shape ) ;
}
}
@ -3726,7 +3733,7 @@ int DRAWING_TOOL::DrawVia( const TOOL_EVENT& aEvent )
for ( PCB_SHAPE * shape : possible_shapes )
{
int dist = ( shape - > GetPosition ( ) - p osition ) . EuclideanNorm ( ) ;
int dist = ( shape - > GetPosition ( ) - aP osition ) . EuclideanNorm ( ) ;
if ( dist < min_d )
{
@ -3877,11 +3884,16 @@ int DRAWING_TOOL::DrawVia( const TOOL_EVENT& aEvent )
MAGNETIC_SETTINGS * settings = m_frame - > GetMagneticItemsSettings ( ) ;
PCB_VIA * via = static_cast < PCB_VIA * > ( aItem ) ;
VECTOR2I position = via - > GetPosition ( ) ;
// When snapping, use the mouse position, not the item position, which may be
// grid-snapped, so that we can get the cursor within snap-range of snap points.
// If we don't get a snap, the via will be left as it is (i.e. maybe grid-snapped).
KIGFX : : VIEW_CONTROLS & viewControls = * m_frame - > GetCanvas ( ) - > GetViewControls ( ) ;
const VECTOR2I position = viewControls . GetMousePosition ( ) ;
if ( settings - > tracks ! = MAGNETIC_OPTIONS : : NO_EFFECT & & m_gridHelper . GetSnap ( ) )
{
if ( PCB_TRACK * track = findTrack ( via ) )
if ( PCB_TRACK * track = findTrack ( via , position ) )
{
SEG trackSeg ( track - > GetStart ( ) , track - > GetEnd ( ) ) ;
VECTOR2I snap = m_gridHelper . AlignToSegment ( position , trackSeg ) ;
@ -3893,7 +3905,7 @@ int DRAWING_TOOL::DrawVia( const TOOL_EVENT& aEvent )
if ( settings - > pads ! = MAGNETIC_OPTIONS : : NO_EFFECT & & m_gridHelper . GetSnap ( ) )
{
if ( PAD * pad = findPad ( via ) )
if ( PAD * pad = findPad ( via , position ) )
{
aItem - > SetPosition ( pad - > GetPosition ( ) ) ;
return ;
@ -3902,7 +3914,7 @@ int DRAWING_TOOL::DrawVia( const TOOL_EVENT& aEvent )
if ( settings - > graphics & & m_gridHelper . GetSnap ( ) )
{
if ( PCB_SHAPE * shape = findGraphic ( via ) )
if ( PCB_SHAPE * shape = findGraphic ( via , position ) )
{
if ( shape - > IsAnyFill ( ) )
{
@ -3988,8 +4000,8 @@ int DRAWING_TOOL::DrawVia( const TOOL_EVENT& aEvent )
WX_INFOBAR * infobar = m_frame - > GetInfoBar ( ) ;
PCB_VIA * via = static_cast < PCB_VIA * > ( aItem ) ;
VECTOR2I viaPos = via - > GetPosition ( ) ;
PCB_TRACK * track = findTrack ( via ) ;
PAD * pad = findPad ( via ) ;
PCB_TRACK * track = findTrack ( via , via - > GetPosition ( ) ) ;
PAD * pad = findPad ( via , via - > GetPosition ( ) ) ;
if ( track )
{