PNS: Allow control of area-restricted drag optimization

CHANGED: The interactive router settings now include a switch to
         enable or disable optimization of the entire dragged track,
         which is now disabled by default.  When enabled, the router
         will reroute the entire track (from the dragged segment to
         the closest pad/via in each direction) to be more optimal.
         When disabled, only the area around the dragged segment
         will be modified.

CHANGED: The "optimizer effort" slider is removed from the interactive
         router settings dialog, as this setting did not have any
         meaningful impact in most cases and was a source of confusion.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/5918
This commit is contained in:
Jon Evans 2021-04-10 15:17:29 -04:00
parent 744e70df36
commit 94afdcb92a
7 changed files with 43 additions and 391 deletions

View File

@ -42,12 +42,11 @@ DIALOG_PNS_SETTINGS::DIALOG_PNS_SETTINGS( wxWindow* aParent, PNS::ROUTING_SETTIN
m_removeLoops->SetValue( m_settings.RemoveLoops() );
m_suggestEnding->SetValue( m_settings.SuggestFinish() );
m_smartPads->SetValue( m_settings.SmartPads() );
m_effort->SetValue( m_settings.OptimizerEffort() );
m_smoothDragged->SetValue( m_settings.SmoothDraggedSegments() );
m_violateDrc->SetValue( m_settings.GetAllowDRCViolationsSetting() );
m_freeAngleMode->SetValue( m_settings.GetFreeAngleMode() );
m_dragToolMode->SetSelection ( m_settings.InlineDragEnabled() ? 1 : 0 );
m_optimizeDraggedTrack->SetValue( m_settings.GetOptimizeDraggedTrack() );
m_optimizeEntireDraggedTrack->SetValue( m_settings.GetOptimizeEntireDraggedTrack() );
m_autoPosture->SetValue( m_settings.GetAutoPosture() );
m_fixAllSegments->SetValue( m_settings.GetFixAllSegments() );
@ -74,10 +73,9 @@ void DIALOG_PNS_SETTINGS::OnOkClick( wxCommandEvent& aEvent )
m_settings.SetRemoveLoops( m_removeLoops->GetValue() );
m_settings.SetSuggestFinish ( m_suggestEnding->GetValue() );
m_settings.SetSmartPads( m_smartPads->GetValue() );
m_settings.SetOptimizerEffort( (PNS::PNS_OPTIMIZATION_EFFORT) m_effort->GetValue() );
m_settings.SetSmoothDraggedSegments( m_smoothDragged->GetValue() );
m_settings.SetInlineDragEnabled( m_dragToolMode->GetSelection () ? true : false );
m_settings.SetOptimizeDraggedTrack( m_optimizeDraggedTrack->GetValue() );
m_settings.SetOptimizeEntireDraggedTrack( m_optimizeEntireDraggedTrack->GetValue() );
m_settings.SetAutoPosture( m_autoPosture->GetValue() );
m_settings.SetFixAllSegments( m_fixAllSegments->GetValue() );

View File

@ -83,8 +83,10 @@ DIALOG_PNS_SETTINGS_BASE::DIALOG_PNS_SETTINGS_BASE( wxWindow* parent, wxWindowID
bOptions->Add( m_suggestEnding, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
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_optimizeEntireDraggedTrack = new wxCheckBox( bOptions->GetStaticBox(), wxID_ANY, _("Optimize entire track being dragged"), wxDefaultPosition, wxDefaultSize, 0 );
m_optimizeEntireDraggedTrack->SetToolTip( _("When enabled, the entire track will be optimized and re-routed when dragged. When disabled, only the area near the segment being dragged will be optimized.") );
bOptions->Add( m_optimizeEntireDraggedTrack, 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") );
@ -96,53 +98,6 @@ DIALOG_PNS_SETTINGS_BASE::DIALOG_PNS_SETTINGS_BASE( wxWindow* parent, wxWindowID
bOptions->Add( m_fixAllSegments, 0, wxALL, 5 );
wxBoxSizer* bEffort;
bEffort = new wxBoxSizer( wxHORIZONTAL );
m_effortLabel = new wxStaticText( bOptions->GetStaticBox(), wxID_ANY, _("Optimizer effort:"), wxDefaultPosition, wxDefaultSize, 0 );
m_effortLabel->Wrap( -1 );
m_effortLabel->SetToolTip( _("Defines how much time the router shall spend optimizing the routed/shoved traces.\nMore effort means cleaner routing (but slower), less effort means faster routing but somewhat jagged traces.") );
bEffort->Add( m_effortLabel, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM, 20 );
bEffort->Add( 5, 0, 0, wxEXPAND, 5 );
wxBoxSizer* bSlider;
bSlider = new wxBoxSizer( wxVERTICAL );
m_effort = new wxSlider( bOptions->GetStaticBox(), wxID_ANY, 1, 0, 2, wxDefaultPosition, wxDefaultSize, wxSL_AUTOTICKS|wxSL_BOTTOM|wxSL_HORIZONTAL|wxSL_TOP );
m_effort->SetMinSize( wxSize( -1,28 ) );
bSlider->Add( m_effort, 1, wxEXPAND|wxTOP, 5 );
wxBoxSizer* bSliderLabels;
bSliderLabels = new wxBoxSizer( wxHORIZONTAL );
m_lowLabel = new wxStaticText( bOptions->GetStaticBox(), wxID_ANY, _("low"), wxDefaultPosition, wxDefaultSize, 0 );
m_lowLabel->Wrap( -1 );
m_lowLabel->SetFont( wxFont( 8, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxEmptyString ) );
bSliderLabels->Add( m_lowLabel, 0, 0, 5 );
bSliderLabels->Add( 0, 0, 1, wxEXPAND, 5 );
m_highLabel = new wxStaticText( bOptions->GetStaticBox(), wxID_ANY, _("high"), wxDefaultPosition, wxDefaultSize, 0 );
m_highLabel->Wrap( -1 );
m_highLabel->SetFont( wxFont( 8, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxEmptyString ) );
bSliderLabels->Add( m_highLabel, 0, 0, 5 );
bSlider->Add( bSliderLabels, 0, wxEXPAND|wxBOTTOM, 5 );
bEffort->Add( bSlider, 1, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 );
bOptions->Add( bEffort, 0, wxEXPAND|wxALL, 5 );
bMainSizer->Add( bOptions, 1, wxEXPAND|wxALL, 5 );

View File

@ -826,7 +826,7 @@
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Optimize track being dragged</property>
<property name="label">Optimize entire track being dragged</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
@ -834,7 +834,7 @@
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_optimizeDraggedTrack</property>
<property name="name">m_optimizeEntireDraggedTrack</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
@ -847,7 +847,7 @@
<property name="style"></property>
<property name="subclass"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="tooltip">When enabled, the entire track will be optimized and re-routed when dragged. When disabled, only the area near the segment being dragged will be optimized.</property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
@ -985,307 +985,6 @@
<property name="window_style"></property>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxALL</property>
<property name="proportion">0</property>
<object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property>
<property name="name">bEffort</property>
<property name="orient">wxHORIZONTAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="0">
<property name="border">20</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM</property>
<property name="proportion">0</property>
<object class="wxStaticText" expanded="0">
<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="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">Optimizer effort:</property>
<property name="markup">0</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_effortLabel</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"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip">Defines how much time the router shall spend optimizing the routed/shoved traces.&#x0A;More effort means cleaner routing (but slower), less effort means faster routing but somewhat jagged traces.</property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<property name="wrap">-1</property>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">0</property>
<object class="spacer" expanded="1">
<property name="height">0</property>
<property name="permission">protected</property>
<property name="width">5</property>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property>
<property name="proportion">1</property>
<object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property>
<property name="name">bSlider</property>
<property name="orient">wxVERTICAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxTOP</property>
<property name="proportion">1</property>
<object class="wxSlider" expanded="0">
<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="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="maxValue">2</property>
<property name="max_size"></property>
<property name="maximize_button">1</property>
<property name="maximum_size"></property>
<property name="minValue">0</property>
<property name="min_size">-1,-1</property>
<property name="minimize_button">0</property>
<property name="minimum_size">-1,28</property>
<property name="moveable">1</property>
<property name="name">m_effort</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">wxSL_AUTOTICKS|wxSL_BOTTOM|wxSL_HORIZONTAL|wxSL_TOP</property>
<property name="subclass"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></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="value">1</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|wxBOTTOM</property>
<property name="proportion">0</property>
<object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property>
<property name="name">bSliderLabels</property>
<property name="orient">wxHORIZONTAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag"></property>
<property name="proportion">0</property>
<object class="wxStaticText" expanded="0">
<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="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">,90,90,8,70,0</property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">low</property>
<property name="markup">0</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_lowLabel</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"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<property name="wrap">-1</property>
</object>
</object>
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">1</property>
<object class="spacer" expanded="0">
<property name="height">0</property>
<property name="permission">protected</property>
<property name="width">0</property>
</object>
</object>
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag"></property>
<property name="proportion">0</property>
<object class="wxStaticText" expanded="0">
<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="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">,90,90,8,70,0</property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">high</property>
<property name="markup">0</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_highLabel</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"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<property name="wrap">-1</property>
</object>
</object>
</object>
</object>
</object>
</object>
</object>
</object>
</object>
</object>
<object class="sizeritem" expanded="0">

View File

@ -21,7 +21,6 @@
#include <wx/choice.h>
#include <wx/sizer.h>
#include <wx/checkbox.h>
#include <wx/slider.h>
#include <wx/statbox.h>
#include <wx/button.h>
#include <wx/dialog.h>
@ -48,13 +47,9 @@ class DIALOG_PNS_SETTINGS_BASE : public DIALOG_SHIM
wxCheckBox* m_smoothDragged;
wxCheckBox* m_violateDrc;
wxCheckBox* m_suggestEnding;
wxCheckBox* m_optimizeDraggedTrack;
wxCheckBox* m_optimizeEntireDraggedTrack;
wxCheckBox* m_autoPosture;
wxCheckBox* m_fixAllSegments;
wxStaticText* m_effortLabel;
wxSlider* m_effort;
wxStaticText* m_lowLabel;
wxStaticText* m_highLabel;
wxStdDialogButtonSizer* m_stdButtons;
wxButton* m_stdButtonsOK;
wxButton* m_stdButtonsCancel;

View File

@ -392,34 +392,36 @@ void DRAGGER::optimizeAndUpdateDraggedLine( LINE& aDragged, const LINE& aOrig, c
lockV = aDragged.CLine().NearestPoint( aP );
if( Settings().GetOptimizeDraggedTrack() )
OPTIMIZER optimizer( m_lastNode );
int effort = OPTIMIZER::MERGE_SEGMENTS | OPTIMIZER::KEEP_TOPOLOGY;
if( !Settings().GetOptimizeEntireDraggedTrack() )
effort |= OPTIMIZER::RESTRICT_AREA;
optimizer.SetEffortLevel( effort );
OPT_BOX2I affectedArea = aDragged.ChangedArea( &aOrig );
VECTOR2I anchor( aP );
if( aDragged.CLine().Find( aP ) < 0 )
{
OPTIMIZER optimizer( m_lastNode );
anchor = aDragged.CLine().NearestPoint( aP );
}
optimizer.SetEffortLevel( OPTIMIZER::MERGE_SEGMENTS | OPTIMIZER::KEEP_TOPOLOGY );
optimizer.SetPreserveVertex( anchor );
OPT_BOX2I affectedArea = aDragged.ChangedArea( &aOrig );
VECTOR2I anchor( aP );
if( affectedArea )
{
Dbg()->AddPoint( anchor, 3 );
Dbg()->AddBox( *affectedArea, 2 );
optimizer.SetRestrictArea( *affectedArea );
optimizer.Optimize( &aDragged );
if( aDragged.CLine().Find( aP ) < 0 )
{
anchor = aDragged.CLine().NearestPoint( aP );
}
OPT_BOX2I optArea = aDragged.ChangedArea( &aOrig );
optimizer.SetPreserveVertex( anchor );
if( affectedArea )
{
Dbg()->AddPoint( anchor, 3 );
Dbg()->AddBox( *affectedArea, 2 );
optimizer.SetRestrictArea( *affectedArea );
optimizer.Optimize( &aDragged );
OPT_BOX2I optArea = aDragged.ChangedArea( &aOrig );
if( optArea )
Dbg()->AddBox( *optArea, 4 );
}
if( optArea )
Dbg()->AddBox( *optArea, 4 );
}
m_lastNode->Add( aDragged );
@ -547,6 +549,8 @@ bool DRAGGER::dragShove( const VECTOR2I& aP )
else
dragged.DragCorner( aP, m_draggedSegmentIndex );
Dbg()->AddLine( dragged.CLine(), 5, 10000 );
SHOVE::SHOVE_STATUS st = m_shove->ShoveLines( dragged );
if( st == SHOVE::SH_OK )

View File

@ -50,7 +50,7 @@ ROUTING_SETTINGS::ROUTING_SETTINGS( JSON_SETTINGS* aParent, const std::string& a
m_inlineDragEnabled = false;
m_snapToTracks = false;
m_snapToPads = false;
m_optimizeDraggedTrack = true;
m_optimizeEntireDraggedTrack = false;
m_cornerMode = CORNER_MODE::MITERED_45;
m_autoPosture = true;
m_fixAllSegments = true;
@ -90,7 +90,8 @@ ROUTING_SETTINGS::ROUTING_SETTINGS( JSON_SETTINGS* aParent, const std::string& a
m_params.emplace_back( new PARAM<bool>( "inline_drag", &m_inlineDragEnabled, false ) );
m_params.emplace_back( new PARAM<bool>( "snap_to_tracks", &m_snapToTracks, false ) );
m_params.emplace_back( new PARAM<bool>( "snap_to_pads", &m_snapToPads, false ) );
m_params.emplace_back( new PARAM<bool>( "optimize_dragged_track", &m_optimizeDraggedTrack, true ) );
m_params.emplace_back( new PARAM<bool>( "optimize_dragged_track",
&m_optimizeEntireDraggedTrack, false ) );
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 ) );

View File

@ -155,8 +155,8 @@ public:
CORNER_MODE GetCornerMode() const { return m_cornerMode; }
void SetCornerMode( CORNER_MODE aMode ) { m_cornerMode = aMode; }
bool GetOptimizeDraggedTrack() const { return m_optimizeDraggedTrack; }
void SetOptimizeDraggedTrack( bool aEnable ) { m_optimizeDraggedTrack = aEnable; }
bool GetOptimizeEntireDraggedTrack() const { return m_optimizeEntireDraggedTrack; }
void SetOptimizeEntireDraggedTrack( bool aEnable ) { m_optimizeEntireDraggedTrack = aEnable; }
bool GetAutoPosture() const { return m_autoPosture; }
void SetAutoPosture( bool aEnable ) { m_autoPosture = aEnable; }
@ -178,7 +178,7 @@ private:
bool m_inlineDragEnabled;
bool m_snapToTracks;
bool m_snapToPads;
bool m_optimizeDraggedTrack;
bool m_optimizeEntireDraggedTrack;
bool m_autoPosture;
bool m_fixAllSegments;