Auto reduction and std::shared_ptr cover types reduction.

And a performance optimization or two resulting from above.  (Using
const& intead of copying std::shared_ptrs.)
This commit is contained in:
Jeff Young 2022-02-13 11:54:41 +00:00
parent 90f6edad61
commit c4e133fdf7
9 changed files with 158 additions and 184 deletions

View File

@ -97,7 +97,7 @@ void CN_CONNECTIVITY_ALGO::markItemNetAsDirty( const BOARD_ITEM* aItem )
{ {
if( aItem->IsConnected() ) if( aItem->IsConnected() )
{ {
auto citem = static_cast<const BOARD_CONNECTED_ITEM*>( aItem ); const BOARD_CONNECTED_ITEM* citem = static_cast<const BOARD_CONNECTED_ITEM*>( aItem );
MarkNetAsDirty( citem->GetNetCode() ); MarkNetAsDirty( citem->GetNetCode() );
} }
else else
@ -213,7 +213,7 @@ void CN_CONNECTIVITY_ALGO::searchConnections()
m_itemList.RemoveInvalidItems( garbage ); m_itemList.RemoveInvalidItems( garbage );
for( auto item : garbage ) for( CN_ITEM* item : garbage )
delete item; delete item;
#ifdef PROFILE #ifdef PROFILE
@ -266,7 +266,9 @@ void CN_CONNECTIVITY_ALGO::searchConnections()
}; };
if( parallelThreadCount <= 1 ) if( parallelThreadCount <= 1 )
{
conn_lambda( &m_itemList, m_progressReporter ); conn_lambda( &m_itemList, m_progressReporter );
}
else else
{ {
for( size_t ii = 0; ii < parallelThreadCount; ++ii ) for( size_t ii = 0; ii < parallelThreadCount; ++ii )
@ -367,9 +369,9 @@ CN_CONNECTIVITY_ALGO::SearchClusters( CLUSTER_SEARCH_MODE aMode, const KICAD_T a
while( !item_set.empty() ) while( !item_set.empty() )
{ {
CN_CLUSTER_PTR cluster = std::make_shared<CN_CLUSTER>(); std::shared_ptr<CN_CLUSTER> cluster = std::make_shared<CN_CLUSTER>();
CN_ITEM* root; CN_ITEM* root;
auto it = item_set.begin(); auto it = item_set.begin();
while( it != item_set.end() && (*it)->Visited() ) while( it != item_set.end() && (*it)->Visited() )
it = item_set.erase( item_set.begin() ); it = item_set.erase( item_set.begin() );
@ -390,7 +392,7 @@ CN_CONNECTIVITY_ALGO::SearchClusters( CLUSTER_SEARCH_MODE aMode, const KICAD_T a
Q.pop_front(); Q.pop_front();
cluster->Add( current ); cluster->Add( current );
for( auto n : current->ConnectedItems() ) for( CN_ITEM* n : current->ConnectedItems() )
{ {
if( withinAnyNet && n->Net() != root->Net() ) if( withinAnyNet && n->Net() != root->Net() )
continue; continue;
@ -410,7 +412,7 @@ CN_CONNECTIVITY_ALGO::SearchClusters( CLUSTER_SEARCH_MODE aMode, const KICAD_T a
return CLUSTERS(); return CLUSTERS();
std::sort( clusters.begin(), clusters.end(), std::sort( clusters.begin(), clusters.end(),
[]( CN_CLUSTER_PTR a, CN_CLUSTER_PTR b ) []( const std::shared_ptr<CN_CLUSTER>& a, const std::shared_ptr<CN_CLUSTER>& b )
{ {
return a->OriginNet() < b->OriginNet(); return a->OriginNet() < b->OriginNet();
} ); } );
@ -585,16 +587,14 @@ void CN_CONNECTIVITY_ALGO::FindIsolatedCopperIslands( ZONE* aZone, PCB_LAYER_ID
m_connClusters = SearchClusters( CSM_CONNECTIVITY_CHECK ); m_connClusters = SearchClusters( CSM_CONNECTIVITY_CHECK );
for( const auto& cluster : m_connClusters ) for( const std::shared_ptr<CN_CLUSTER>& cluster : m_connClusters )
{ {
if( cluster->Contains( aZone ) && cluster->IsOrphaned() ) if( cluster->Contains( aZone ) && cluster->IsOrphaned() )
{ {
for( auto z : *cluster ) for( CN_ITEM* z : *cluster )
{ {
if( z->Parent() == aZone && z->Layer() == aLayer ) if( z->Parent() == aZone && z->Layer() == aLayer )
{
aIslands.push_back( static_cast<CN_ZONE_LAYER*>(z)->SubpolyIndex() ); aIslands.push_back( static_cast<CN_ZONE_LAYER*>(z)->SubpolyIndex() );
}
} }
} }
} }
@ -619,7 +619,7 @@ void CN_CONNECTIVITY_ALGO::FindIsolatedCopperIslands( std::vector<CN_ZONE_ISOLAT
if( zone.m_zone->GetFilledPolysList( layer ).IsEmpty() ) if( zone.m_zone->GetFilledPolysList( layer ).IsEmpty() )
continue; continue;
for( const CN_CLUSTER_PTR& cluster : m_connClusters ) for( const std::shared_ptr<CN_CLUSTER>& cluster : m_connClusters )
{ {
if( cluster->Contains( zone.m_zone ) && cluster->IsOrphaned() ) if( cluster->Contains( zone.m_zone ) && cluster->IsOrphaned() )
{ {

View File

@ -2,7 +2,7 @@
* This program source code file is part of KICAD, a free EDA CAD application. * This program source code file is part of KICAD, a free EDA CAD application.
* *
* Copyright (C) 2013-2017 CERN * Copyright (C) 2013-2017 CERN
* Copyright (C) 2019-2021 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2019-2022 KiCad Developers, see AUTHORS.txt for contributors.
* *
* @author Maciej Suminski <maciej.suminski@cern.ch> * @author Maciej Suminski <maciej.suminski@cern.ch>
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch> * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
@ -48,7 +48,6 @@
#include <connectivity/connectivity_data.h> #include <connectivity/connectivity_data.h>
#include <connectivity/connectivity_items.h> #include <connectivity/connectivity_items.h>
class CN_CONNECTIVITY_ALGO_IMPL;
class CN_RATSNEST_NODES; class CN_RATSNEST_NODES;
class BOARD; class BOARD;
class BOARD_CONNECTED_ITEM; class BOARD_CONNECTED_ITEM;
@ -64,12 +63,17 @@ class PROGRESS_REPORTER;
class CN_EDGE class CN_EDGE
{ {
public: public:
CN_EDGE() CN_EDGE() :
: m_weight( 0 ), m_visible( true ) m_weight( 0 ),
m_visible( true )
{} {}
CN_EDGE( CN_ANCHOR_PTR aSource, CN_ANCHOR_PTR aTarget, unsigned aWeight = 0 ) CN_EDGE( const std::shared_ptr<CN_ANCHOR>& aSource, const std::shared_ptr<CN_ANCHOR>& aTarget,
: m_source( aSource ), m_target( aTarget ), m_weight( aWeight ), m_visible( true ) unsigned aWeight = 0 ) :
m_source( aSource ),
m_target( aTarget ),
m_weight( aWeight ),
m_visible( true )
{} {}
/** /**
@ -83,39 +87,26 @@ public:
return m_weight < aOther.m_weight; return m_weight < aOther.m_weight;
} }
CN_ANCHOR_PTR GetSourceNode() const { return m_source; } std::shared_ptr<CN_ANCHOR> GetSourceNode() const { return m_source; }
CN_ANCHOR_PTR GetTargetNode() const { return m_target; } std::shared_ptr<CN_ANCHOR> GetTargetNode() const { return m_target; }
void SetSourceNode( const std::shared_ptr<CN_ANCHOR>& aNode ) { m_source = aNode; }
void SetTargetNode( const std::shared_ptr<CN_ANCHOR>& aNode ) { m_target = aNode; }
void SetWeight( unsigned weight ) { m_weight = weight; }
unsigned GetWeight() const { return m_weight; } unsigned GetWeight() const { return m_weight; }
void SetSourceNode( const CN_ANCHOR_PTR& aNode ) { m_source = aNode; } void SetVisible( bool aVisible ) { m_visible = aVisible; }
void SetTargetNode( const CN_ANCHOR_PTR& aNode ) { m_target = aNode; } bool IsVisible() const { return m_visible; }
void SetWeight( unsigned weight ) { m_weight = weight; }
void SetVisible( bool aVisible ) const VECTOR2I GetSourcePos() const { return m_source->Pos(); }
{ const VECTOR2I GetTargetPos() const { return m_target->Pos(); }
m_visible = aVisible;
}
bool IsVisible() const
{
return m_visible;
}
const VECTOR2I GetSourcePos() const
{
return m_source->Pos();
}
const VECTOR2I GetTargetPos() const
{
return m_target->Pos();
}
private: private:
CN_ANCHOR_PTR m_source; std::shared_ptr<CN_ANCHOR> m_source;
CN_ANCHOR_PTR m_target; std::shared_ptr<CN_ANCHOR> m_target;
unsigned m_weight; unsigned m_weight;
bool m_visible; bool m_visible;
}; };
@ -129,7 +120,7 @@ public:
CSM_RATSNEST CSM_RATSNEST
}; };
using CLUSTERS = std::vector<CN_CLUSTER_PTR>; using CLUSTERS = std::vector<std::shared_ptr<CN_CLUSTER>>;
class ITEM_MAP_ENTRY class ITEM_MAP_ENTRY
{ {
@ -142,10 +133,8 @@ public:
void MarkItemsAsInvalid() void MarkItemsAsInvalid()
{ {
for( auto item : m_items ) for( CN_ITEM* item : m_items )
{
item->SetValid( false ); item->SetValid( false );
}
} }
void Link( CN_ITEM* aItem ) void Link( CN_ITEM* aItem )
@ -184,13 +173,13 @@ public:
void ClearDirtyFlags() void ClearDirtyFlags()
{ {
for( auto i = m_dirtyNets.begin(); i != m_dirtyNets.end(); ++i ) for( bool dirty : m_dirtyNets )
*i = false; dirty = false;
} }
void GetDirtyClusters( CLUSTERS& aClusters ) const void GetDirtyClusters( CLUSTERS& aClusters ) const
{ {
for( const auto& cl : m_ratsnestClusters ) for( const std::shared_ptr<CN_CLUSTER>& cl : m_ratsnestClusters )
{ {
int net = cl->OriginNet(); int net = cl->OriginNet();
@ -246,9 +235,9 @@ public:
template <typename Func> template <typename Func>
void ForEachAnchor( Func&& aFunc ) const void ForEachAnchor( Func&& aFunc ) const
{ {
for( auto&& item : m_itemList ) for( CN_ITEM* item : m_itemList )
{ {
for( auto&& anchor : item->Anchors() ) for( std::shared_ptr<CN_ANCHOR>& anchor : item->Anchors() )
aFunc( *anchor ); aFunc( *anchor );
} }
} }
@ -256,7 +245,7 @@ public:
template <typename Func> template <typename Func>
void ForEachItem( Func&& aFunc ) const void ForEachItem( Func&& aFunc ) const
{ {
for( auto&& item : m_itemList ) for( CN_ITEM* item : m_itemList )
aFunc( *item ); aFunc( *item );
} }
@ -272,7 +261,7 @@ private:
template <class Container, class BItem> template <class Container, class BItem>
void add( Container& c, BItem brditem ) void add( Container& c, BItem brditem )
{ {
auto item = c.Add( brditem ); CN_ITEM* item = c.Add( brditem );
m_itemMap[ brditem ] = ITEM_MAP_ENTRY( item ); m_itemMap[ brditem ] = ITEM_MAP_ENTRY( item );
} }

View File

@ -2,7 +2,7 @@
* This program source code file is part of KICAD, a free EDA CAD application. * This program source code file is part of KICAD, a free EDA CAD application.
* *
* Copyright (C) 2017 CERN * Copyright (C) 2017 CERN
* Copyright (C) 2018-2020 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2018-2022 KiCad Developers, see AUTHORS.txt for contributors.
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch> * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
@ -214,7 +214,7 @@ void CONNECTIVITY_DATA::RecalculateRatsnest( BOARD_COMMIT* aCommit )
m_nets[i] = new RN_NET; m_nets[i] = new RN_NET;
} }
const std::vector<CN_CLUSTER_PTR>& clusters = m_connAlgo->GetClusters(); const std::vector<std::shared_ptr<CN_CLUSTER>>& clusters = m_connAlgo->GetClusters();
int dirtyNets = 0; int dirtyNets = 0;
@ -227,7 +227,7 @@ void CONNECTIVITY_DATA::RecalculateRatsnest( BOARD_COMMIT* aCommit )
} }
} }
for( const CN_CLUSTER_PTR& c : clusters ) for( const std::shared_ptr<CN_CLUSTER>& c : clusters )
{ {
int net = c->OriginNet(); int net = c->OriginNet();
@ -322,14 +322,14 @@ void CONNECTIVITY_DATA::ComputeDynamicRatsnest( const std::vector<BOARD_ITEM*>&
if( dynNet->GetNodeCount() != 0 ) if( dynNet->GetNodeCount() != 0 )
{ {
RN_NET* ourNet = m_nets[nc]; RN_NET* ourNet = m_nets[nc];
CN_ANCHOR_PTR nodeA, nodeB; VECTOR2I pos1, pos2;
if( ourNet->NearestBicoloredPair( *dynNet, nodeA, nodeB ) ) if( ourNet->NearestBicoloredPair( *dynNet, &pos1, &pos2 ) )
{ {
RN_DYNAMIC_LINE l; RN_DYNAMIC_LINE l;
l.a = nodeA->Pos(); l.a = pos1;
l.b = nodeB->Pos(); l.b = pos2;
l.netCode = nc; l.netCode = nc;
m_dynamicRatsnest.push_back( l ); m_dynamicRatsnest.push_back( l );
@ -342,9 +342,9 @@ void CONNECTIVITY_DATA::ComputeDynamicRatsnest( const std::vector<BOARD_ITEM*>&
for( const CN_EDGE& edge : edges ) for( const CN_EDGE& edge : edges )
{ {
const CN_ANCHOR_PTR& nodeA = edge.GetSourceNode(); const std::shared_ptr<CN_ANCHOR>& nodeA = edge.GetSourceNode();
const CN_ANCHOR_PTR& nodeB = edge.GetTargetNode(); const std::shared_ptr<CN_ANCHOR>& nodeB = edge.GetTargetNode();
RN_DYNAMIC_LINE l; RN_DYNAMIC_LINE l;
// Use the parents' positions // Use the parents' positions
l.a = nodeA->Parent()->GetPosition() + aInternalOffset; l.a = nodeA->Parent()->GetPosition() + aInternalOffset;

View File

@ -155,9 +155,6 @@ private:
}; };
typedef std::shared_ptr<CN_ANCHOR> CN_ANCHOR_PTR;
typedef std::vector<CN_ANCHOR_PTR> CN_ANCHORS;
/** /**
* CN_ITEM represents a BOARD_CONNETED_ITEM in the connectivity system (ie: a pad, track/arc/via, * CN_ITEM represents a BOARD_CONNETED_ITEM in the connectivity system (ie: a pad, track/arc/via,
@ -166,8 +163,6 @@ typedef std::vector<CN_ANCHOR_PTR> CN_ANCHORS;
class CN_ITEM class CN_ITEM
{ {
public: public:
using CONNECTED_ITEMS = std::vector<CN_ITEM*>;
void Dump(); void Dump();
CN_ITEM( BOARD_CONNECTED_ITEM* aParent, bool aCanChangeNet, int aAnchorCount = 2 ) CN_ITEM( BOARD_CONNECTED_ITEM* aParent, bool aCanChangeNet, int aAnchorCount = 2 )
@ -189,7 +184,7 @@ public:
m_anchors.emplace_back( std::make_shared<CN_ANCHOR>( aPos, this ) ); m_anchors.emplace_back( std::make_shared<CN_ANCHOR>( aPos, this ) );
} }
CN_ANCHORS& Anchors() { return m_anchors; } std::vector<std::shared_ptr<CN_ANCHOR>>& Anchors() { return m_anchors; }
void SetValid( bool aValid ) { m_valid = aValid; } void SetValid( bool aValid ) { m_valid = aValid; }
bool Valid() const { return m_valid; } bool Valid() const { return m_valid; }
@ -233,7 +228,7 @@ public:
BOARD_CONNECTED_ITEM* Parent() const { return m_parent; } BOARD_CONNECTED_ITEM* Parent() const { return m_parent; }
const CONNECTED_ITEMS& ConnectedItems() const { return m_connected; } const std::vector<CN_ITEM*>& ConnectedItems() const { return m_connected; }
void ClearConnections() { m_connected.clear(); } void ClearConnections() { m_connected.clear(); }
void SetVisited( bool aVisited ) { m_visited = aVisited; } void SetVisited( bool aVisited ) { m_visited = aVisited; }
@ -270,10 +265,10 @@ protected:
BOX2I m_bbox; ///< bounding box for the item BOX2I m_bbox; ///< bounding box for the item
private: private:
BOARD_CONNECTED_ITEM* m_parent; BOARD_CONNECTED_ITEM* m_parent;
CONNECTED_ITEMS m_connected; ///< list of items physically connected (touching) std::vector<CN_ITEM*> m_connected; ///< list of physically touching items
CN_ANCHORS m_anchors; std::vector<std::shared_ptr<CN_ANCHOR>> m_anchors;
bool m_canChangeNet; ///< can the net propagator modify the netcode? bool m_canChangeNet; ///< can the net propagator modify the netcode?
@ -474,7 +469,6 @@ public:
ITER end() { return m_items.end(); }; ITER end() { return m_items.end(); };
}; };
typedef std::shared_ptr<CN_CLUSTER> CN_CLUSTER_PTR;
#endif /* PCBNEW_CONNECTIVITY_ITEMS_H */ #endif /* PCBNEW_CONNECTIVITY_ITEMS_H */

View File

@ -1,7 +1,7 @@
/* /*
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2004-2020 KiCad Developers. * Copyright (C) 2004-2022 KiCad Developers.
* *
* This program is free software: you can redistribute it and/or modify it * This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the * under the terms of the GNU General Public License as published by the
@ -88,8 +88,10 @@ static PATH_STATUS uniquePathBetweenNodes( CN_ITEM* u, CN_ITEM* v, std::vector<C
if( last == v ) if( last == v )
{ {
outPath = path; outPath = path;
if( pathFound ) if( pathFound )
return PS_MULTIPLE_PATHS; return PS_MULTIPLE_PATHS;
pathFound = true; pathFound = true;
} }
@ -119,11 +121,11 @@ static PATH_STATUS uniquePathBetweenNodes( CN_ITEM* u, CN_ITEM* v, std::vector<C
int FROM_TO_CACHE::cacheFromToPaths( const wxString& aFrom, const wxString& aTo ) int FROM_TO_CACHE::cacheFromToPaths( const wxString& aFrom, const wxString& aTo )
{ {
std::vector<FT_PATH> paths; std::vector<FT_PATH> paths;
auto connectivity = m_board->GetConnectivity(); std::shared_ptr<CONNECTIVITY_DATA> connectivity = m_board->GetConnectivity();
auto cnAlgo = connectivity->GetConnectivityAlgo(); std::shared_ptr<CN_CONNECTIVITY_ALGO> cnAlgo = connectivity->GetConnectivityAlgo();
for( auto& endpoint : m_ftEndpoints ) for( FT_ENDPOINT& endpoint : m_ftEndpoints )
{ {
if( WildCompareString( aFrom, endpoint.name, false ) ) if( WildCompareString( aFrom, endpoint.name, false ) )
{ {
@ -135,7 +137,7 @@ int FROM_TO_CACHE::cacheFromToPaths( const wxString& aFrom, const wxString& aTo
} }
} }
for( auto &path : paths ) for( FT_PATH& path : paths )
{ {
int count = 0; int count = 0;
auto netName = path.from->GetNetname(); auto netName = path.from->GetNetname();
@ -148,7 +150,7 @@ int FROM_TO_CACHE::cacheFromToPaths( const wxString& aFrom, const wxString& aTo
auto padCandidates = connectivity->GetConnectedItems( path.from, onlyRouting ); auto padCandidates = connectivity->GetConnectedItems( path.from, onlyRouting );
PAD* toPad = nullptr; PAD* toPad = nullptr;
for( auto pitem : padCandidates ) for( BOARD_CONNECTED_ITEM* pitem : padCandidates )
{ {
if( pitem == path.from ) if( pitem == path.from )
continue; continue;
@ -161,44 +163,43 @@ int FROM_TO_CACHE::cacheFromToPaths( const wxString& aFrom, const wxString& aTo
wxString toName = pad->GetParent()->GetReference() + wxT( "-" ) + pad->GetNumber(); wxString toName = pad->GetParent()->GetReference() + wxT( "-" ) + pad->GetNumber();
for ( const auto& endpoint : m_ftEndpoints ) for( const FT_ENDPOINT& endpoint : m_ftEndpoints )
{ {
if( pad == endpoint.parent ) if( pad == endpoint.parent )
{ {
if( WildCompareString( aTo, endpoint.name, false ) ) if( WildCompareString( aTo, endpoint.name, false ) )
{
count++;
toPad = endpoint.parent;
path.to = toPad;
path.fromName = fromName;
path.toName = toName;
path.fromWildcard = aFrom;
path.toWildcard = aTo;
if( count >= 2 )
{ {
count++; // fixme: report this somewhere?
toPad = endpoint.parent; //printf("Multiple targets found, aborting...\n");
path.to = nullptr;
path.to = toPad;
path.fromName = fromName;
path.toName = toName;
path.fromWildcard = aFrom;
path.toWildcard = aTo;
if( count >= 2 )
{
// fixme: report this somewhere?
//printf("Multiple targets found, aborting...\n");
path.to = nullptr;
}
} }
} }
} }
}
} }
} }
int newPaths = 0; int newPaths = 0;
for( auto &path : paths ) for( FT_PATH& path : paths )
{ {
if( !path.from || !path.to ) if( !path.from || !path.to )
continue; continue;
CN_ITEM* cnFrom = cnAlgo->ItemEntry( path.from ).GetItems().front();
CN_ITEM *cnFrom = cnAlgo->ItemEntry( path.from ).GetItems().front(); CN_ITEM* cnTo = cnAlgo->ItemEntry( path.to ).GetItems().front();
CN_ITEM *cnTo = cnAlgo->ItemEntry( path.to ).GetItems().front(); std::vector<CN_ITEM*> upath;
CN_ITEM::CONNECTED_ITEMS upath;
auto result = uniquePathBetweenNodes( cnFrom, cnTo, upath ); auto result = uniquePathBetweenNodes( cnFrom, cnTo, upath );
@ -238,19 +239,18 @@ bool FROM_TO_CACHE::IsOnFromToPath( BOARD_CONNECTED_ITEM* aItem, const wxString
for( int attempt = 0; attempt < 2; attempt++ ) for( int attempt = 0; attempt < 2; attempt++ )
{ {
// item already belongs to path // item already belongs to path
for( auto& ftPath : m_ftPaths ) for( FT_PATH& ftPath : m_ftPaths )
{ {
if( aFrom == ftPath.fromWildcard && if( aFrom == ftPath.fromWildcard && aTo == ftPath.toWildcard )
aTo == ftPath.toWildcard ) {
{ nFromTosFound++;
nFromTosFound++;
if( ftPath.pathItems.count( aItem ) ) if( ftPath.pathItems.count( aItem ) )
{ {
// printf("Found cached path for %p [%s->%s]\n", aItem, (const char *)ftPath.fromName, (const char *) ftPath.toName ); // printf("Found cached path for %p [%s->%s]\n", aItem, (const char *)ftPath.fromName, (const char *) ftPath.toName );
return true; return true;
}
} }
}
} }
if( !nFromTosFound ) if( !nFromTosFound )
@ -273,7 +273,7 @@ void FROM_TO_CACHE::Rebuild( BOARD* aBoard )
FROM_TO_CACHE::FT_PATH* FROM_TO_CACHE::QueryFromToPath( const std::set<BOARD_CONNECTED_ITEM*>& aItems ) FROM_TO_CACHE::FT_PATH* FROM_TO_CACHE::QueryFromToPath( const std::set<BOARD_CONNECTED_ITEM*>& aItems )
{ {
for( auto& ftPath : m_ftPaths ) for( FT_PATH& ftPath : m_ftPaths )
{ {
if ( ftPath.pathItems == aItems ) if ( ftPath.pathItems == aItems )
return &ftPath; return &ftPath;

View File

@ -1,7 +1,7 @@
/* /*
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2004-2020 KiCad Developers. * Copyright (C) 2004-2022 KiCad Developers.
* *
* This program is free software: you can redistribute it and/or modify it * This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the * under the terms of the GNU General Public License as published by the
@ -17,8 +17,8 @@
* with this program. If not, see <http://www.gnu.org/licenses/>. * with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef __FROM_TO_CACHE_H #ifndef FROM_TO_CACHE_H
#define __FROM_TO_CACHE_H #define FROM_TO_CACHE_H
#include <set> #include <set>
@ -32,12 +32,12 @@ public:
struct FT_ENDPOINT struct FT_ENDPOINT
{ {
wxString name; wxString name;
PAD* parent; PAD* parent;
}; };
struct FT_PATH struct FT_PATH
{ {
int net; int net;
PAD* from; PAD* from;
PAD* to; PAD* to;
wxString fromName, toName; wxString fromName, toName;
@ -61,14 +61,14 @@ public:
FT_PATH* QueryFromToPath( const std::set<BOARD_CONNECTED_ITEM*>& aItems ); FT_PATH* QueryFromToPath( const std::set<BOARD_CONNECTED_ITEM*>& aItems );
private: private:
int cacheFromToPaths( const wxString& aFrom, const wxString& aTo ); int cacheFromToPaths( const wxString& aFrom, const wxString& aTo );
void buildEndpointList(); void buildEndpointList();
private:
std::vector<FT_ENDPOINT> m_ftEndpoints; std::vector<FT_ENDPOINT> m_ftEndpoints;
std::vector<FT_PATH> m_ftPaths; std::vector<FT_PATH> m_ftPaths;
BOARD* m_board; BOARD* m_board;
}; };
#endif #endif

View File

@ -116,13 +116,13 @@ void RN_NET::kruskalMST( std::vector<CN_EDGE>& aEdges,
int i = 0; int i = 0;
for( const CN_ANCHOR_PTR& node : m_nodes ) for( const std::shared_ptr<CN_ANCHOR>& node : m_nodes )
node->SetTag( i++ ); node->SetTag( i++ );
for( CN_EDGE& tmp : aEdges ) for( CN_EDGE& tmp : aEdges )
{ {
const CN_ANCHOR_PTR& source = tmp.GetSourceNode(); const std::shared_ptr<CN_ANCHOR>& source = tmp.GetSourceNode();
const CN_ANCHOR_PTR& target = tmp.GetTargetNode(); const std::shared_ptr<CN_ANCHOR>& target = tmp.GetTargetNode();
if( dset.unite( source->GetTag(), target->GetTag() ) ) if( dset.unite( source->GetTag(), target->GetTag() ) )
{ {
@ -141,12 +141,12 @@ void RN_NET::kruskalMST( std::vector<CN_EDGE>& aEdges,
class RN_NET::TRIANGULATOR_STATE class RN_NET::TRIANGULATOR_STATE
{ {
private: private:
std::multiset<CN_ANCHOR_PTR, CN_PTR_CMP> m_allNodes; std::multiset<std::shared_ptr<CN_ANCHOR>, CN_PTR_CMP> m_allNodes;
// Checks if all nodes in aNodes lie on a single line. Requires the nodes to // Checks if all nodes in aNodes lie on a single line. Requires the nodes to
// have unique coordinates! // have unique coordinates!
bool areNodesColinear( const std::vector<CN_ANCHOR_PTR>& aNodes ) const bool areNodesColinear( const std::vector<std::shared_ptr<CN_ANCHOR>>& aNodes ) const
{ {
if ( aNodes.size() <= 2 ) if ( aNodes.size() <= 2 )
return true; return true;
@ -172,23 +172,29 @@ public:
m_allNodes.clear(); m_allNodes.clear();
} }
void AddNode( CN_ANCHOR_PTR aNode ) void AddNode( std::shared_ptr<CN_ANCHOR> aNode )
{ {
m_allNodes.insert( aNode ); m_allNodes.insert( aNode );
} }
void Triangulate( std::vector<CN_EDGE>& mstEdges ) void Triangulate( std::vector<CN_EDGE>& mstEdges )
{ {
std::vector<double> node_pts; std::vector<double> node_pts;
std::vector<CN_ANCHOR_PTR> anchors; std::vector<std::shared_ptr<CN_ANCHOR>> anchors;
std::vector< std::vector<CN_ANCHOR_PTR> > anchorChains( m_allNodes.size() ); std::vector< std::vector<std::shared_ptr<CN_ANCHOR>> > anchorChains( m_allNodes.size() );
node_pts.reserve( 2 * m_allNodes.size() ); node_pts.reserve( 2 * m_allNodes.size() );
anchors.reserve( m_allNodes.size() ); anchors.reserve( m_allNodes.size() );
CN_ANCHOR_PTR prev = nullptr; auto addEdge =
[&]( const std::shared_ptr<CN_ANCHOR>& src, const std::shared_ptr<CN_ANCHOR>& dst )
{
mstEdges.emplace_back( src, dst, src->Dist( *dst ) );
};
for( const CN_ANCHOR_PTR& n : m_allNodes ) std::shared_ptr<CN_ANCHOR> prev = nullptr;
for( const std::shared_ptr<CN_ANCHOR>& n : m_allNodes )
{ {
if( !prev || prev->Pos() != n->Pos() ) if( !prev || prev->Pos() != n->Pos() )
{ {
@ -211,11 +217,7 @@ public:
// triangulation for such set. In this case, we sort along any coordinate // triangulation for such set. In this case, we sort along any coordinate
// and chain the nodes together. // and chain the nodes together.
for( size_t i = 0; i < anchors.size() - 1; i++ ) for( size_t i = 0; i < anchors.size() - 1; i++ )
{ addEdge( anchors[i], anchors[i + 1] );
const CN_ANCHOR_PTR& src = anchors[i];
const CN_ANCHOR_PTR& dst = anchors[i + 1];
mstEdges.emplace_back( src, dst, src->Dist( *dst ) );
}
} }
else else
{ {
@ -224,17 +226,9 @@ public:
for( size_t i = 0; i < triangles.size(); i += 3 ) for( size_t i = 0; i < triangles.size(); i += 3 )
{ {
CN_ANCHOR_PTR src = anchors[triangles[i]]; addEdge( anchors[triangles[i]], anchors[triangles[i + 1]] );
CN_ANCHOR_PTR dst = anchors[triangles[i + 1]]; addEdge( anchors[triangles[i + 1]], anchors[triangles[i + 2]] );
mstEdges.emplace_back( src, dst, src->Dist( *dst ) ); addEdge( anchors[triangles[i + 2]], anchors[triangles[i]] );
src = anchors[triangles[i + 1]];
dst = anchors[triangles[i + 2]];
mstEdges.emplace_back( src, dst, src->Dist( *dst ) );
src = anchors[triangles[i + 2]];
dst = anchors[triangles[i]];
mstEdges.emplace_back( src, dst, src->Dist( *dst ) );
} }
for( size_t i = 0; i < delaunator.halfedges.size(); i++ ) for( size_t i = 0; i < delaunator.halfedges.size(); i++ )
@ -242,29 +236,27 @@ public:
if( delaunator.halfedges[i] == delaunator::INVALID_INDEX ) if( delaunator.halfedges[i] == delaunator::INVALID_INDEX )
continue; continue;
const CN_ANCHOR_PTR& src = anchors[triangles[i]]; addEdge( anchors[triangles[i]], anchors[triangles[delaunator.halfedges[i]]] );
const CN_ANCHOR_PTR& dst = anchors[triangles[delaunator.halfedges[i]]];
mstEdges.emplace_back( src, dst, src->Dist( *dst ) );
} }
} }
for( size_t i = 0; i < anchorChains.size(); i++ ) for( size_t i = 0; i < anchorChains.size(); i++ )
{ {
std::vector<CN_ANCHOR_PTR>& chain = anchorChains[i]; std::vector<std::shared_ptr<CN_ANCHOR>>& chain = anchorChains[i];
if( chain.size() < 2 ) if( chain.size() < 2 )
continue; continue;
std::sort( chain.begin(), chain.end(), std::sort( chain.begin(), chain.end(),
[] ( const CN_ANCHOR_PTR& a, const CN_ANCHOR_PTR& b ) [] ( const std::shared_ptr<CN_ANCHOR>& a, const std::shared_ptr<CN_ANCHOR>& b )
{ {
return a->GetCluster().get() < b->GetCluster().get(); return a->GetCluster().get() < b->GetCluster().get();
} ); } );
for( unsigned int j = 1; j < chain.size(); j++ ) for( unsigned int j = 1; j < chain.size(); j++ )
{ {
const CN_ANCHOR_PTR& prevNode = chain[j - 1]; const std::shared_ptr<CN_ANCHOR>& prevNode = chain[j - 1];
const CN_ANCHOR_PTR& curNode = chain[j]; const std::shared_ptr<CN_ANCHOR>& curNode = chain[j];
int weight = prevNode->GetCluster() != curNode->GetCluster() ? 1 : 0; int weight = prevNode->GetCluster() != curNode->GetCluster() ? 1 : 0;
mstEdges.emplace_back( prevNode, curNode, weight ); mstEdges.emplace_back( prevNode, curNode, weight );
} }
@ -293,9 +285,10 @@ void RN_NET::compute( const std::set< std::pair<KIID, KIID> >& aExclusions )
auto last = ++m_nodes.begin(); auto last = ++m_nodes.begin();
// There can be only one possible connection, but it is missing // There can be only one possible connection, but it is missing
CN_EDGE edge( *m_nodes.begin(), *last ); CN_EDGE edge( *m_nodes.begin(), *last );
const CN_ANCHOR_PTR& source = edge.GetSourceNode(); const std::shared_ptr<CN_ANCHOR>& source = edge.GetSourceNode();
const CN_ANCHOR_PTR& target = edge.GetTargetNode(); const std::shared_ptr<CN_ANCHOR>& target = edge.GetTargetNode();
std::pair<KIID, KIID> ids = { source->Parent()->m_Uuid, target->Parent()->m_Uuid }; std::pair<KIID, KIID> ids = { source->Parent()->m_Uuid, target->Parent()->m_Uuid };
source->SetTag( 0 ); source->SetTag( 0 );
@ -307,7 +300,7 @@ void RN_NET::compute( const std::set< std::pair<KIID, KIID> >& aExclusions )
else else
{ {
// Set tags to m_nodes as connected // Set tags to m_nodes as connected
for( const CN_ANCHOR_PTR& node : m_nodes ) for( const std::shared_ptr<CN_ANCHOR>& node : m_nodes )
node->SetTag( 0 ); node->SetTag( 0 );
} }
@ -317,7 +310,7 @@ void RN_NET::compute( const std::set< std::pair<KIID, KIID> >& aExclusions )
m_triangulator->Clear(); m_triangulator->Clear();
for( const CN_ANCHOR_PTR& n : m_nodes ) for( const std::shared_ptr<CN_ANCHOR>& n : m_nodes )
m_triangulator->AddNode( n ); m_triangulator->AddNode( n );
std::vector<CN_EDGE> triangEdges; std::vector<CN_EDGE> triangEdges;
@ -366,15 +359,14 @@ void RN_NET::Clear()
} }
void RN_NET::AddCluster( CN_CLUSTER_PTR aCluster ) void RN_NET::AddCluster( std::shared_ptr<CN_CLUSTER> aCluster )
{ {
CN_ANCHOR_PTR firstAnchor; std::shared_ptr<CN_ANCHOR> firstAnchor;
for( CN_ITEM* item : *aCluster ) for( CN_ITEM* item : *aCluster )
{ {
bool isZone = dynamic_cast<CN_ZONE_LAYER*>( item ); std::vector<std::shared_ptr<CN_ANCHOR>>& anchors = item->Anchors();
std::vector<CN_ANCHOR_PTR>& anchors = item->Anchors(); unsigned int nAnchors = dynamic_cast<CN_ZONE_LAYER*>( item ) ? 1 : anchors.size();
unsigned int nAnchors = isZone ? 1 : anchors.size();
if( nAnchors > anchors.size() ) if( nAnchors > anchors.size() )
nAnchors = anchors.size(); nAnchors = anchors.size();
@ -398,8 +390,7 @@ void RN_NET::AddCluster( CN_CLUSTER_PTR aCluster )
} }
bool RN_NET::NearestBicoloredPair( const RN_NET& aOtherNet, CN_ANCHOR_PTR& aNode1, bool RN_NET::NearestBicoloredPair( const RN_NET& aOtherNet, VECTOR2I* aPos1, VECTOR2I* aPos2 ) const
CN_ANCHOR_PTR& aNode2 ) const
{ {
bool rv = false; bool rv = false;
@ -414,10 +405,10 @@ bool RN_NET::NearestBicoloredPair( const RN_NET& aOtherNet, CN_ANCHOR_PTR& aNode
if( dist_sq < distMax_sq ) if( dist_sq < distMax_sq )
{ {
rv = true; rv = true;
distMax_sq = dist_sq; distMax_sq = dist_sq;
aNode1 = aTestNode1; *aPos1 = aTestNode1->Pos();
aNode2 = aTestNode2; *aPos2 = aTestNode2->Pos();
} }
}; };

View File

@ -46,7 +46,8 @@ class CN_CLUSTER;
struct CN_PTR_CMP struct CN_PTR_CMP
{ {
bool operator()( const CN_ANCHOR_PTR& aItem, const CN_ANCHOR_PTR& bItem ) const bool operator()( const std::shared_ptr<CN_ANCHOR>& aItem,
const std::shared_ptr<CN_ANCHOR>& bItem ) const
{ {
if( aItem->Pos().x == bItem->Pos().x ) if( aItem->Pos().x == bItem->Pos().x )
return aItem->Pos().y < bItem->Pos().y; return aItem->Pos().y < bItem->Pos().y;
@ -89,8 +90,7 @@ public:
const std::vector<CN_EDGE>& GetEdges() const { return m_rnEdges; } const std::vector<CN_EDGE>& GetEdges() const { return m_rnEdges; }
std::vector<CN_EDGE>& GetEdges() { return m_rnEdges; } std::vector<CN_EDGE>& GetEdges() { return m_rnEdges; }
bool NearestBicoloredPair( const RN_NET& aOtherNet, CN_ANCHOR_PTR& aNode1, bool NearestBicoloredPair( const RN_NET& aOtherNet, VECTOR2I* aPos1, VECTOR2I* aPos2 ) const;
CN_ANCHOR_PTR& aNode2 ) const;
protected: protected:
///< Recompute ratsnest from scratch. ///< Recompute ratsnest from scratch.
@ -101,7 +101,7 @@ protected:
const std::set< std::pair<KIID, KIID> >& aExclusions ); const std::set< std::pair<KIID, KIID> >& aExclusions );
///< Vector of nodes ///< Vector of nodes
std::multiset<CN_ANCHOR_PTR, CN_PTR_CMP> m_nodes; std::multiset<std::shared_ptr<CN_ANCHOR>, CN_PTR_CMP> m_nodes;
///< Vector of edges that make pre-defined connections ///< Vector of edges that make pre-defined connections
std::vector<CN_EDGE> m_boardEdges; std::vector<CN_EDGE> m_boardEdges;

View File

@ -177,10 +177,10 @@ void RATSNEST_VIEW_ITEM::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const
if( !edge.IsVisible() ) if( !edge.IsVisible() )
continue; continue;
const CN_ANCHOR_PTR& sourceNode = edge.GetSourceNode(); const std::shared_ptr<CN_ANCHOR>& sourceNode = edge.GetSourceNode();
const CN_ANCHOR_PTR& targetNode = edge.GetTargetNode(); const std::shared_ptr<CN_ANCHOR>& targetNode = edge.GetTargetNode();
const VECTOR2I source( sourceNode->Pos() ); const VECTOR2I source( sourceNode->Pos() );
const VECTOR2I target( targetNode->Pos() ); const VECTOR2I target( targetNode->Pos() );
if( !sourceNode->Valid() || !targetNode->Valid() ) if( !sourceNode->Valid() || !targetNode->Valid() )
continue; continue;