Split anchor vectors by layer
This is a speed commit for large boards. Tracks and pads cannot connect to elements that are not on the same layer. Rather than checking for this at the last step, this commit splits the anchor vectors by layer, limiting the initial search space.
This commit is contained in:
parent
019ada0a92
commit
b2d0631370
|
@ -473,6 +473,8 @@ void CN_CONNECTIVITY_ALGO::searchConnections( bool aIncludeZones )
|
||||||
#ifdef PROFILE
|
#ifdef PROFILE
|
||||||
PROF_COUNTER search_cnt( "search-connections" );
|
PROF_COUNTER search_cnt( "search-connections" );
|
||||||
PROF_COUNTER search_basic( "search-basic" );
|
PROF_COUNTER search_basic( "search-basic" );
|
||||||
|
PROF_COUNTER search_pads( "search-pads" );
|
||||||
|
PROF_COUNTER search_tracks( "search-tracks" );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if( m_padList.IsDirty() || m_trackList.IsDirty() || m_viaList.IsDirty() )
|
if( m_padList.IsDirty() || m_trackList.IsDirty() || m_viaList.IsDirty() )
|
||||||
|
@ -484,10 +486,13 @@ void CN_CONNECTIVITY_ALGO::searchConnections( bool aIncludeZones )
|
||||||
auto pad = static_cast<D_PAD*> ( padItem->Parent() );
|
auto pad = static_cast<D_PAD*> ( padItem->Parent() );
|
||||||
auto searchPads = std::bind( checkForConnection, _1, padItem );
|
auto searchPads = std::bind( checkForConnection, _1, padItem );
|
||||||
|
|
||||||
m_padList.FindNearby( pad->ShapePos(), pad->GetBoundingRadius(), searchPads );
|
m_padList.FindNearby( pad->ShapePos(), pad->GetBoundingRadius(), searchPads, pad->GetLayerSet() );
|
||||||
m_trackList.FindNearby( pad->ShapePos(), pad->GetBoundingRadius(), searchPads );
|
m_trackList.FindNearby( pad->ShapePos(), pad->GetBoundingRadius(), searchPads, pad->GetLayerSet() );
|
||||||
m_viaList.FindNearby( pad->ShapePos(), pad->GetBoundingRadius(), searchPads );
|
m_viaList.FindNearby( pad->ShapePos(), pad->GetBoundingRadius(), searchPads, pad->GetLayerSet() );
|
||||||
}
|
}
|
||||||
|
#ifdef PROFILE
|
||||||
|
search_pads.Show();
|
||||||
|
#endif
|
||||||
|
|
||||||
for( auto& trackItem : m_trackList )
|
for( auto& trackItem : m_trackList )
|
||||||
{
|
{
|
||||||
|
@ -495,9 +500,12 @@ void CN_CONNECTIVITY_ALGO::searchConnections( bool aIncludeZones )
|
||||||
int dist_max = track->GetWidth() / 2;
|
int dist_max = track->GetWidth() / 2;
|
||||||
auto searchTracks = std::bind( checkForConnection, _1, trackItem, dist_max );
|
auto searchTracks = std::bind( checkForConnection, _1, trackItem, dist_max );
|
||||||
|
|
||||||
m_trackList.FindNearby( track->GetStart(), dist_max, searchTracks );
|
m_trackList.FindNearby( track->GetStart(), dist_max, searchTracks, track->GetLayerSet() );
|
||||||
m_trackList.FindNearby( track->GetEnd(), dist_max, searchTracks );
|
m_trackList.FindNearby( track->GetEnd(), dist_max, searchTracks, track->GetLayerSet() );
|
||||||
}
|
}
|
||||||
|
#ifdef PROFILE
|
||||||
|
search_tracks.Show();
|
||||||
|
#endif
|
||||||
|
|
||||||
for( auto& viaItem : m_viaList )
|
for( auto& viaItem : m_viaList )
|
||||||
{
|
{
|
||||||
|
@ -602,6 +610,15 @@ void CN_LIST::RemoveInvalidItems( std::vector<CN_ITEM*>& aGarbage )
|
||||||
} );
|
} );
|
||||||
|
|
||||||
m_anchors.resize( lastAnchor - m_anchors.begin() );
|
m_anchors.resize( lastAnchor - m_anchors.begin() );
|
||||||
|
for( auto i = 0; i < PCB_LAYER_ID_COUNT; i++ )
|
||||||
|
{
|
||||||
|
lastAnchor = std::remove_if(m_layer_anchors[i].begin(), m_layer_anchors[i].end(),
|
||||||
|
[] ( const CN_ANCHOR_PTR anchor ) {
|
||||||
|
return !anchor->Valid();
|
||||||
|
} );
|
||||||
|
|
||||||
|
m_layer_anchors[i].resize( lastAnchor - m_layer_anchors[i].begin() );
|
||||||
|
}
|
||||||
|
|
||||||
auto lastItem = std::remove_if(m_items.begin(), m_items.end(), [&aGarbage] ( CN_ITEM* item ) {
|
auto lastItem = std::remove_if(m_items.begin(), m_items.end(), [&aGarbage] ( CN_ITEM* item ) {
|
||||||
if( !item->Valid() )
|
if( !item->Valid() )
|
||||||
|
|
|
@ -408,13 +408,21 @@ class CN_LIST
|
||||||
private:
|
private:
|
||||||
bool m_dirty;
|
bool m_dirty;
|
||||||
std::vector<CN_ANCHOR_PTR> m_anchors;
|
std::vector<CN_ANCHOR_PTR> m_anchors;
|
||||||
|
CN_ANCHORS m_layer_anchors[PCB_LAYER_ID_COUNT];
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::vector<CN_ITEM*> m_items;
|
std::vector<CN_ITEM*> m_items;
|
||||||
|
|
||||||
void addAnchor( VECTOR2I pos, CN_ITEM* item )
|
void addAnchor( VECTOR2I pos, CN_ITEM* item )
|
||||||
{
|
{
|
||||||
m_anchors.push_back( item->AddAnchor( pos ) );
|
CN_ANCHOR_PTR new_anchor = item->AddAnchor( pos );
|
||||||
|
m_anchors.push_back( new_anchor );
|
||||||
|
|
||||||
|
for( int i = 0; i < PCB_LAYER_ID_COUNT; i++ )
|
||||||
|
{
|
||||||
|
if( ( item->Parent()->GetLayerSet() & LSET( 1, i ) ).any() )
|
||||||
|
m_layer_anchors[i].push_back( new_anchor );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -425,6 +433,11 @@ private:
|
||||||
{
|
{
|
||||||
std::sort( m_anchors.begin(), m_anchors.end() );
|
std::sort( m_anchors.begin(), m_anchors.end() );
|
||||||
|
|
||||||
|
for( auto i = 0; i < PCB_LAYER_ID_COUNT; i++ )
|
||||||
|
{
|
||||||
|
std::sort( m_layer_anchors[i].begin(), m_layer_anchors[i].end() );
|
||||||
|
}
|
||||||
|
|
||||||
m_dirty = false;
|
m_dirty = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -453,10 +466,10 @@ public:
|
||||||
std::vector<CN_ANCHOR_PTR>& Anchors() { return m_anchors; }
|
std::vector<CN_ANCHOR_PTR>& Anchors() { return m_anchors; }
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
void FindNearby( VECTOR2I aPosition, int aDistMax, T aFunc, bool aDirtyOnly = false );
|
void FindNearby( VECTOR2I aPosition, int aDistMax, T aFunc, LSET aLayers = LSET::AllLayersMask(), bool aDirtyOnly = false );
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
void FindNearby( BOX2I aBBox, T aFunc, bool aDirtyOnly = false );
|
void FindNearby( BOX2I aBBox, T aFunc, LSET aLayers = LSET::AllLayersMask(), bool aDirtyOnly = false );
|
||||||
|
|
||||||
void SetDirty( bool aDirty = true )
|
void SetDirty( bool aDirty = true )
|
||||||
{
|
{
|
||||||
|
@ -627,18 +640,27 @@ public:
|
||||||
|
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
void CN_LIST::FindNearby( BOX2I aBBox, T aFunc, bool aDirtyOnly )
|
void CN_LIST::FindNearby( BOX2I aBBox, T aFunc, LSET aLayers, bool aDirtyOnly )
|
||||||
{
|
{
|
||||||
sort();
|
sort();
|
||||||
|
|
||||||
CN_ANCHOR_PTR lower_ptr = std::make_shared<CN_ANCHOR>
|
CN_ANCHORS *anchor_set = &m_anchors;
|
||||||
( aBBox.GetPosition(), m_anchors[0]->Item() );
|
PCB_LAYER_ID layer = aLayers.ExtractLayer();
|
||||||
|
|
||||||
auto lower_it = std::lower_bound( m_anchors.begin(), m_anchors.end(), lower_ptr,
|
if( layer > 0 )
|
||||||
|
anchor_set = &(m_layer_anchors[ layer ]);
|
||||||
|
|
||||||
|
if( (*anchor_set).size() == 0 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
CN_ANCHOR_PTR lower_ptr = std::make_shared<CN_ANCHOR>
|
||||||
|
( aBBox.GetPosition(), (*anchor_set)[0]->Item() );
|
||||||
|
|
||||||
|
auto lower_it = std::lower_bound( anchor_set->begin(), anchor_set->end(), lower_ptr,
|
||||||
[]( const CN_ANCHOR_PTR& a, const CN_ANCHOR_PTR& b ) -> bool
|
[]( const CN_ANCHOR_PTR& a, const CN_ANCHOR_PTR& b ) -> bool
|
||||||
{ return a->Pos().x < b->Pos().x; } );
|
{ return a->Pos().x < b->Pos().x; } );
|
||||||
|
|
||||||
for( auto it = lower_it; it != m_anchors.end(); it++)
|
for( auto it = lower_it; it != anchor_set->end(); it++)
|
||||||
{
|
{
|
||||||
if( (*it)->Pos().x > aBBox.GetRight() )
|
if( (*it)->Pos().x > aBBox.GetRight() )
|
||||||
break;
|
break;
|
||||||
|
@ -669,7 +691,7 @@ void CN_ZONE_LIST::FindNearbyZones( BOX2I aBBox, T aFunc, bool aDirtyOnly )
|
||||||
|
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
void CN_LIST::FindNearby( VECTOR2I aPosition, int aDistMax, T aFunc, bool aDirtyOnly )
|
void CN_LIST::FindNearby( VECTOR2I aPosition, int aDistMax, T aFunc, LSET aLayers, bool aDirtyOnly )
|
||||||
{
|
{
|
||||||
/* Search items in m_Candidates that position is <= aDistMax from aPosition
|
/* Search items in m_Candidates that position is <= aDistMax from aPosition
|
||||||
* (Rectilinear distance)
|
* (Rectilinear distance)
|
||||||
|
@ -680,14 +702,23 @@ void CN_LIST::FindNearby( VECTOR2I aPosition, int aDistMax, T aFunc, bool aDirty
|
||||||
|
|
||||||
sort();
|
sort();
|
||||||
|
|
||||||
CN_ANCHOR_PTR lower = std::make_shared<CN_ANCHOR>
|
CN_ANCHORS *anchor_set = &m_anchors;
|
||||||
( aPosition - VECTOR2I( aDistMax + 1, 0 ), m_anchors[0]->Item() );
|
PCB_LAYER_ID layer = aLayers.ExtractLayer();
|
||||||
|
|
||||||
auto lower_it = std::lower_bound( m_anchors.begin(), m_anchors.end(), lower,
|
if( layer > 0 )
|
||||||
|
anchor_set = &(m_layer_anchors[ layer ]);
|
||||||
|
|
||||||
|
if( (*anchor_set).size() == 0 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
CN_ANCHOR_PTR lower = std::make_shared<CN_ANCHOR>
|
||||||
|
( aPosition - VECTOR2I( aDistMax, 0 ), (*anchor_set)[0]->Item() );
|
||||||
|
|
||||||
|
auto lower_it = std::lower_bound( anchor_set->begin(), anchor_set->end(), lower,
|
||||||
[]( const CN_ANCHOR_PTR& a, const CN_ANCHOR_PTR& b ) -> bool
|
[]( const CN_ANCHOR_PTR& a, const CN_ANCHOR_PTR& b ) -> bool
|
||||||
{ return a->Pos().x < b->Pos().x; } );
|
{ return a->Pos().x < b->Pos().x; } );
|
||||||
|
|
||||||
for( auto it = lower_it; it != m_anchors.end(); it++ )
|
for( auto it = lower_it; it != anchor_set->end(); it++ )
|
||||||
{
|
{
|
||||||
if( (*it)->Pos().x > aDistMax + aPosition.x )
|
if( (*it)->Pos().x > aDistMax + aPosition.x )
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue