Manager teardrops on arcs. From master branch.
This commit is contained in:
parent
36978d2ddc
commit
c5caa23a63
|
@ -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();
|
||||
|
@ -426,9 +426,6 @@ int TEARDROP_MANAGER::RemoveTeardrops( BOARD_COMMIT* aCommitter, bool aCommitAft
|
|||
|
||||
if( count )
|
||||
{
|
||||
ZONE_FILLER filler( m_board, aCommitter );
|
||||
(void)filler.Fill( m_board->Zones() );
|
||||
|
||||
if( aCommitter && aCommitAfterRemove )
|
||||
aCommitter->Push( _( "Remove teardrops" ), SKIP_CONNECTIVITY );
|
||||
|
||||
|
|
|
@ -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(); // one reference point on the track, inside teardrop
|
||||
VECTOR2I end = aTrack->GetEnd(); // the second reference point on the track, outside teardrop
|
||||
int radius = aViaPad.m_Width / 2;
|
||||
|
||||
// Requested length of the teardrop:
|
||||
|
@ -603,12 +603,15 @@ bool TEARDROP_MANAGER::findAnchorPointsOnTrack( TEARDROP_PARAMETERS* aCurrParams
|
|||
if( aCurrParams->m_TdMaxLen > 0 )
|
||||
targetLength = std::min( aCurrParams->m_TdMaxLen, targetLength );
|
||||
|
||||
int actualTdLen; // The actual teardrop length, limited by the available track length
|
||||
// actualTdLen is the distance between start and the teardrop point on the segment from start to end
|
||||
int actualTdLen;
|
||||
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;
|
||||
|
@ -634,17 +637,20 @@ bool TEARDROP_MANAGER::findAnchorPointsOnTrack( TEARDROP_PARAMETERS* aCurrParams
|
|||
int pt_count = outline.Intersect( SEG( start, end ), pts );
|
||||
|
||||
// Ensure a intersection point was found, otherwise we cannot built the teardrop
|
||||
// using this track
|
||||
// using this track (it is fully outside or inside the pad/via shape)
|
||||
if( pt_count < 1 )
|
||||
return false;
|
||||
|
||||
VECTOR2I intersect = pts[0].p;
|
||||
start.x = intersect.x;
|
||||
start.y = intersect.y;
|
||||
start = intersect; // This is currently the reference point of the teardrop lenght
|
||||
|
||||
// actualTdLen for now the distance between start and the teardrop point on the (start end)segment
|
||||
// It cannot be bigger than the lenght of this segment
|
||||
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)
|
||||
// explore the connected track(s), and try to find a anchor point at targetLength from initial start
|
||||
if( actualTdLen < targetLength && aFollowTracks )
|
||||
{
|
||||
int consumed = 0;
|
||||
|
@ -660,21 +666,87 @@ bool TEARDROP_MANAGER::findAnchorPointsOnTrack( TEARDROP_PARAMETERS* aCurrParams
|
|||
|
||||
// TODO: stop if angle between old and new segment is > 45 deg to avoid bad shape
|
||||
consumed += actualTdLen;
|
||||
// actualTdLen is the new distance from new start point and the teardrop anchor point
|
||||
actualTdLen = std::min( targetLength-consumed, int( connected_track->GetLength() ) );
|
||||
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 ) - start ).EuclideanNorm();
|
||||
|
||||
// The first segment at a distance of the reference point < actualTdLen is OK
|
||||
// and is suitable to define the reference segment of the teardrop anchor.
|
||||
if( dist_from_start < actualTdLen || ii == 0 )
|
||||
{
|
||||
start = poly.CPoint( ii );
|
||||
|
||||
if( ii < poly.PointCount()-1 )
|
||||
end = poly.CPoint( ii+1 );
|
||||
|
||||
// actualTdLen is the distance between start (the reference 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();
|
||||
|
||||
// Ensure validity of actualTdLen: >= 0, and <= segment lenght
|
||||
if( actualTdLen < 0 ) // should not happen, but...
|
||||
actualTdLen = 0;
|
||||
|
||||
actualTdLen = std::min( actualTdLen, (end - start).EuclideanNorm() );
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// aStartPoint and aEndPoint will define later a segment to build the 2 anchors points
|
||||
// of the teardrop on the aTrack shape.
|
||||
// they are two points (both outside the pad/via shape) 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 +805,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