PNS: Add a setting to disable posture solver
PNS: Prevent autoposture flutter when trail has little area Fixes https://gitlab.com/kicad/code/kicad/-/issues/6797
This commit is contained in:
parent
eb1f07bade
commit
8c247fc97c
|
@ -48,6 +48,8 @@ DIALOG_PNS_SETTINGS::DIALOG_PNS_SETTINGS( wxWindow* aParent, PNS::ROUTING_SETTIN
|
|||
m_freeAngleMode->SetValue( m_settings.GetFreeAngleMode() );
|
||||
m_dragToolMode->SetSelection ( m_settings.InlineDragEnabled() ? 1 : 0 );
|
||||
m_optimizeDraggedTrack->SetValue( m_settings.GetOptimizeDraggedTrack() );
|
||||
m_autoPosture->SetValue( m_settings.GetAutoPosture() );
|
||||
|
||||
// Enable/disable some options
|
||||
wxCommandEvent event;
|
||||
onModeChange( event );
|
||||
|
@ -75,6 +77,7 @@ void DIALOG_PNS_SETTINGS::OnOkClick( wxCommandEvent& aEvent )
|
|||
m_settings.SetSmoothDraggedSegments( m_smoothDragged->GetValue() );
|
||||
m_settings.SetInlineDragEnabled( m_dragToolMode->GetSelection () ? true : false );
|
||||
m_settings.SetOptimizeDraggedTrack( m_optimizeDraggedTrack->GetValue() );
|
||||
m_settings.SetAutoPosture( m_autoPosture->GetValue() );
|
||||
|
||||
if( m_mode->GetSelection() == PNS::RM_MarkObstacles )
|
||||
{
|
||||
|
|
|
@ -86,6 +86,11 @@ DIALOG_PNS_SETTINGS_BASE::DIALOG_PNS_SETTINGS_BASE( wxWindow* parent, wxWindowID
|
|||
m_optimizeDraggedTrack = new wxCheckBox( bOptions->GetStaticBox(), wxID_ANY, _("Optimize track being dragged"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
bOptions->Add( m_optimizeDraggedTrack, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
|
||||
|
||||
m_autoPosture = new wxCheckBox( bOptions->GetStaticBox(), wxID_ANY, _("Use mouse path to set track posture"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_autoPosture->SetToolTip( _("When enabled, the posture of tracks will be guided by how the mouse is moved from the starting location") );
|
||||
|
||||
bOptions->Add( m_autoPosture, 0, wxALL, 5 );
|
||||
|
||||
wxBoxSizer* bEffort;
|
||||
bEffort = new wxBoxSizer( wxHORIZONTAL );
|
||||
|
||||
|
|
|
@ -857,6 +857,70 @@
|
|||
<property name="window_style"></property>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALL</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxCheckBox" expanded="1">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer"></property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="checked">0</property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="default_pane">0</property>
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
<property name="font"></property>
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">Use mouse path to set track posture</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="min_size"></property>
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_autoPosture</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pin_button">1</property>
|
||||
<property name="pos"></property>
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="style"></property>
|
||||
<property name="subclass">; ; forward_declare</property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip">When enabled, the posture of tracks will be guided by how the mouse is moved from the starting location</property>
|
||||
<property name="validator_data_type"></property>
|
||||
<property name="validator_style">wxFILTER_NONE</property>
|
||||
<property name="validator_type">wxDefaultValidator</property>
|
||||
<property name="validator_variable"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND|wxALL</property>
|
||||
|
|
|
@ -49,6 +49,7 @@ class DIALOG_PNS_SETTINGS_BASE : public DIALOG_SHIM
|
|||
wxCheckBox* m_violateDrc;
|
||||
wxCheckBox* m_suggestEnding;
|
||||
wxCheckBox* m_optimizeDraggedTrack;
|
||||
wxCheckBox* m_autoPosture;
|
||||
wxStaticText* m_effortLabel;
|
||||
wxSlider* m_effort;
|
||||
wxStaticText* m_lowLabel;
|
||||
|
|
|
@ -1408,7 +1408,7 @@ bool LINE_PLACER::buildInitialLine( const VECTOR2I& aP, LINE& aHead )
|
|||
initial_radius = Settings().GetMaxRadius();
|
||||
|
||||
|
||||
if( !m_tail.PointCount() )
|
||||
if( !m_tail.PointCount() && Settings().GetAutoPosture() )
|
||||
l = guessedDir.BuildInitialTrace( m_p_start, aP, false, initial_radius );
|
||||
else
|
||||
l = m_direction.BuildInitialTrace( m_p_start, aP, false, initial_radius );
|
||||
|
@ -1571,8 +1571,17 @@ void POSTURE_SOLVER::AddTrailPoint( const VECTOR2I& aP )
|
|||
|
||||
DIRECTION_45 POSTURE_SOLVER::GetPosture( const VECTOR2I& aP )
|
||||
{
|
||||
// Tuning factor for how good the "fit" of the trail must be to the posture
|
||||
const double areaRatioThreshold = 1.5;
|
||||
|
||||
// Tuning factor to minimize flutter
|
||||
const double areaRatioEpsilon = 0.3;
|
||||
|
||||
// Minimum distance factor of the trail before the min area test is used to lock the solver
|
||||
const double minAreaCutoffDistanceFactor = 6;
|
||||
|
||||
// Adjusts how far away from p0 we get before whatever posture we solved is locked in
|
||||
const int lockDistanceFactor = 40;
|
||||
const int lockDistanceFactor = 25;
|
||||
|
||||
// Adjusts how close to p0 we unlock the posture again if one was locked already
|
||||
const int unlockDistanceFactor = 4;
|
||||
|
@ -1589,17 +1598,19 @@ DIRECTION_45 POSTURE_SOLVER::GetPosture( const VECTOR2I& aP )
|
|||
SHAPE_LINE_CHAIN straight( DIRECTION_45().BuildInitialTrace( p0, aP, false ) );
|
||||
straight.SetClosed( true );
|
||||
straight.Append( m_trail.Reverse() );
|
||||
straight.Simplify();
|
||||
dbg->AddLine( straight, m_forced ? 3 : 2, 100000 );
|
||||
|
||||
double areaS = straight.Area();
|
||||
double areaS = std::abs( straight.Area() );
|
||||
|
||||
SHAPE_LINE_CHAIN diag( DIRECTION_45().BuildInitialTrace( p0, aP, true ) );
|
||||
diag.Append( m_trail.Reverse() );
|
||||
diag.SetClosed( true );
|
||||
diag.Simplify();
|
||||
dbg->AddLine( diag, 1, 100000 );
|
||||
|
||||
double areaDiag = diag.Area();
|
||||
double ratio = abs( areaS ) / ( fabs( areaDiag ) + 1.0 );
|
||||
double areaDiag = std::abs( diag.Area() );
|
||||
double ratio = areaS / ( areaDiag + 1.0 );
|
||||
|
||||
// heuristic to detect that the user dragged back the cursor to the beginning of the trace
|
||||
// in this case, we cancel any forced posture and restart the trail
|
||||
|
@ -1611,15 +1622,29 @@ DIRECTION_45 POSTURE_SOLVER::GetPosture( const VECTOR2I& aP )
|
|||
m_trail.Append( start );
|
||||
}
|
||||
|
||||
bool areaOk = true;
|
||||
|
||||
// Check the actual trail area against the cutoff. This prevents flutter when the trail is
|
||||
// very close to a straight line.
|
||||
if( !m_forced && refLength > minAreaCutoffDistanceFactor * m_tolerance )
|
||||
{
|
||||
double areaCutoff = m_tolerance * refLength;
|
||||
SHAPE_LINE_CHAIN trail( m_trail );
|
||||
trail.SetClosed( true );
|
||||
|
||||
if( std::abs( trail.Area() ) < areaCutoff )
|
||||
areaOk = false;
|
||||
}
|
||||
|
||||
// If we get far away from the initial point, lock in the current solution to prevent flutter
|
||||
if( !m_forced && refLength > lockDistanceFactor * m_tolerance )
|
||||
m_forced = true;
|
||||
|
||||
if( m_forced )
|
||||
return m_direction;
|
||||
else if( ratio > areaRatioThreshold + areaRatioEpsilon )
|
||||
else if( areaOk && ratio > areaRatioThreshold + areaRatioEpsilon )
|
||||
m_direction = DIRECTION_45::NE;
|
||||
else if( ratio < ( 1.0 / areaRatioThreshold ) - areaRatioEpsilon )
|
||||
else if( areaOk && ratio < ( 1.0 / areaRatioThreshold ) - areaRatioEpsilon )
|
||||
m_direction = DIRECTION_45::N;
|
||||
else if( m_lastSegDirection != DIRECTION_45::UNDEFINED )
|
||||
m_direction = m_lastSegDirection;
|
||||
|
@ -1634,6 +1659,5 @@ void POSTURE_SOLVER::FlipPosture()
|
|||
m_forced = true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -94,9 +94,6 @@ public:
|
|||
void FlipPosture();
|
||||
|
||||
private:
|
||||
const double areaRatioThreshold = 1.5;
|
||||
const double areaRatioEpsilon = 0.2;
|
||||
|
||||
SHAPE_LINE_CHAIN m_trail;
|
||||
int m_tolerance;
|
||||
DIRECTION_45 m_direction;
|
||||
|
|
|
@ -54,6 +54,7 @@ ROUTING_SETTINGS::ROUTING_SETTINGS( JSON_SETTINGS* aParent, const std::string& a
|
|||
m_minRadius = 0;
|
||||
m_maxRadius = 1000000;
|
||||
m_roundedCorners = false;
|
||||
m_autoPosture = true;
|
||||
|
||||
m_params.emplace_back( new PARAM<int>( "mode", reinterpret_cast<int*>( &m_routingMode ),
|
||||
static_cast<int>( RM_Walkaround ) ) );
|
||||
|
@ -95,6 +96,7 @@ ROUTING_SETTINGS::ROUTING_SETTINGS( JSON_SETTINGS* aParent, const std::string& a
|
|||
m_params.emplace_back( new PARAM<int>( "min_radius", &m_minRadius, 0 ) );
|
||||
m_params.emplace_back( new PARAM<int>( "max_radius", &m_maxRadius, 1000000 ) );
|
||||
m_params.emplace_back( new PARAM<bool>( "use_rounded", &m_roundedCorners, false ) );
|
||||
m_params.emplace_back( new PARAM<bool>( "auto_posture", &m_autoPosture, true ) );
|
||||
|
||||
LoadFromFile();
|
||||
}
|
||||
|
|
|
@ -147,6 +147,9 @@ public:
|
|||
bool GetOptimizeDraggedTrack() const { return m_optimizeDraggedTrack; }
|
||||
void SetOptimizeDraggedTrack( bool aEnable ) { m_optimizeDraggedTrack = aEnable; }
|
||||
|
||||
bool GetAutoPosture() const { return m_autoPosture; }
|
||||
void SetAutoPosture( bool aEnable ) { m_autoPosture = aEnable; }
|
||||
|
||||
void SetMinRadius( int aRadius )
|
||||
{
|
||||
m_minRadius = aRadius;
|
||||
|
@ -182,6 +185,7 @@ private:
|
|||
bool m_snapToPads;
|
||||
bool m_roundedCorners;
|
||||
bool m_optimizeDraggedTrack;
|
||||
bool m_autoPosture;
|
||||
|
||||
int m_minRadius;
|
||||
int m_maxRadius;
|
||||
|
|
Loading…
Reference in New Issue