Teardrops: handle arcs in tracks.
Fixes #13858 https://gitlab.com/kicad/code/kicad/issues/13858
This commit is contained in:
parent
30a49462fe
commit
3a11d90d92
|
@ -2,7 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2021 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||
* Copyright (C) 2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -117,7 +117,7 @@ int TEARDROP_MANAGER::SetTeardrops( BOARD_COMMIT* aCommitter, bool aFollowTracks
|
|||
// Build the track list (only straight lines)
|
||||
for( PCB_TRACK* track: m_board->Tracks() )
|
||||
{
|
||||
if( track->Type() == PCB_TRACE_T )
|
||||
if( track->Type() == PCB_TRACE_T || track->Type() == PCB_ARC_T)
|
||||
{
|
||||
int netcode = track->GetNetCode();
|
||||
int layer = track->GetLayer();
|
||||
|
@ -132,7 +132,7 @@ int TEARDROP_MANAGER::SetTeardrops( BOARD_COMMIT* aCommitter, bool aFollowTracks
|
|||
|
||||
for( PCB_TRACK* track : m_board->Tracks() )
|
||||
{
|
||||
if( track->Type() != PCB_TRACE_T )
|
||||
if( ! (track->Type() == PCB_TRACE_T || track->Type() == PCB_ARC_T ) )
|
||||
continue;
|
||||
|
||||
// Search for a padvia connected to track, with one end inside and one end outside
|
||||
|
@ -284,7 +284,7 @@ int TEARDROP_MANAGER::addTeardropsOnTracks( BOARD_COMMIT* aCommitter )
|
|||
// Build the track list (only straight lines)
|
||||
for( PCB_TRACK* track: m_board->Tracks() )
|
||||
{
|
||||
if( track->Type() == PCB_TRACE_T )
|
||||
if( track->Type() == PCB_TRACE_T || track->Type() == PCB_ARC_T )
|
||||
{
|
||||
int netcode = track->GetNetCode();
|
||||
int layer = track->GetLayer();
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2021 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||
* Copyright (C) 2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -183,7 +183,7 @@ private:
|
|||
/**
|
||||
* Compute the 2 points on pad/via of the teardrop shape
|
||||
* @return false if these 2 points are not found
|
||||
* @param aTrack is the reference track included in teardrop
|
||||
* @param aLayer is the layer for the teardrop
|
||||
* @param aViaPad is the teardrop anchor
|
||||
* teardrop height = aViaPad size * aHeightRatio
|
||||
* @param aPts is the buffer that contains initial and final teardrop polygonal shape
|
||||
|
@ -194,7 +194,7 @@ private:
|
|||
* m_heightRatio is the factor to calculate the aViaPad teardrop size
|
||||
*/
|
||||
bool ComputePointsOnPadVia( TEARDROP_PARAMETERS* aCurrParams,
|
||||
PCB_TRACK* aTrack, VIAPAD& aViaPad,
|
||||
PCB_LAYER_ID aLayer, VIAPAD& aViaPad,
|
||||
std::vector<VECTOR2I>& aPts ) const;
|
||||
|
||||
/**
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2021 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||
* Copyright (C) 2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -401,7 +401,7 @@ void TEARDROP_MANAGER::computeCurvedForRectShape( TEARDROP_PARAMETERS* aCurrPar
|
|||
|
||||
|
||||
bool TEARDROP_MANAGER::ComputePointsOnPadVia( TEARDROP_PARAMETERS* aCurrParams,
|
||||
PCB_TRACK* aTrack,
|
||||
PCB_LAYER_ID aLayer,
|
||||
VIAPAD& aViaPad,
|
||||
std::vector<VECTOR2I>& aPts ) const
|
||||
{
|
||||
|
@ -441,7 +441,7 @@ bool TEARDROP_MANAGER::ComputePointsOnPadVia( TEARDROP_PARAMETERS* aCurrParams,
|
|||
force_clip_shape = true;
|
||||
|
||||
preferred_height = aViaPad.m_Width * aCurrParams->m_HeightRatio;
|
||||
pad->TransformShapeToPolygon( c_buffer, aTrack->GetLayer(), 0, ARC_LOW_DEF, ERROR_INSIDE );
|
||||
pad->TransformShapeToPolygon( c_buffer, aLayer, 0, ARC_LOW_DEF, ERROR_INSIDE );
|
||||
}
|
||||
|
||||
// Clip the pad/via shape to match the m_TdMaxHeight constraint, and for
|
||||
|
@ -593,8 +593,8 @@ bool TEARDROP_MANAGER::findAnchorPointsOnTrack( TEARDROP_PARAMETERS* aCurrParams
|
|||
TRACK_BUFFER& aTrackLookupList ) const
|
||||
{
|
||||
bool found = true;
|
||||
VECTOR2I start = aTrack->GetStart();
|
||||
VECTOR2I end = aTrack->GetEnd();
|
||||
VECTOR2I start = aTrack->GetStart(); // the anchor point on the track, inside teardrop
|
||||
VECTOR2I end = aTrack->GetEnd(); // the anchor point on the track, outside teardrop
|
||||
int radius = aViaPad.m_Width / 2;
|
||||
|
||||
// Requested length of the teardrop:
|
||||
|
@ -604,11 +604,13 @@ bool TEARDROP_MANAGER::findAnchorPointsOnTrack( TEARDROP_PARAMETERS* aCurrParams
|
|||
targetLength = std::min( aCurrParams->m_TdMaxLen, targetLength );
|
||||
|
||||
int actualTdLen; // The actual teardrop length, limited by the available track length
|
||||
bool need_swap = false; // true if the start and end points of the current track are swapped
|
||||
|
||||
// ensure that start is at the via/pad end
|
||||
if( SEG( end, aViaPad.m_Pos ).Length() < radius )
|
||||
{
|
||||
std::swap( start, end );
|
||||
need_swap = true;
|
||||
}
|
||||
|
||||
SHAPE_POLY_SET shapebuffer;
|
||||
|
@ -639,9 +641,10 @@ bool TEARDROP_MANAGER::findAnchorPointsOnTrack( TEARDROP_PARAMETERS* aCurrParams
|
|||
return false;
|
||||
|
||||
VECTOR2I intersect = pts[0].p;
|
||||
start.x = intersect.x;
|
||||
start.y = intersect.y;
|
||||
start = intersect;
|
||||
|
||||
actualTdLen = std::min( targetLength, SEG( start, end ).Length() );
|
||||
VECTOR2I ref_lenght_point = start; // the reference point of actualTdLen
|
||||
|
||||
// If the first track is too short to allow a teardrop having the requested length
|
||||
// explore the connected track(s)
|
||||
|
@ -664,17 +667,78 @@ bool TEARDROP_MANAGER::findAnchorPointsOnTrack( TEARDROP_PARAMETERS* aCurrParams
|
|||
aTrack = connected_track;
|
||||
end = connected_track->GetEnd();
|
||||
start = connected_track->GetStart();
|
||||
need_swap = false;
|
||||
|
||||
if( matchType != STARTPOINT )
|
||||
{
|
||||
std::swap( start, end );
|
||||
need_swap = true;
|
||||
}
|
||||
|
||||
// If we do not want to explore more than one connected track, stop search here
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if aTrack is an arc, find the best teardrop end point on the arc
|
||||
// It is currently on the segment from arc start point to arc end point,
|
||||
// therefore not really on the arc, because we have used only the track end points.
|
||||
if( aTrack->Type() == PCB_ARC_T )
|
||||
{
|
||||
// To find the best start and end points to build the teardrop shape, we convert
|
||||
// the arc to segments, and search for the segment havig its start point at a dist
|
||||
// < actualTdLen, and its end point at adist > actualTdLen:
|
||||
SHAPE_ARC arc( aTrack->GetStart(), static_cast<PCB_ARC*>( aTrack )->GetMid(),
|
||||
aTrack->GetEnd(), aTrack->GetWidth() );
|
||||
|
||||
if( need_swap )
|
||||
arc.Reverse();
|
||||
|
||||
SHAPE_LINE_CHAIN poly = arc.ConvertToPolyline();
|
||||
|
||||
// Now, find the segment of the arc at a distance < actualTdLen from ref_lenght_point.
|
||||
// We just search for the first segment (starting from the farest segment) with its
|
||||
// start point at a distance < actualTdLen dist
|
||||
// This is basic, but it is probably enough.
|
||||
if( poly.PointCount() > 2 )
|
||||
{
|
||||
// Note: the first point is inside or near the pad/via shape
|
||||
// The last point is outside and the farest from the ref_lenght_point
|
||||
// So we explore segments from the last to the first
|
||||
for( int ii = poly.PointCount()-1; ii >= 0 ; ii-- )
|
||||
{
|
||||
int dist_from_start = ( poly.CPoint( ii ) - ref_lenght_point ).EuclideanNorm();
|
||||
|
||||
// The first segment at a distance of the reference point < actualTdLen is OK
|
||||
if( dist_from_start < actualTdLen )
|
||||
{
|
||||
start = poly.CPoint( ii );
|
||||
|
||||
if( ii < poly.PointCount()-1 )
|
||||
end = poly.CPoint( ii+1 );
|
||||
|
||||
// actualTdLen is the distance between start (the segment start point)
|
||||
// and the point on track of the teardrop.
|
||||
// This is the difference between the initial actualTdLen value and the
|
||||
// distance between start and ref_lenght_point.
|
||||
actualTdLen -= (start - ref_lenght_point).EuclideanNorm();
|
||||
|
||||
if( actualTdLen < 0 )
|
||||
actualTdLen = 0;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// aStartPoint and aEndPoint will define later a segment to build the 2 anchors points
|
||||
// of the teardrop on the aTrack shape.
|
||||
// they are the end point of aTrack if aTrack is a segment,
|
||||
// or a small segment on aTrack if aTrack is an ARC
|
||||
aStartPoint = start;
|
||||
aEndPoint = end;
|
||||
|
||||
*aEffectiveTeardropLen = actualTdLen;
|
||||
return found;
|
||||
}
|
||||
|
@ -733,7 +797,7 @@ bool TEARDROP_MANAGER::computeTeardropPolygonPoints( TEARDROP_PARAMETERS* aCurrP
|
|||
VECTOR2I pointC, pointE; // Point on PADVIA outlines
|
||||
std::vector<VECTOR2I> pts = {pointA, pointB, pointC, pointD, pointE};
|
||||
|
||||
ComputePointsOnPadVia( aCurrParams, aTrack, aViaPad, pts );
|
||||
ComputePointsOnPadVia( aCurrParams, aTrack->GetLayer(), aViaPad, pts );
|
||||
|
||||
if( !aCurrParams->IsCurved() )
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue