pcbnew: Remove all threading from dynamic ratsnest
The last remaining threaded operation in dynamic ratsnest was the recalculation of the dynamic connectivity map. Because we do not require any of the extra features of the connectivity map, we can get away with a lightweight move of the anchors to update the ratsnest. The resulting connectivity tree is not valid but it is not needed for the ratsnest, which only needs a list of nets/anchors.
This commit is contained in:
parent
ec5040aff5
commit
b8b3d5c16d
|
@ -167,8 +167,6 @@ private:
|
|||
|
||||
void searchConnections();
|
||||
|
||||
void update();
|
||||
|
||||
void propagateConnections( BOARD_COMMIT* aCommit = nullptr );
|
||||
|
||||
template <class Container, class BItem>
|
||||
|
@ -281,7 +279,6 @@ public:
|
|||
|
||||
void MarkNetAsDirty( int aNet );
|
||||
void SetProgressReporter( PROGRESS_REPORTER* aReporter );
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -95,6 +95,12 @@ void CONNECTIVITY_DATA::Build( const std::vector<BOARD_ITEM*>& aItems )
|
|||
}
|
||||
|
||||
|
||||
void CONNECTIVITY_DATA::Move( const VECTOR2I& aDelta )
|
||||
{
|
||||
m_connAlgo->ForEachAnchor( [&aDelta] ( CN_ANCHOR& anchor ) { anchor.Move( aDelta ); } );
|
||||
}
|
||||
|
||||
|
||||
void CONNECTIVITY_DATA::updateRatsnest()
|
||||
{
|
||||
#ifdef PROFILE
|
||||
|
@ -255,24 +261,19 @@ void CONNECTIVITY_DATA::FindIsolatedCopperIslands( std::vector<CN_ZONE_ISOLATED_
|
|||
}
|
||||
|
||||
|
||||
void CONNECTIVITY_DATA::ComputeDynamicRatsnest( const std::vector<BOARD_ITEM*>& aItems )
|
||||
void CONNECTIVITY_DATA::ComputeDynamicRatsnest( const std::vector<BOARD_ITEM*>& aItems,
|
||||
const CONNECTIVITY_DATA* aDynamicData )
|
||||
{
|
||||
if( !aDynamicData )
|
||||
return;
|
||||
|
||||
m_dynamicRatsnest.clear();
|
||||
|
||||
if( std::none_of( aItems.begin(), aItems.end(), []( const BOARD_ITEM* aItem )
|
||||
{ return( aItem->Type() == PCB_TRACE_T || aItem->Type() == PCB_PAD_T ||
|
||||
aItem->Type() == PCB_ARC_T || aItem->Type() == PCB_ZONE_AREA_T ||
|
||||
aItem->Type() == PCB_MODULE_T || aItem->Type() == PCB_VIA_T ); } ) )
|
||||
// This gets connections between the stationary board and the
|
||||
// moving selection
|
||||
for( unsigned int nc = 1; nc < aDynamicData->m_nets.size(); nc++ )
|
||||
{
|
||||
return ;
|
||||
}
|
||||
|
||||
CONNECTIVITY_DATA connData( aItems, true );
|
||||
BlockRatsnestItems( aItems );
|
||||
|
||||
for( unsigned int nc = 1; nc < connData.m_nets.size(); nc++ )
|
||||
{
|
||||
auto dynNet = connData.m_nets[nc];
|
||||
auto dynNet = aDynamicData->m_nets[nc];
|
||||
|
||||
if( dynNet->GetNodeCount() != 0 )
|
||||
{
|
||||
|
@ -291,6 +292,7 @@ void CONNECTIVITY_DATA::ComputeDynamicRatsnest( const std::vector<BOARD_ITEM*>&
|
|||
}
|
||||
}
|
||||
|
||||
// This gets the ratsnest for internal connections in the moving set
|
||||
const auto& edges = GetRatsnestForItems( aItems );
|
||||
|
||||
for( const auto& edge : edges )
|
||||
|
|
|
@ -125,6 +125,15 @@ public:
|
|||
*/
|
||||
bool Update( BOARD_ITEM* aItem );
|
||||
|
||||
/**
|
||||
* Moves the connectivity list anchors. N.B., this does not move the bounding
|
||||
* boxes for the the RTree, so the use of this function will invalidate the
|
||||
* connectivity data for uses other than the dynamic ratsnest
|
||||
*
|
||||
* @param aDelta vector for movement of the tree
|
||||
*/
|
||||
void Move( const VECTOR2I& aDelta );
|
||||
|
||||
/**
|
||||
* Function Clear()
|
||||
* Erases the connectivity database.
|
||||
|
@ -208,7 +217,8 @@ public:
|
|||
* Calculates the temporary dynamic ratsnest (i.e. the ratsnest lines that)
|
||||
* for the set of items aItems.
|
||||
*/
|
||||
void ComputeDynamicRatsnest( const std::vector<BOARD_ITEM*>& aItems );
|
||||
void ComputeDynamicRatsnest( const std::vector<BOARD_ITEM*>& aItems,
|
||||
const CONNECTIVITY_DATA* aDynamicData );
|
||||
|
||||
const std::vector<RN_DYNAMIC_LINE>& GetDynamicRatsnest() const
|
||||
{
|
||||
|
@ -257,6 +267,13 @@ public:
|
|||
private:
|
||||
|
||||
void updateRatsnest();
|
||||
|
||||
/**
|
||||
* Updates the item positions without modifying the dirtyNet flag. This is valid only when the
|
||||
* item list contains all elements in the connectivity database
|
||||
* @param aItems List of items with new positions
|
||||
*/
|
||||
void updateItemPositions( const std::vector<BOARD_ITEM*>& aItems );
|
||||
void addRatsnestCluster( const std::shared_ptr<CN_CLUSTER>& aCluster );
|
||||
|
||||
std::shared_ptr<CN_CONNECTIVITY_ALGO> m_connAlgo;
|
||||
|
|
|
@ -81,6 +81,11 @@ public:
|
|||
return m_pos;
|
||||
}
|
||||
|
||||
void Move( const VECTOR2I& aPos )
|
||||
{
|
||||
m_pos += aPos;
|
||||
}
|
||||
|
||||
const unsigned int Dist( const CN_ANCHOR& aSecond )
|
||||
{
|
||||
return ( m_pos - aSecond.Pos() ).EuclideanNorm();
|
||||
|
|
|
@ -390,6 +390,7 @@ int EDIT_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, bool aPickReference )
|
|||
// Main loop: keep receiving events
|
||||
do
|
||||
{
|
||||
VECTOR2I movement;
|
||||
editFrame->GetCanvas()->SetCurrentCursor( wxCURSOR_ARROW );
|
||||
grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
|
||||
grid.SetUseGrid( !evt->Modifier( MD_ALT ) );
|
||||
|
@ -421,7 +422,7 @@ int EDIT_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, bool aPickReference )
|
|||
controls->ForceCursorPosition( true, m_cursor );
|
||||
selection.SetReferencePoint( m_cursor );
|
||||
|
||||
VECTOR2I movement( m_cursor - prevPos );
|
||||
movement = m_cursor - prevPos;
|
||||
prevPos = m_cursor;
|
||||
totalMovement += movement;
|
||||
|
||||
|
@ -494,7 +495,7 @@ int EDIT_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, bool aPickReference )
|
|||
// start moving with the reference point attached to the cursor
|
||||
grid.SetAuxAxes( false );
|
||||
|
||||
auto delta = m_cursor - selection.GetReferencePoint();
|
||||
movement = m_cursor - selection.GetReferencePoint();
|
||||
|
||||
// Drag items to the current cursor position
|
||||
for( EDA_ITEM* item : selection )
|
||||
|
@ -503,7 +504,7 @@ int EDIT_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, bool aPickReference )
|
|||
if( item->GetParent() && item->GetParent()->IsSelected() )
|
||||
continue;
|
||||
|
||||
static_cast<BOARD_ITEM*>( item )->Move( delta );
|
||||
static_cast<BOARD_ITEM*>( item )->Move( movement );
|
||||
}
|
||||
|
||||
selection.SetReferencePoint( m_cursor );
|
||||
|
@ -550,7 +551,7 @@ int EDIT_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, bool aPickReference )
|
|||
}
|
||||
|
||||
m_toolMgr->PostEvent( EVENTS::SelectedItemsModified );
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::updateLocalRatsnest, false );
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::updateLocalRatsnest, false, new VECTOR2I( movement ) );
|
||||
}
|
||||
|
||||
else if( evt->IsCancelInteractive() || evt->IsActivate() )
|
||||
|
@ -615,14 +616,11 @@ int EDIT_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, bool aPickReference )
|
|||
|
||||
// If canceled, we need to remove the dynamic ratsnest from the screen
|
||||
if( restore_state )
|
||||
{
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::hideDynamicRatsnest, true );
|
||||
m_commit->Revert();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_commit->Push( _( "Drag" ) );
|
||||
}
|
||||
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::hideDynamicRatsnest, true );
|
||||
|
||||
if( unselect )
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2019 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2019-2020 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
|
||||
|
@ -38,8 +38,7 @@ PCB_INSPECTION_TOOL::PCB_INSPECTION_TOOL() :
|
|||
{
|
||||
m_probingSchToPcb = false;
|
||||
m_lastNetcode = -1;
|
||||
|
||||
m_slowRatsnest = false;
|
||||
m_dynamicData = nullptr;
|
||||
}
|
||||
|
||||
|
||||
|
@ -103,10 +102,6 @@ bool PCB_INSPECTION_TOOL::Init()
|
|||
selectionTool->GetToolMenu().AddSubMenu( netSubMenu );
|
||||
menu.AddMenu( netSubMenu.get(), SELECTION_CONDITIONS::OnlyTypes( connectedTypes ) );
|
||||
|
||||
m_ratsnestTimer.SetOwner( this );
|
||||
Connect( m_ratsnestTimer.GetId(), wxEVT_TIMER,
|
||||
wxTimerEventHandler( PCB_INSPECTION_TOOL::ratsnestTimer ), NULL, this );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -429,6 +424,8 @@ int PCB_INSPECTION_TOOL::LocalRatsnestTool( const TOOL_EVENT& aEvent )
|
|||
|
||||
int PCB_INSPECTION_TOOL::UpdateSelectionRatsnest( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
VECTOR2I* delta = aEvent.Parameter<VECTOR2I*>();
|
||||
|
||||
auto selectionTool = m_toolMgr->GetTool<SELECTION_TOOL>();
|
||||
auto& selection = selectionTool->GetSelection();
|
||||
auto connectivity = getModel<BOARD>()->GetConnectivity();
|
||||
|
@ -436,62 +433,30 @@ int PCB_INSPECTION_TOOL::UpdateSelectionRatsnest( const TOOL_EVENT& aEvent )
|
|||
if( selection.Empty() )
|
||||
{
|
||||
connectivity->ClearDynamicRatsnest();
|
||||
}
|
||||
else if( m_slowRatsnest )
|
||||
{
|
||||
// Compute ratsnest only when user stops dragging for a moment
|
||||
connectivity->HideDynamicRatsnest();
|
||||
m_ratsnestTimer.Start( 20 );
|
||||
delete m_dynamicData;
|
||||
m_dynamicData = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Check how much time doest it take to calculate ratsnest
|
||||
PROF_COUNTER counter;
|
||||
calculateSelectionRatsnest();
|
||||
counter.Stop();
|
||||
|
||||
// If it is too slow, then switch to 'slow ratsnest' mode when
|
||||
// ratsnest is calculated when user stops dragging items for a moment
|
||||
if( counter.msecs() > 25 )
|
||||
{
|
||||
m_slowRatsnest = true;
|
||||
connectivity->HideDynamicRatsnest();
|
||||
}
|
||||
calculateSelectionRatsnest( *delta );
|
||||
}
|
||||
|
||||
delete delta;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int PCB_INSPECTION_TOOL::HideDynamicRatsnest( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
getModel<BOARD>()->GetConnectivity()->HideDynamicRatsnest();
|
||||
m_slowRatsnest = false;
|
||||
getModel<BOARD>()->GetConnectivity()->ClearDynamicRatsnest();
|
||||
delete m_dynamicData;
|
||||
m_dynamicData = nullptr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void PCB_INSPECTION_TOOL::ratsnestTimer( wxTimerEvent& aEvent )
|
||||
{
|
||||
auto connectivity = getModel<BOARD>()->GetConnectivity();
|
||||
|
||||
m_ratsnestTimer.Stop();
|
||||
|
||||
/// Check how much time does it take to calculate ratsnest
|
||||
PROF_COUNTER counter;
|
||||
calculateSelectionRatsnest();
|
||||
counter.Stop();
|
||||
|
||||
/// If the ratsnest is fast enough, turn the slow ratsnest off
|
||||
if( counter.msecs() <= 25 )
|
||||
m_slowRatsnest = false;
|
||||
|
||||
m_frame->GetCanvas()->RedrawRatsnest();
|
||||
m_frame->GetCanvas()->Refresh();
|
||||
}
|
||||
|
||||
|
||||
void PCB_INSPECTION_TOOL::calculateSelectionRatsnest()
|
||||
void PCB_INSPECTION_TOOL::calculateSelectionRatsnest( const VECTOR2I& aDelta )
|
||||
{
|
||||
SELECTION_TOOL* selectionTool = m_toolMgr->GetTool<SELECTION_TOOL>();
|
||||
SELECTION& selection = selectionTool->GetSelection();
|
||||
|
@ -515,7 +480,25 @@ void PCB_INSPECTION_TOOL::calculateSelectionRatsnest()
|
|||
}
|
||||
}
|
||||
|
||||
connectivity->ComputeDynamicRatsnest( items );
|
||||
if( items.empty() || std::none_of( items.begin(), items.end(), []( const BOARD_ITEM* aItem )
|
||||
{ return( aItem->Type() == PCB_TRACE_T || aItem->Type() == PCB_PAD_T ||
|
||||
aItem->Type() == PCB_ARC_T || aItem->Type() == PCB_ZONE_AREA_T ||
|
||||
aItem->Type() == PCB_MODULE_T || aItem->Type() == PCB_VIA_T ); } ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if( !m_dynamicData )
|
||||
{
|
||||
m_dynamicData = new CONNECTIVITY_DATA( items, true );
|
||||
connectivity->BlockRatsnestItems( items );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_dynamicData->Move( aDelta );
|
||||
}
|
||||
|
||||
connectivity->ComputeDynamicRatsnest( items, m_dynamicData );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2019 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2019-2020 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
|
||||
|
@ -24,13 +24,14 @@
|
|||
#ifndef __BOARD_STATISTICS_TOOL_H
|
||||
#define __BOARD_STATISTICS_TOOL_H
|
||||
|
||||
|
||||
#include <dialogs/dialog_board_statistics.h>
|
||||
#include <dialogs/dialog_select_net_from_list.h>
|
||||
#include <pcb_edit_frame.h>
|
||||
#include <tools/pcb_actions.h>
|
||||
#include <tools/pcb_tool_base.h>
|
||||
|
||||
class CONNECTIVITY_DATA;
|
||||
|
||||
/**
|
||||
* PCB_INSPECTION_TOOL
|
||||
*
|
||||
|
@ -93,7 +94,7 @@ private:
|
|||
void ratsnestTimer( wxTimerEvent& aEvent );
|
||||
|
||||
///> Recalculates dynamic ratsnest for the current selection
|
||||
void calculateSelectionRatsnest();
|
||||
void calculateSelectionRatsnest( const VECTOR2I& aDelta );
|
||||
|
||||
bool highlightNet( const VECTOR2D& aPosition, bool aUseSelection );
|
||||
|
||||
|
@ -110,11 +111,11 @@ private:
|
|||
bool m_probingSchToPcb; // Recursion guard when cross-probing to EESchema
|
||||
int m_lastNetcode; // Used for toggling between last two highlighted nets
|
||||
|
||||
bool m_slowRatsnest; // Indicates current selection ratsnest will be slow to calculate
|
||||
wxTimer m_ratsnestTimer; // Timer to initiate lazy ratsnest calculation (ie: when slow)
|
||||
CONNECTIVITY_DATA* m_dynamicData; // Cached connectivity data from the selection
|
||||
|
||||
std::unique_ptr<DIALOG_SELECT_NET_FROM_LIST> m_listNetsDialog;
|
||||
DIALOG_SELECT_NET_FROM_LIST::SETTINGS m_listNetsDialogSettings;
|
||||
|
||||
};
|
||||
|
||||
#endif //__BOARD_STATISTICS_TOOL_H
|
||||
|
|
Loading…
Reference in New Issue