Pcbnew: fix teardrop generation for pads having different shapes by layer.

Teardrop generator used pad::HitTest not testing the hit of a specific layer.
It created false test for some complex pads. Now use a test specific to a layer.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/21560
This commit is contained in:
jean-pierre charras 2025-08-27 11:03:00 +02:00
parent 2f21414186
commit 963aa47778
4 changed files with 23 additions and 4 deletions

View File

@ -1473,6 +1473,20 @@ void PAD::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>&
}
bool PAD::HitTest( const VECTOR2I& aPosition, int aAccuracy, PCB_LAYER_ID aLayer ) const
{
VECTOR2I delta = aPosition - GetPosition();
int boundingRadius = GetBoundingRadius() + aAccuracy;
if( delta.SquaredEuclideanNorm() > SEG::Square( boundingRadius ) )
return false;
bool contains = GetEffectivePolygon( aLayer, ERROR_INSIDE )->Contains( aPosition, -1, aAccuracy );
return contains;
}
bool PAD::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
{
VECTOR2I delta = aPosition - GetPosition();

View File

@ -823,6 +823,11 @@ public:
bool HitTest( const BOX2I& aRect, bool aContained, int aAccuracy = 0 ) const override;
bool HitTest( const SHAPE_LINE_CHAIN& aPoly, bool aContained ) const override;
/**
* return true if hit test on the specified layer
*/
bool HitTest( const VECTOR2I& aPosition, int aAccuracy, PCB_LAYER_ID aLayer ) const;
/**
* Recombines the pad with other graphical shapes in the footprint
*

View File

@ -275,8 +275,8 @@ void TEARDROP_MANAGER::UpdateTeardrops( BOARD_COMMIT& aCommit,
continue;
}
bool startHitsPad = pad->HitTest( track->GetStart() );
bool endHitsPad = pad->HitTest( track->GetEnd() );
bool startHitsPad = pad->HitTest( track->GetStart(), 0, track->GetLayer() );
bool endHitsPad = pad->HitTest( track->GetEnd(), 0, track->GetLayer() );
// The track is entirely inside the pad; cannot create a teardrop
if( startHitsPad && endHitsPad )

View File

@ -724,10 +724,10 @@ bool TEARDROP_MANAGER::computeTeardropPolygon( const TEARDROP_PARAMETERS& aParam
{
PAD* pad = static_cast<PAD*>( aOther );
if( pad->HitTest( pointA ) )
if( pad->HitTest( pointA, 0, layer ) )
return false;
if( pad->HitTest( pointB ) )
if( pad->HitTest( pointB, 0, layer ) )
return false;
}