PNS: Fix visible area restriction

VIEW::GetBoundary() returns the entire view area, not the visible area.
Surprisingly, we had no API for this, so I added one.

Also, changed the dragger behavior to toggle between optimizing just the
modified area and optimizing the visible area, i.e. we will now never
optimize off-screen portions of the dragged track.
This commit is contained in:
Jon Evans 2021-04-10 16:13:01 -04:00
parent f13eb13b9a
commit 7784d7cb12
7 changed files with 43 additions and 20 deletions

View File

@ -212,6 +212,21 @@ void GAL::ComputeWorldScreenMatrix()
}
BOX2D GAL::GetVisibleWorldExtents() const
{
const MATRIX3x3D& matrix = GetScreenWorldMatrix();
VECTOR2D halfSize = VECTOR2D( matrix.GetScale().x * m_screenSize.x * 0.5,
matrix.GetScale().y * m_screenSize.y * 0.5 );
BOX2D extents;
extents.SetOrigin( GetLookAtPoint() - halfSize );
extents.SetSize( halfSize * 2 );
return extents;
}
double GAL::computeMinGridSpacing() const
{
// just return the current value. This could be cleverer and take

View File

@ -606,6 +606,11 @@ public:
m_worldScreenMatrix = aMatrix;
}
/**
* @return the bounding box of the world that is displayed on screen at the moment
*/
BOX2D GetVisibleWorldExtents() const;
/**
* Set the unit length.
*

View File

@ -84,7 +84,7 @@ DIALOG_PNS_SETTINGS_BASE::DIALOG_PNS_SETTINGS_BASE( wxWindow* parent, wxWindowID
bOptions->Add( m_suggestEnding, 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.") );
m_optimizeEntireDraggedTrack->SetToolTip( _("When enabled, the entire portion of the track that is visible on the screen will be optimized and re-routed when a segment is dragged. When disabled, only the area near the segment being dragged will be optimized.") );
bOptions->Add( m_optimizeEntireDraggedTrack, 0, wxTOP|wxRIGHT|wxLEFT, 5 );

View File

@ -847,7 +847,7 @@
<property name="style"></property>
<property name="subclass"></property>
<property name="toolbar_pane">0</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="tooltip">When enabled, the entire portion of the track that is visible on the screen will be optimized and re-routed when a segment is 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>

View File

@ -38,7 +38,6 @@ LOGGER* ALGO_BASE::Logger()
const BOX2I& ALGO_BASE::VisibleViewArea() const
{
auto bb = m_router->VisibleViewArea();
return m_router->VisibleViewArea();
}

View File

@ -394,12 +394,9 @@ void DRAGGER::optimizeAndUpdateDraggedLine( LINE& aDragged, const LINE& aOrig, c
OPTIMIZER optimizer( m_lastNode );
int effort = OPTIMIZER::MERGE_SEGMENTS | OPTIMIZER::KEEP_TOPOLOGY;
if( !Settings().GetOptimizeEntireDraggedTrack() )
effort |= OPTIMIZER::RESTRICT_AREA;
optimizer.SetEffortLevel( effort );
optimizer.SetEffortLevel( OPTIMIZER::MERGE_SEGMENTS |
OPTIMIZER::KEEP_TOPOLOGY |
OPTIMIZER::RESTRICT_AREA );
OPT_BOX2I affectedArea = aDragged.ChangedArea( &aOrig );
VECTOR2I anchor( aP );
@ -411,18 +408,21 @@ void DRAGGER::optimizeAndUpdateDraggedLine( LINE& aDragged, const LINE& aOrig, c
optimizer.SetPreserveVertex( anchor );
if( affectedArea )
{
Dbg()->AddPoint( anchor, 3 );
Dbg()->AddBox( *affectedArea, 2 );
optimizer.SetRestrictArea( *affectedArea );
optimizer.Optimize( &aDragged );
// If we get an affected area and "optimize entire track" is off, we restrict to just that
// affected area. Otherwise, people almost never want KiCad to reroute tracks in areas they
// can't even see, so restrict the area to what is visible.
if( !affectedArea || Settings().GetOptimizeEntireDraggedTrack() )
affectedArea = VisibleViewArea();
OPT_BOX2I optArea = aDragged.ChangedArea( &aOrig );
Dbg()->AddPoint( anchor, 3 );
Dbg()->AddBox( *affectedArea, 2 );
optimizer.SetRestrictArea( *affectedArea );
optimizer.Optimize( &aDragged );
if( optArea )
Dbg()->AddBox( *optArea, 4 );
}
OPT_BOX2I optArea = aDragged.ChangedArea( &aOrig );
if( optArea )
Dbg()->AddBox( *optArea, 4 );
m_lastNode->Add( aDragged );
m_draggedItems.Clear();

View File

@ -546,7 +546,7 @@ void ROUTER_TOOL::handleCommonEvents( TOOL_EVENT& aEvent )
{
if( aEvent.Category() == TC_VIEW || aEvent.Category() == TC_MOUSE )
{
auto viewAreaD = getView()->GetBoundary();
BOX2D viewAreaD = getView()->GetGAL()->GetVisibleWorldExtents();
m_router->SetVisibleViewArea( BOX2I( viewAreaD.GetOrigin(), viewAreaD.GetSize() ) );
}
@ -1648,6 +1648,10 @@ int ROUTER_TOOL::InlineDrag( const TOOL_EVENT& aEvent )
// Set initial cursor
setCursor();
// Set the initial visible area
BOX2D viewAreaD = getView()->GetGAL()->GetVisibleWorldExtents();
m_router->SetVisibleViewArea( BOX2I( viewAreaD.GetOrigin(), viewAreaD.GetSize() ) );
// Send an initial movement to prime the collision detection
m_router->Move( p, nullptr );