PNS: Add support for 90-degree corner modes
Fixes https://gitlab.com/kicad/code/kicad/-/issues/6902
This commit is contained in:
parent
e4b61de792
commit
64f77b3596
|
@ -59,6 +59,18 @@ public:
|
|||
UNDEFINED = -1
|
||||
};
|
||||
|
||||
/**
|
||||
* Corner modes.
|
||||
* A corner can either be 45° or 90° and can be fillet/rounded or mitered
|
||||
*/
|
||||
enum CORNER_MODE
|
||||
{
|
||||
MITERED_45 = 0, ///< H/V/45 with mitered corners (default)
|
||||
ROUNDED_45 = 1, ///< H/V/45 with filleted corners
|
||||
MITERED_90 = 2, ///< H/V only (90-degree corners)
|
||||
ROUNDED_90 = 3, ///< H/V with filleted corners
|
||||
};
|
||||
|
||||
/**
|
||||
* Represent kind of angle formed by vectors heading in two DIRECTION_45s.
|
||||
*/
|
||||
|
@ -215,12 +227,13 @@ public:
|
|||
* @param aP0 starting point
|
||||
* @param aP1 ending point
|
||||
* @param aStartDiagonal whether the first segment has to be diagonal
|
||||
* @param aFillet if true will fillet the 45-degree portion of the line chain
|
||||
* @param aMode How the corner is made. If it is a 90° corner, aStartDiagonal means
|
||||
* start with the shorter direction first / use arc before the straight segment.
|
||||
* @return the trace
|
||||
*/
|
||||
const SHAPE_LINE_CHAIN BuildInitialTrace( const VECTOR2I& aP0, const VECTOR2I& aP1,
|
||||
bool aStartDiagonal = false,
|
||||
bool aFillet = false ) const;
|
||||
bool aStartDiagonal = false,
|
||||
CORNER_MODE aMode = CORNER_MODE::MITERED_45 ) const;
|
||||
|
||||
bool operator==( const DIRECTION_45& aOther ) const
|
||||
{
|
||||
|
@ -295,7 +308,6 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Calculate the direction from a vector. If the vector's angle is not a multiple of 45
|
||||
* degrees, the direction is rounded to the nearest octant.
|
||||
|
|
|
@ -21,7 +21,9 @@
|
|||
|
||||
|
||||
const SHAPE_LINE_CHAIN DIRECTION_45::BuildInitialTrace( const VECTOR2I& aP0, const VECTOR2I& aP1,
|
||||
bool aStartDiagonal, bool aFillet ) const
|
||||
bool aStartDiagonal,
|
||||
CORNER_MODE aMode ) const
|
||||
|
||||
{
|
||||
bool startDiagonal;
|
||||
|
||||
|
@ -35,70 +37,94 @@ const SHAPE_LINE_CHAIN DIRECTION_45::BuildInitialTrace( const VECTOR2I& aP0, con
|
|||
int sw = sign( aP1.x - aP0.x );
|
||||
int sh = sign( aP1.y - aP0.y );
|
||||
|
||||
VECTOR2I mp0, mp1;
|
||||
|
||||
/*
|
||||
* Non-filleted case:
|
||||
*
|
||||
* For width greater than height, we're calculating something like this.
|
||||
* mp0 will be used if we start straight; mp1 if we start diagonal.
|
||||
*
|
||||
* aP0 ----------------- mp0
|
||||
* . \
|
||||
* . \
|
||||
* . \
|
||||
* mp1 . . . . . . . . aP1
|
||||
*
|
||||
* Filleted case:
|
||||
*
|
||||
* For a fillet, we need to know the arc start point (A in the diagram below)
|
||||
* A straight segment will be needed between aP0 and A if we are starting straight,
|
||||
* or between the arc end and aP1 if we are starting diagonally.
|
||||
*
|
||||
* aP0 -- A --___ mp0
|
||||
* . ---
|
||||
* . --
|
||||
* . --
|
||||
* mp1 . . . . . . . . aP1
|
||||
*
|
||||
* For the length of this segment (tangentLength), we subtract the length of the "diagonal"
|
||||
* line from the "straight" line (i.e. dist(aP0, mp0) - dist(mp0, aP1))
|
||||
* In the example above, we will have a straight segment from aP0 to A, and then we can use
|
||||
* the distance from A to aP1 (diagLength) to calculate the radius of the arc.
|
||||
*/
|
||||
|
||||
int tangentLength;
|
||||
|
||||
if( w > h )
|
||||
{
|
||||
mp0 = VECTOR2I( ( w - h ) * sw, 0 ); // direction: E
|
||||
mp1 = VECTOR2I( h * sw, h * sh ); // direction: NE
|
||||
tangentLength = ( w - h ) - mp1.EuclideanNorm();
|
||||
}
|
||||
else
|
||||
{
|
||||
mp0 = VECTOR2I( 0, sh * ( h - w ) ); // direction: N
|
||||
mp1 = VECTOR2I( sw * w, sh * w ); // direction: NE
|
||||
tangentLength = ( h - w ) - mp1.EuclideanNorm();
|
||||
}
|
||||
|
||||
bool is90mode = aMode == CORNER_MODE::ROUNDED_90 || aMode == CORNER_MODE::MITERED_90;
|
||||
SHAPE_LINE_CHAIN pl;
|
||||
|
||||
// Shortcut where we can generate just one segment and quit. Avoids more complicated handling
|
||||
// of precision errors if filleting is enabled
|
||||
// TODO: needs refactoring if we support 90-degree arcs via this function
|
||||
if( w == h || w == 0 || h == 0 )
|
||||
if( w == 0 || h == 0 || ( !is90mode && h == w ) )
|
||||
{
|
||||
pl.Append( aP0 );
|
||||
pl.Append( aP1 );
|
||||
return pl;
|
||||
}
|
||||
|
||||
// TODO: if tangentLength zero, we could still place a small arc at the start...
|
||||
if( aFillet )
|
||||
VECTOR2I mp0, mp1;
|
||||
int tangentLength;
|
||||
|
||||
if( is90mode )
|
||||
{
|
||||
SHAPE_ARC arc;
|
||||
VECTOR2I arcEndpoint;
|
||||
if( startDiagonal == ( h >= w ) )
|
||||
{
|
||||
mp0 = VECTOR2I( w * sw, 0 ); // direction: E
|
||||
}
|
||||
else
|
||||
{
|
||||
mp0 = VECTOR2I( 0, sh * h ); // direction: N
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( w > h )
|
||||
{
|
||||
mp0 = VECTOR2I( ( w - h ) * sw, 0 ); // direction: E
|
||||
mp1 = VECTOR2I( h * sw, h * sh ); // direction: NE
|
||||
tangentLength = ( w - h ) - mp1.EuclideanNorm();
|
||||
}
|
||||
else
|
||||
{
|
||||
mp0 = VECTOR2I( 0, sh * ( h - w ) ); // direction: N
|
||||
mp1 = VECTOR2I( sw * w, sh * w ); // direction: NE
|
||||
tangentLength = ( h - w ) - mp1.EuclideanNorm();
|
||||
}
|
||||
}
|
||||
|
||||
SHAPE_ARC arc;
|
||||
VECTOR2I arcEndpoint;
|
||||
|
||||
switch( aMode )
|
||||
{
|
||||
case CORNER_MODE::MITERED_45:
|
||||
/*
|
||||
* For width greater than height, we're calculating something like this.
|
||||
* mp0 will be used if we start straight; mp1 if we start diagonal.
|
||||
*
|
||||
* aP0 ----------------- mp0
|
||||
* . \
|
||||
* . \
|
||||
* . \
|
||||
* mp1 . . . . . . . . aP1
|
||||
*
|
||||
*/
|
||||
pl.Append( aP0 );
|
||||
pl.Append( startDiagonal ? ( aP0 + mp1 ) : ( aP0 + mp0 ) );
|
||||
pl.Append( aP1 );
|
||||
break;
|
||||
|
||||
case CORNER_MODE::ROUNDED_45:
|
||||
{
|
||||
/*
|
||||
* For a fillet, we need to know the arc start point (A in the diagram below)
|
||||
* A straight segment will be needed between aP0 and A if we are starting straight,
|
||||
* or between the arc end and aP1 if we are starting diagonally.
|
||||
*
|
||||
* aP0 -- A --___ mp0
|
||||
* . ---
|
||||
* . --
|
||||
* . --
|
||||
* mp1 . . . . . . . . aP1
|
||||
*
|
||||
* For the length of this segment (tangentLength), we subtract the length of the "diagonal"
|
||||
* line from the "straight" line (i.e. dist(aP0, mp0) - dist(mp0, aP1))
|
||||
* In the example above, we will have a straight segment from aP0 to A, and then we can use
|
||||
* the distance from A to aP1 (diagLength) to calculate the radius of the arc.
|
||||
*/
|
||||
if( w == h )
|
||||
{
|
||||
pl.Append( aP0 );
|
||||
pl.Append( aP1 );
|
||||
break;
|
||||
}
|
||||
|
||||
double diag2 = tangentLength >= 0 ? mp1.SquaredEuclideanNorm() : mp0.SquaredEuclideanNorm();
|
||||
double diagLength = std::sqrt( ( 2 * diag2 ) - ( 2 * diag2 * std::cos( 3 * M_PI_4 ) ) );
|
||||
|
@ -188,12 +214,94 @@ const SHAPE_LINE_CHAIN DIRECTION_45::BuildInitialTrace( const VECTOR2I& aP0, con
|
|||
pl.Append( aP1 );
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
case CORNER_MODE::MITERED_90:
|
||||
/*
|
||||
* For width greater than height, we're calculating something like this.
|
||||
*
|
||||
* <-mp0->
|
||||
* aP0 -------------------+
|
||||
* |
|
||||
* |
|
||||
* |
|
||||
* aP1
|
||||
*/
|
||||
pl.Append( aP0 );
|
||||
pl.Append( startDiagonal ? ( aP0 + mp1 ) : ( aP0 + mp0 ) );
|
||||
pl.Append( aP0 + mp0 );
|
||||
pl.Append( aP1 );
|
||||
break;
|
||||
|
||||
case CORNER_MODE::ROUNDED_90:
|
||||
/*
|
||||
* For a fillet, we need to know the arc end point
|
||||
* A straight segment will be needed between aP0 and arcEnd in case distance aP0,mp0 is bigger
|
||||
* than the distance mp0,aP1, if the distance is shorter the straigth segment is between
|
||||
* arcEnd and aP1. If both distances are equal, we don't need a straight segment.
|
||||
*
|
||||
* aP0 ----- arcEnd ---__
|
||||
* --
|
||||
* \
|
||||
* |
|
||||
* arcCenter aP1
|
||||
*
|
||||
* For the length of the radius we use the shorter of the horizontal and vertical distance.
|
||||
*/
|
||||
SHAPE_ARC arc;
|
||||
|
||||
if( w == h ) // we only need one arc without a straigth line.
|
||||
{
|
||||
arc.ConstructFromStartEndCenter( aP0, aP1, aP1 - mp0, sh == sw != startDiagonal );
|
||||
pl.Append( arc );
|
||||
return pl;
|
||||
}
|
||||
|
||||
VECTOR2I arcEnd; // Arc position that is not at aP0 nor aP1
|
||||
VECTOR2I arcCenter;
|
||||
|
||||
if( startDiagonal ) //Means start with the arc first
|
||||
{
|
||||
if( h > w ) // Arc followed by a vertical line
|
||||
{
|
||||
int y = aP0.y + ( w * sh );
|
||||
arcEnd = VECTOR2I( aP1.x, y );
|
||||
arcCenter = VECTOR2I( aP0.x, y );
|
||||
arc.ConstructFromStartEndCenter( aP0, arcEnd, arcCenter, sh != sw );
|
||||
pl.Append( arc );
|
||||
pl.Append( aP1 );
|
||||
}
|
||||
else // Arc followed by a horizontal line
|
||||
{
|
||||
int x = aP0.x + ( h * sw );
|
||||
arcEnd = VECTOR2I( x, aP1.y );
|
||||
arcCenter = VECTOR2I( x, aP0.y );
|
||||
arc.ConstructFromStartEndCenter( aP0, arcEnd, arcCenter, sh == sw );
|
||||
pl.Append( arc );
|
||||
pl.Append( aP1 );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( w > h ) // Horizontal line followed by the arc
|
||||
{
|
||||
int x = aP1.x - ( h * sw );
|
||||
arcEnd = VECTOR2I( x, aP0.y );
|
||||
arcCenter = VECTOR2I( x, aP1.y );
|
||||
pl.Append( aP0 );
|
||||
arc.ConstructFromStartEndCenter( arcEnd, aP1, arcCenter, sh != sw );
|
||||
pl.Append( arc );
|
||||
}
|
||||
else // Vertical line followed by the arc
|
||||
{
|
||||
int y = aP1.y - ( w * sh );
|
||||
arcEnd = VECTOR2I( aP0.x, y );
|
||||
arcCenter = VECTOR2I( aP1.x, y );
|
||||
pl.Append( aP0 );
|
||||
arc.ConstructFromStartEndCenter( arcEnd, aP1, arcCenter, sh == sw );
|
||||
pl.Append( arc );
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
pl.Simplify();
|
||||
|
|
|
@ -1656,8 +1656,10 @@ bool LINE_PLACER::buildInitialLine( const VECTOR2I& aP, LINE& aHead, bool aForce
|
|||
wxLogTrace( "PNS", "buildInitialLine: m_direction %s, guessedDir %s, tail points %d",
|
||||
m_direction.Format(), guessedDir.Format(), m_tail.PointCount() );
|
||||
|
||||
DIRECTION_45::CORNER_MODE cornerMode = Settings().GetCornerMode();
|
||||
// Rounded corners don't make sense when routing orthogonally (single track at a time)
|
||||
bool fillet = !m_orthoMode && Settings().GetCornerMode() == CORNER_MODE::ROUNDED_45;
|
||||
if( m_orthoMode )
|
||||
cornerMode = DIRECTION_45::CORNER_MODE::MITERED_45;
|
||||
|
||||
if( m_p_start == aP )
|
||||
{
|
||||
|
@ -1672,9 +1674,9 @@ bool LINE_PLACER::buildInitialLine( const VECTOR2I& aP, LINE& aHead, bool aForce
|
|||
else
|
||||
{
|
||||
if( !m_tail.PointCount() )
|
||||
l = guessedDir.BuildInitialTrace( m_p_start, aP, false, fillet );
|
||||
l = guessedDir.BuildInitialTrace( m_p_start, aP, false, cornerMode );
|
||||
else
|
||||
l = m_direction.BuildInitialTrace( m_p_start, aP, false, fillet );
|
||||
l = m_direction.BuildInitialTrace( m_p_start, aP, false, cornerMode );
|
||||
}
|
||||
|
||||
if( l.SegmentCount() > 1 && m_orthoMode )
|
||||
|
@ -1708,8 +1710,8 @@ bool LINE_PLACER::buildInitialLine( const VECTOR2I& aP, LINE& aHead, bool aForce
|
|||
|
||||
if( v.PushoutForce( m_currentNode, lead, force, solidsOnly, 40 ) )
|
||||
{
|
||||
SHAPE_LINE_CHAIN line = guessedDir.BuildInitialTrace( m_p_start, aP + force, false,
|
||||
fillet );
|
||||
SHAPE_LINE_CHAIN line =
|
||||
guessedDir.BuildInitialTrace( m_p_start, aP + force, false, cornerMode );
|
||||
aHead = LINE( aHead, line );
|
||||
|
||||
v.SetPos( v.Pos() + force );
|
||||
|
|
|
@ -111,7 +111,7 @@ DIRECTION_45 MOUSE_TRAIL_TRACER::GetPosture( const VECTOR2I& aP )
|
|||
DEBUG_DECORATOR* dbg = ROUTER::GetInstance()->GetInterface()->GetDebugDecorator();
|
||||
VECTOR2I p0 = m_trail.CPoint( 0 );
|
||||
double refLength = SEG( p0, aP ).Length();
|
||||
SHAPE_LINE_CHAIN straight( DIRECTION_45().BuildInitialTrace( p0, aP, false, false ) );
|
||||
SHAPE_LINE_CHAIN straight( DIRECTION_45().BuildInitialTrace( p0, aP, false ) );
|
||||
|
||||
straight.SetClosed( true );
|
||||
straight.Append( m_trail.Reverse() );
|
||||
|
@ -121,7 +121,7 @@ DIRECTION_45 MOUSE_TRAIL_TRACER::GetPosture( const VECTOR2I& aP )
|
|||
|
||||
double areaS = straight.Area();
|
||||
|
||||
SHAPE_LINE_CHAIN diag( DIRECTION_45().BuildInitialTrace( p0, aP, true, false ) );
|
||||
SHAPE_LINE_CHAIN diag( DIRECTION_45().BuildInitialTrace( p0, aP, true ) );
|
||||
diag.Append( m_trail.Reverse() );
|
||||
diag.SetClosed( true );
|
||||
diag.Simplify();
|
||||
|
|
|
@ -586,10 +586,8 @@ bool OPTIMIZER::mergeColinear( LINE* aLine )
|
|||
if( s1.SquaredLength() == 0 || s2.SquaredLength() == 0 )
|
||||
continue;
|
||||
|
||||
if( s1.Collinear( s2 ) )
|
||||
if( s1.Collinear( s2 ) && !line.IsPtOnArc( segIdx + 1 ) )
|
||||
{
|
||||
// We should not see a collinear vertex inside an arc
|
||||
wxASSERT( !line.IsPtOnArc( segIdx + 1 ) );
|
||||
line.Remove( segIdx + 1 );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -813,21 +813,19 @@ bool ROUTER::IsPlacingVia() const
|
|||
}
|
||||
|
||||
|
||||
void ROUTER::ToggleRounded()
|
||||
void ROUTER::ToggleCornerMode()
|
||||
{
|
||||
CORNER_MODE newMode = CORNER_MODE::MITERED_45;
|
||||
DIRECTION_45::CORNER_MODE mode = m_settings->GetCornerMode();
|
||||
|
||||
switch( m_settings->GetCornerMode() )
|
||||
{
|
||||
case CORNER_MODE::MITERED_45:
|
||||
newMode = CORNER_MODE::ROUNDED_45;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
case DIRECTION_45::CORNER_MODE::MITERED_45: mode = DIRECTION_45::CORNER_MODE::ROUNDED_45; break;
|
||||
case DIRECTION_45::CORNER_MODE::ROUNDED_45: mode = DIRECTION_45::CORNER_MODE::MITERED_90; break;
|
||||
case DIRECTION_45::CORNER_MODE::MITERED_90: mode = DIRECTION_45::CORNER_MODE::ROUNDED_90; break;
|
||||
case DIRECTION_45::CORNER_MODE::ROUNDED_90: mode = DIRECTION_45::CORNER_MODE::MITERED_45; break;
|
||||
}
|
||||
|
||||
m_settings->SetCornerMode( newMode );
|
||||
m_settings->SetCornerMode( mode );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -160,7 +160,7 @@ public:
|
|||
void ToggleViaPlacement();
|
||||
void SetOrthoMode( bool aEnable );
|
||||
|
||||
void ToggleRounded();
|
||||
void ToggleCornerMode();
|
||||
|
||||
int GetCurrentLayer() const;
|
||||
const std::vector<int> GetCurrentNets() const;
|
||||
|
|
|
@ -50,7 +50,7 @@ ROUTING_SETTINGS::ROUTING_SETTINGS( JSON_SETTINGS* aParent, const std::string& a
|
|||
m_snapToTracks = false;
|
||||
m_snapToPads = false;
|
||||
m_optimizeEntireDraggedTrack = false;
|
||||
m_cornerMode = CORNER_MODE::MITERED_45;
|
||||
m_cornerMode = DIRECTION_45::CORNER_MODE::MITERED_45;
|
||||
m_walkaroundHugLengthThreshold = 1.5;
|
||||
m_autoPosture = true;
|
||||
m_fixAllSegments = true;
|
||||
|
@ -95,9 +95,9 @@ ROUTING_SETTINGS::ROUTING_SETTINGS( JSON_SETTINGS* aParent, const std::string& a
|
|||
m_params.emplace_back( new PARAM<bool>( "auto_posture", &m_autoPosture, true ) );
|
||||
m_params.emplace_back( new PARAM<bool>( "fix_all_segments", &m_fixAllSegments, true ) );
|
||||
|
||||
m_params.emplace_back( new PARAM_ENUM<CORNER_MODE>( "corner_mode", &m_cornerMode,
|
||||
CORNER_MODE::MITERED_45, CORNER_MODE::ROUNDED_90,
|
||||
CORNER_MODE::MITERED_45 ) );
|
||||
m_params.emplace_back( new PARAM_ENUM<DIRECTION_45::CORNER_MODE>(
|
||||
"corner_mode", &m_cornerMode, DIRECTION_45::CORNER_MODE::MITERED_45,
|
||||
DIRECTION_45::CORNER_MODE::ROUNDED_90, DIRECTION_45::CORNER_MODE::MITERED_45 ) );
|
||||
|
||||
m_params.emplace_back( new PARAM<double>( "walkaround_hug_length_threshold", &m_walkaroundHugLengthThreshold, 1.5 ) );
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include <cstdio>
|
||||
|
||||
#include <settings/nested_settings.h>
|
||||
#include <geometry/direction45.h>
|
||||
|
||||
#include "time_limit.h"
|
||||
|
||||
|
@ -51,15 +52,6 @@ enum PNS_OPTIMIZATION_EFFORT
|
|||
OE_FULL = 2
|
||||
};
|
||||
|
||||
///< What kind of corners to create in the line placers.
|
||||
enum class CORNER_MODE
|
||||
{
|
||||
MITERED_90, ///< H/V only (90-degree corners) (not yet implemented)
|
||||
MITERED_45, ///< H/V/45 with mitered corners (default)
|
||||
ROUNDED_90, ///< H/V with filleted corners (not yet implemented)
|
||||
ROUNDED_45 ///< H/V/45 with filleted corners
|
||||
};
|
||||
|
||||
/**
|
||||
* Contain all persistent settings of the router, such as the mode, optimization effort, etc.
|
||||
*/
|
||||
|
@ -149,8 +141,8 @@ public:
|
|||
bool GetSnapToTracks() const { return m_snapToTracks; }
|
||||
bool GetSnapToPads() const { return m_snapToPads; }
|
||||
|
||||
CORNER_MODE GetCornerMode() const { return m_cornerMode; }
|
||||
void SetCornerMode( CORNER_MODE aMode ) { m_cornerMode = aMode; }
|
||||
DIRECTION_45::CORNER_MODE GetCornerMode() const { return m_cornerMode; }
|
||||
void SetCornerMode( DIRECTION_45::CORNER_MODE aMode ) { m_cornerMode = aMode; }
|
||||
|
||||
bool GetOptimizeEntireDraggedTrack() const { return m_optimizeEntireDraggedTrack; }
|
||||
void SetOptimizeEntireDraggedTrack( bool aEnable ) { m_optimizeEntireDraggedTrack = aEnable; }
|
||||
|
@ -180,7 +172,7 @@ private:
|
|||
bool m_autoPosture;
|
||||
bool m_fixAllSegments;
|
||||
|
||||
CORNER_MODE m_cornerMode;
|
||||
DIRECTION_45::CORNER_MODE m_cornerMode;
|
||||
|
||||
PNS_MODE m_routingMode;
|
||||
PNS_OPTIMIZATION_EFFORT m_optimizerEffort;
|
||||
|
|
|
@ -157,11 +157,11 @@ static const TOOL_ACTION ACT_SwitchPosture( "pcbnew.InteractiveRouter.SwitchPost
|
|||
_( "Switches posture of the currently routed track." ),
|
||||
BITMAPS::change_entry_orient );
|
||||
|
||||
static const TOOL_ACTION ACT_SwitchRounding( "pcbnew.InteractiveRouter.SwitchRounding",
|
||||
static const TOOL_ACTION ACT_SwitchCornerMode( "pcbnew.InteractiveRouter.SwitchRounding",
|
||||
AS_CONTEXT,
|
||||
MD_CTRL + '/', "",
|
||||
_( "Track Corner Mode" ),
|
||||
_( "Switches between sharp and rounded corners when routing tracks." ),
|
||||
_( "Switches between sharp/rounded and 45°/90° corners when routing tracks." ),
|
||||
BITMAPS::switch_corner_rounding_shape );
|
||||
|
||||
#undef _
|
||||
|
@ -469,7 +469,7 @@ bool ROUTER_TOOL::Init()
|
|||
menu.AddItem( ACT_SelLayerAndPlaceBlindVia, SELECTION_CONDITIONS::ShowAlways );
|
||||
menu.AddItem( ACT_SelLayerAndPlaceMicroVia, SELECTION_CONDITIONS::ShowAlways );
|
||||
menu.AddItem( ACT_SwitchPosture, SELECTION_CONDITIONS::ShowAlways );
|
||||
menu.AddItem( ACT_SwitchRounding, SELECTION_CONDITIONS::ShowAlways );
|
||||
menu.AddItem( ACT_SwitchCornerMode, SELECTION_CONDITIONS::ShowAlways );
|
||||
|
||||
menu.AddSeparator();
|
||||
|
||||
|
@ -1202,9 +1202,9 @@ void ROUTER_TOOL::performRouting()
|
|||
m_router->Move( m_endSnapPoint, m_endItem );
|
||||
m_startItem = nullptr;
|
||||
}
|
||||
else if( evt->IsAction( &ACT_SwitchRounding ) )
|
||||
else if( evt->IsAction( &ACT_SwitchCornerMode ) )
|
||||
{
|
||||
m_router->ToggleRounded();
|
||||
m_router->ToggleCornerMode();
|
||||
updateMessagePanel();
|
||||
updateEndItem( *evt );
|
||||
m_router->Move( m_endSnapPoint, m_endItem ); // refresh
|
||||
|
@ -2063,10 +2063,10 @@ void ROUTER_TOOL::updateMessagePanel()
|
|||
{
|
||||
switch( m_router->Settings().GetCornerMode() )
|
||||
{
|
||||
case PNS::CORNER_MODE::MITERED_45: cornerMode = _( "45-degree" ); break;
|
||||
case PNS::CORNER_MODE::ROUNDED_45: cornerMode = _( "45-degree rounded" ); break;
|
||||
case PNS::CORNER_MODE::MITERED_90: cornerMode = _( "90-degree" ); break;
|
||||
case PNS::CORNER_MODE::ROUNDED_90: cornerMode = _( "90-degree rounded" ); break;
|
||||
case DIRECTION_45::CORNER_MODE::MITERED_45: cornerMode = _( "45-degree" ); break;
|
||||
case DIRECTION_45::CORNER_MODE::ROUNDED_45: cornerMode = _( "45-degree rounded" ); break;
|
||||
case DIRECTION_45::CORNER_MODE::MITERED_90: cornerMode = _( "90-degree" ); break;
|
||||
case DIRECTION_45::CORNER_MODE::ROUNDED_90: cornerMode = _( "90-degree rounded" ); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -79,7 +79,8 @@ bool PNS_LOG_FILE::Load( const std::string& logName, const std::string boardName
|
|||
m_routerSettings->SetMode( (PNS::PNS_MODE) wxAtoi( tokens.GetNextToken() ) );
|
||||
m_routerSettings->SetRemoveLoops( wxAtoi( tokens.GetNextToken() ) );
|
||||
m_routerSettings->SetFixAllSegments( wxAtoi( tokens.GetNextToken() ) );
|
||||
m_routerSettings->SetCornerMode( (PNS::CORNER_MODE) wxAtoi( tokens.GetNextToken() ) );
|
||||
m_routerSettings->SetCornerMode(
|
||||
(DIRECTION_45::CORNER_MODE) wxAtoi( tokens.GetNextToken() ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue