Remove delauney computations from dynamic ratsnest

Avoids additional calculations on movement by using cached ratsnest for
internal nets and keeping bicolored line calc for others.

Fixes https://gitlab.com/kicad/code/kicad/issues/1865
This commit is contained in:
Seth Hillbrand 2020-06-22 20:35:34 -07:00
parent d01b29ab37
commit 104ff29e5f
2 changed files with 71 additions and 89 deletions

View File

@ -42,7 +42,8 @@ CONNECTIVITY_DATA::CONNECTIVITY_DATA()
}
CONNECTIVITY_DATA::CONNECTIVITY_DATA( const std::vector<BOARD_ITEM*>& aItems )
CONNECTIVITY_DATA::CONNECTIVITY_DATA( const std::vector<BOARD_ITEM*>& aItems, bool aSkipRatsnest )
: m_skipRatsnest( aSkipRatsnest )
{
Build( aItems );
m_progressReporter = nullptr;
@ -187,7 +188,8 @@ void CONNECTIVITY_DATA::RecalculateRatsnest( BOARD_COMMIT* aCommit )
m_connAlgo->ClearDirtyFlags();
updateRatsnest();
if( !m_skipRatsnest )
updateRatsnest();
}
@ -254,7 +256,7 @@ void CONNECTIVITY_DATA::ComputeDynamicRatsnest( const std::vector<BOARD_ITEM*>&
return ;
}
CONNECTIVITY_DATA connData( aItems );
CONNECTIVITY_DATA connData( aItems, true );
BlockRatsnestItems( aItems );
for( unsigned int nc = 1; nc < connData.m_nets.size(); nc++ )
@ -278,27 +280,19 @@ void CONNECTIVITY_DATA::ComputeDynamicRatsnest( const std::vector<BOARD_ITEM*>&
}
}
for( auto net : connData.m_nets )
const auto& edges = GetRatsnestForItems( aItems );
for( const auto& edge : edges )
{
if( !net )
continue;
const auto& nodeA = edge.GetSourceNode();
const auto& nodeB = edge.GetTargetNode();
RN_DYNAMIC_LINE l;
const auto& edges = net->GetUnconnected();
if( edges.empty() )
continue;
for( const auto& edge : edges )
{
const auto& nodeA = edge.GetSourceNode();
const auto& nodeB = edge.GetTargetNode();
RN_DYNAMIC_LINE l;
l.a = nodeA->Pos();
l.b = nodeB->Pos();
l.netCode = 0;
m_dynamicRatsnest.push_back( l );
}
// Use the parents' positions
l.a = nodeA->Parent()->GetPosition();
l.b = nodeB->Parent()->GetPosition();
l.netCode = 0;
m_dynamicRatsnest.push_back( l );
}
}
@ -521,68 +515,6 @@ unsigned int CONNECTIVITY_DATA::GetPadCount( int aNet ) const
}
const std::vector<VECTOR2I> CONNECTIVITY_DATA::NearestUnconnectedTargets(
const BOARD_CONNECTED_ITEM* aRef,
const VECTOR2I& aPos,
int aNet )
{
CN_CLUSTER_PTR refCluster;
int refNet = -1;
if( aRef )
refNet = aRef->GetNetCode();
if( aNet >= 0 )
refNet = aNet;
if( aRef )
{
for( auto cl : m_connAlgo->GetClusters() )
{
if( cl->Contains( aRef ) )
{
refCluster = cl;
break;
}
}
}
std::set <VECTOR2I> anchors;
for( auto cl : m_connAlgo->GetClusters() )
{
if( cl != refCluster )
{
for( auto item : *cl )
{
if( item->Valid() && item->Parent()->GetNetCode() == refNet
&& item->Parent()->Type() != PCB_ZONE_AREA_T )
{
for( auto anchor : item->Anchors() )
{
anchors.insert( anchor->Pos() );
}
}
}
}
}
std::vector<VECTOR2I> rv;
std::copy( anchors.begin(), anchors.end(), std::back_inserter( rv ) );
std::sort( rv.begin(), rv.end(), [aPos] ( const VECTOR2I& a, const VECTOR2I& b )
{
auto da = (a - aPos).EuclideanNorm();
auto db = (b - aPos).EuclideanNorm();
return da < db;
} );
return rv;
}
void CONNECTIVITY_DATA::GetUnconnectedEdges( std::vector<CN_EDGE>& aEdges) const
{
for( auto rnNet : m_nets )
@ -689,6 +621,56 @@ void CONNECTIVITY_DATA::SetProgressReporter( PROGRESS_REPORTER* aReporter )
}
const std::vector<CN_EDGE> CONNECTIVITY_DATA::GetRatsnestForItems( std::vector<BOARD_ITEM*> aItems )
{
std::set<int> nets;
std::vector<CN_EDGE> edges;
std::set<BOARD_ITEM*> item_set( aItems.begin(), aItems.end() );
for( auto item : aItems )
{
auto conn_item = static_cast<BOARD_CONNECTED_ITEM*>( item );
if( item->Type() == PCB_MODULE_T )
{
auto component = static_cast<MODULE*>( item );
for( auto pad : component->Pads() )
{
nets.insert( pad->GetNetCode() );
item_set.insert( pad );
}
}
else
{
nets.insert( conn_item->GetNetCode() );
}
}
for( const auto& netcode : nets )
{
const auto& net = GetRatsnestForNet( netcode );
for( const auto& edge : net->GetEdges() )
{
auto srcNode = edge.GetSourceNode();
auto dstNode = edge.GetTargetNode();
auto srcParent = static_cast<BOARD_ITEM*>( srcNode->Parent() );
auto dstParent = static_cast<BOARD_ITEM*>( dstNode->Parent() );
bool srcFound = ( item_set.find(srcParent) != item_set.end() );
bool dstFound = ( item_set.find(dstParent) != item_set.end() );
if ( srcFound && dstFound )
edges.push_back( edge );
}
}
return edges;
}
const std::vector<CN_EDGE> CONNECTIVITY_DATA::GetRatsnestForComponent( MODULE* aComponent, bool aSkipInternalConnections )
{
std::set<int> nets;

View File

@ -83,7 +83,7 @@ public:
CONNECTIVITY_DATA();
~CONNECTIVITY_DATA();
CONNECTIVITY_DATA( const std::vector<BOARD_ITEM*>& aItems );
CONNECTIVITY_DATA( const std::vector<BOARD_ITEM*>& aItems, bool aSkipItems = false );
/**
* Function Build()
@ -227,10 +227,6 @@ public:
const std::vector<BOARD_CONNECTED_ITEM*> GetNetItems( int aNetCode,
const KICAD_T aTypes[] ) const;
const std::vector<VECTOR2I> NearestUnconnectedTargets( const BOARD_CONNECTED_ITEM* aRef,
const VECTOR2I& aPos,
int aMaxCount = -1 );
void BlockRatsnestItems( const std::vector<BOARD_ITEM*>& aItems );
std::shared_ptr<CN_CONNECTIVITY_ALGO> GetConnectivityAlgo() const
@ -247,6 +243,8 @@ public:
void SetProgressReporter( PROGRESS_REPORTER* aReporter );
#ifndef SWIG
const std::vector<CN_EDGE> GetRatsnestForItems( const std::vector<BOARD_ITEM*> aItems );
const std::vector<CN_EDGE> GetRatsnestForComponent( MODULE* aComponent, bool aSkipInternalConnections = false );
#endif
@ -262,6 +260,8 @@ private:
PROGRESS_REPORTER* m_progressReporter;
bool m_skipRatsnest = false;
std::mutex m_lock;
};