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() )
{
auto citem = static_cast<const BOARD_CONNECTED_ITEM*>( aItem );
const BOARD_CONNECTED_ITEM* citem = static_cast<const BOARD_CONNECTED_ITEM*>( aItem );
MarkNetAsDirty( citem->GetNetCode() );
}
else
@ -213,7 +213,7 @@ void CN_CONNECTIVITY_ALGO::searchConnections()
m_itemList.RemoveInvalidItems( garbage );
for( auto item : garbage )
for( CN_ITEM* item : garbage )
delete item;
#ifdef PROFILE
@ -266,7 +266,9 @@ void CN_CONNECTIVITY_ALGO::searchConnections()
};
if( parallelThreadCount <= 1 )
{
conn_lambda( &m_itemList, m_progressReporter );
}
else
{
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() )
{
CN_CLUSTER_PTR cluster = std::make_shared<CN_CLUSTER>();
CN_ITEM* root;
auto it = item_set.begin();
std::shared_ptr<CN_CLUSTER> cluster = std::make_shared<CN_CLUSTER>();
CN_ITEM* root;
auto it = item_set.begin();
while( it != item_set.end() && (*it)->Visited() )
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();
cluster->Add( current );
for( auto n : current->ConnectedItems() )
for( CN_ITEM* n : current->ConnectedItems() )
{
if( withinAnyNet && n->Net() != root->Net() )
continue;
@ -410,7 +412,7 @@ CN_CONNECTIVITY_ALGO::SearchClusters( CLUSTER_SEARCH_MODE aMode, const KICAD_T a
return CLUSTERS();
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();
} );
@ -585,16 +587,14 @@ void CN_CONNECTIVITY_ALGO::FindIsolatedCopperIslands( ZONE* aZone, PCB_LAYER_ID
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() )
{
for( auto z : *cluster )
for( CN_ITEM* z : *cluster )
{
if( z->Parent() == aZone && z->Layer() == aLayer )
{
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() )
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() )
{

View File

@ -2,7 +2,7 @@
* This program source code file is part of KICAD, a free EDA CAD application.
*
* 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 Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
@ -48,7 +48,6 @@
#include <connectivity/connectivity_data.h>
#include <connectivity/connectivity_items.h>
class CN_CONNECTIVITY_ALGO_IMPL;
class CN_RATSNEST_NODES;
class BOARD;
class BOARD_CONNECTED_ITEM;
@ -64,12 +63,17 @@ class PROGRESS_REPORTER;
class CN_EDGE
{
public:
CN_EDGE()
: m_weight( 0 ), m_visible( true )
CN_EDGE() :
m_weight( 0 ),
m_visible( true )
{}
CN_EDGE( CN_ANCHOR_PTR aSource, CN_ANCHOR_PTR aTarget, unsigned aWeight = 0 )
: m_source( aSource ), m_target( aTarget ), m_weight( aWeight ), m_visible( true )
CN_EDGE( const std::shared_ptr<CN_ANCHOR>& aSource, const std::shared_ptr<CN_ANCHOR>& aTarget,
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;
}
CN_ANCHOR_PTR GetSourceNode() const { return m_source; }
CN_ANCHOR_PTR GetTargetNode() const { return m_target; }
std::shared_ptr<CN_ANCHOR> GetSourceNode() const { return m_source; }
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; }
void SetSourceNode( const CN_ANCHOR_PTR& aNode ) { m_source = aNode; }
void SetTargetNode( const CN_ANCHOR_PTR& aNode ) { m_target = aNode; }
void SetWeight( unsigned weight ) { m_weight = weight; }
void SetVisible( bool aVisible ) { m_visible = aVisible; }
bool IsVisible() const { return m_visible; }
void SetVisible( bool aVisible )
{
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();
}
const VECTOR2I GetSourcePos() const { return m_source->Pos(); }
const VECTOR2I GetTargetPos() const { return m_target->Pos(); }
private:
CN_ANCHOR_PTR m_source;
CN_ANCHOR_PTR m_target;
unsigned m_weight;
bool m_visible;
std::shared_ptr<CN_ANCHOR> m_source;
std::shared_ptr<CN_ANCHOR> m_target;
unsigned m_weight;
bool m_visible;
};
@ -129,7 +120,7 @@ public:
CSM_RATSNEST
};
using CLUSTERS = std::vector<CN_CLUSTER_PTR>;
using CLUSTERS = std::vector<std::shared_ptr<CN_CLUSTER>>;
class ITEM_MAP_ENTRY
{
@ -142,10 +133,8 @@ public:
void MarkItemsAsInvalid()
{
for( auto item : m_items )
{
for( CN_ITEM* item : m_items )
item->SetValid( false );
}
}
void Link( CN_ITEM* aItem )
@ -184,13 +173,13 @@ public:
void ClearDirtyFlags()
{
for( auto i = m_dirtyNets.begin(); i != m_dirtyNets.end(); ++i )
*i = false;
for( bool dirty : m_dirtyNets )
dirty = false;
}
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();
@ -246,9 +235,9 @@ public:
template <typename Func>
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 );
}
}
@ -256,7 +245,7 @@ public:
template <typename Func>
void ForEachItem( Func&& aFunc ) const
{
for( auto&& item : m_itemList )
for( CN_ITEM* item : m_itemList )
aFunc( *item );
}
@ -272,7 +261,7 @@ private:
template <class Container, class BItem>
void add( Container& c, BItem brditem )
{
auto item = c.Add( brditem );
CN_ITEM* item = c.Add( brditem );
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.
*
* 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>
*
* 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;
}
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;
@ -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();
@ -322,14 +322,14 @@ void CONNECTIVITY_DATA::ComputeDynamicRatsnest( const std::vector<BOARD_ITEM*>&
if( dynNet->GetNodeCount() != 0 )
{
RN_NET* ourNet = m_nets[nc];
CN_ANCHOR_PTR nodeA, nodeB;
RN_NET* ourNet = m_nets[nc];
VECTOR2I pos1, pos2;
if( ourNet->NearestBicoloredPair( *dynNet, nodeA, nodeB ) )
if( ourNet->NearestBicoloredPair( *dynNet, &pos1, &pos2 ) )
{
RN_DYNAMIC_LINE l;
l.a = nodeA->Pos();
l.b = nodeB->Pos();
l.a = pos1;
l.b = pos2;
l.netCode = nc;
m_dynamicRatsnest.push_back( l );
@ -342,9 +342,9 @@ void CONNECTIVITY_DATA::ComputeDynamicRatsnest( const std::vector<BOARD_ITEM*>&
for( const CN_EDGE& edge : edges )
{
const CN_ANCHOR_PTR& nodeA = edge.GetSourceNode();
const CN_ANCHOR_PTR& nodeB = edge.GetTargetNode();
RN_DYNAMIC_LINE l;
const std::shared_ptr<CN_ANCHOR>& nodeA = edge.GetSourceNode();
const std::shared_ptr<CN_ANCHOR>& nodeB = edge.GetTargetNode();
RN_DYNAMIC_LINE l;
// Use the parents' positions
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,
@ -166,8 +163,6 @@ typedef std::vector<CN_ANCHOR_PTR> CN_ANCHORS;
class CN_ITEM
{
public:
using CONNECTED_ITEMS = std::vector<CN_ITEM*>;
void Dump();
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 ) );
}
CN_ANCHORS& Anchors() { return m_anchors; }
std::vector<std::shared_ptr<CN_ANCHOR>>& Anchors() { return m_anchors; }
void SetValid( bool aValid ) { m_valid = aValid; }
bool Valid() const { return m_valid; }
@ -233,7 +228,7 @@ public:
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 SetVisited( bool aVisited ) { m_visited = aVisited; }
@ -270,10 +265,10 @@ protected:
BOX2I m_bbox; ///< bounding box for the item
private:
BOARD_CONNECTED_ITEM* m_parent;
BOARD_CONNECTED_ITEM* m_parent;
CONNECTED_ITEMS m_connected; ///< list of items physically connected (touching)
CN_ANCHORS m_anchors;
std::vector<CN_ITEM*> m_connected; ///< list of physically touching items
std::vector<std::shared_ptr<CN_ANCHOR>> m_anchors;
bool m_canChangeNet; ///< can the net propagator modify the netcode?
@ -474,7 +469,6 @@ public:
ITER end() { return m_items.end(); };
};
typedef std::shared_ptr<CN_CLUSTER> CN_CLUSTER_PTR;
#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.
*
* 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
* 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 )
{
outPath = path;
if( pathFound )
return PS_MULTIPLE_PATHS;
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 )
{
std::vector<FT_PATH> paths;
auto connectivity = m_board->GetConnectivity();
auto cnAlgo = connectivity->GetConnectivityAlgo();
std::vector<FT_PATH> paths;
std::shared_ptr<CONNECTIVITY_DATA> connectivity = m_board->GetConnectivity();
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 ) )
{
@ -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;
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 );
PAD* toPad = nullptr;
for( auto pitem : padCandidates )
for( BOARD_CONNECTED_ITEM* pitem : padCandidates )
{
if( pitem == path.from )
continue;
@ -161,44 +163,43 @@ int FROM_TO_CACHE::cacheFromToPaths( const wxString& aFrom, const wxString& aTo
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( 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++;
toPad = endpoint.parent;
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;
}
// fixme: report this somewhere?
//printf("Multiple targets found, aborting...\n");
path.to = nullptr;
}
}
}
}
}
}
int newPaths = 0;
for( auto &path : paths )
for( FT_PATH& path : paths )
{
if( !path.from || !path.to )
continue;
CN_ITEM *cnFrom = cnAlgo->ItemEntry( path.from ).GetItems().front();
CN_ITEM *cnTo = cnAlgo->ItemEntry( path.to ).GetItems().front();
CN_ITEM::CONNECTED_ITEMS upath;
CN_ITEM* cnFrom = cnAlgo->ItemEntry( path.from ).GetItems().front();
CN_ITEM* cnTo = cnAlgo->ItemEntry( path.to ).GetItems().front();
std::vector<CN_ITEM*> 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++ )
{
// item already belongs to path
for( auto& ftPath : m_ftPaths )
for( FT_PATH& ftPath : m_ftPaths )
{
if( aFrom == ftPath.fromWildcard &&
aTo == ftPath.toWildcard )
{
nFromTosFound++;
if( aFrom == ftPath.fromWildcard && aTo == ftPath.toWildcard )
{
nFromTosFound++;
if( ftPath.pathItems.count( aItem ) )
{
// printf("Found cached path for %p [%s->%s]\n", aItem, (const char *)ftPath.fromName, (const char *) ftPath.toName );
return true;
}
if( ftPath.pathItems.count( aItem ) )
{
// printf("Found cached path for %p [%s->%s]\n", aItem, (const char *)ftPath.fromName, (const char *) ftPath.toName );
return true;
}
}
}
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 )
{
for( auto& ftPath : m_ftPaths )
for( FT_PATH& ftPath : m_ftPaths )
{
if ( ftPath.pathItems == aItems )
return &ftPath;

View File

@ -1,7 +1,7 @@
/*
* 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
* 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/>.
*/
#ifndef __FROM_TO_CACHE_H
#define __FROM_TO_CACHE_H
#ifndef FROM_TO_CACHE_H
#define FROM_TO_CACHE_H
#include <set>
@ -32,12 +32,12 @@ public:
struct FT_ENDPOINT
{
wxString name;
PAD* parent;
PAD* parent;
};
struct FT_PATH
{
int net;
int net;
PAD* from;
PAD* to;
wxString fromName, toName;
@ -61,14 +61,14 @@ public:
FT_PATH* QueryFromToPath( const std::set<BOARD_CONNECTED_ITEM*>& aItems );
private:
int cacheFromToPaths( const wxString& aFrom, const wxString& aTo );
void buildEndpointList();
private:
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

View File

@ -116,13 +116,13 @@ void RN_NET::kruskalMST( std::vector<CN_EDGE>& aEdges,
int i = 0;
for( const CN_ANCHOR_PTR& node : m_nodes )
for( const std::shared_ptr<CN_ANCHOR>& node : m_nodes )
node->SetTag( i++ );
for( CN_EDGE& tmp : aEdges )
{
const CN_ANCHOR_PTR& source = tmp.GetSourceNode();
const CN_ANCHOR_PTR& target = tmp.GetTargetNode();
const std::shared_ptr<CN_ANCHOR>& source = tmp.GetSourceNode();
const std::shared_ptr<CN_ANCHOR>& target = tmp.GetTargetNode();
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
{
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
// 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 )
return true;
@ -172,23 +172,29 @@ public:
m_allNodes.clear();
}
void AddNode( CN_ANCHOR_PTR aNode )
void AddNode( std::shared_ptr<CN_ANCHOR> aNode )
{
m_allNodes.insert( aNode );
}
void Triangulate( std::vector<CN_EDGE>& mstEdges )
{
std::vector<double> node_pts;
std::vector<CN_ANCHOR_PTR> anchors;
std::vector< std::vector<CN_ANCHOR_PTR> > anchorChains( m_allNodes.size() );
std::vector<double> node_pts;
std::vector<std::shared_ptr<CN_ANCHOR>> anchors;
std::vector< std::vector<std::shared_ptr<CN_ANCHOR>> > anchorChains( m_allNodes.size() );
node_pts.reserve( 2 * 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() )
{
@ -211,11 +217,7 @@ public:
// triangulation for such set. In this case, we sort along any coordinate
// and chain the nodes together.
for( size_t i = 0; i < anchors.size() - 1; i++ )
{
const CN_ANCHOR_PTR& src = anchors[i];
const CN_ANCHOR_PTR& dst = anchors[i + 1];
mstEdges.emplace_back( src, dst, src->Dist( *dst ) );
}
addEdge( anchors[i], anchors[i + 1] );
}
else
{
@ -224,17 +226,9 @@ public:
for( size_t i = 0; i < triangles.size(); i += 3 )
{
CN_ANCHOR_PTR src = anchors[triangles[i]];
CN_ANCHOR_PTR dst = anchors[triangles[i + 1]];
mstEdges.emplace_back( src, dst, src->Dist( *dst ) );
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 ) );
addEdge( anchors[triangles[i]], anchors[triangles[i + 1]] );
addEdge( anchors[triangles[i + 1]], anchors[triangles[i + 2]] );
addEdge( anchors[triangles[i + 2]], anchors[triangles[i]] );
}
for( size_t i = 0; i < delaunator.halfedges.size(); i++ )
@ -242,29 +236,27 @@ public:
if( delaunator.halfedges[i] == delaunator::INVALID_INDEX )
continue;
const CN_ANCHOR_PTR& src = anchors[triangles[i]];
const CN_ANCHOR_PTR& dst = anchors[triangles[delaunator.halfedges[i]]];
mstEdges.emplace_back( src, dst, src->Dist( *dst ) );
addEdge( anchors[triangles[i]], anchors[triangles[delaunator.halfedges[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 )
continue;
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();
} );
for( unsigned int j = 1; j < chain.size(); j++ )
{
const CN_ANCHOR_PTR& prevNode = chain[j - 1];
const CN_ANCHOR_PTR& curNode = chain[j];
const std::shared_ptr<CN_ANCHOR>& prevNode = chain[j - 1];
const std::shared_ptr<CN_ANCHOR>& curNode = chain[j];
int weight = prevNode->GetCluster() != curNode->GetCluster() ? 1 : 0;
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();
// There can be only one possible connection, but it is missing
CN_EDGE edge( *m_nodes.begin(), *last );
const CN_ANCHOR_PTR& source = edge.GetSourceNode();
const CN_ANCHOR_PTR& target = edge.GetTargetNode();
CN_EDGE edge( *m_nodes.begin(), *last );
const std::shared_ptr<CN_ANCHOR>& source = edge.GetSourceNode();
const std::shared_ptr<CN_ANCHOR>& target = edge.GetTargetNode();
std::pair<KIID, KIID> ids = { source->Parent()->m_Uuid, target->Parent()->m_Uuid };
source->SetTag( 0 );
@ -307,7 +300,7 @@ void RN_NET::compute( const std::set< std::pair<KIID, KIID> >& aExclusions )
else
{
// 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 );
}
@ -317,7 +310,7 @@ void RN_NET::compute( const std::set< std::pair<KIID, KIID> >& aExclusions )
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 );
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 )
{
bool isZone = dynamic_cast<CN_ZONE_LAYER*>( item );
std::vector<CN_ANCHOR_PTR>& anchors = item->Anchors();
unsigned int nAnchors = isZone ? 1 : anchors.size();
std::vector<std::shared_ptr<CN_ANCHOR>>& anchors = item->Anchors();
unsigned int nAnchors = dynamic_cast<CN_ZONE_LAYER*>( item ) ? 1 : anchors.size();
if( 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,
CN_ANCHOR_PTR& aNode2 ) const
bool RN_NET::NearestBicoloredPair( const RN_NET& aOtherNet, VECTOR2I* aPos1, VECTOR2I* aPos2 ) const
{
bool rv = false;
@ -414,10 +405,10 @@ bool RN_NET::NearestBicoloredPair( const RN_NET& aOtherNet, CN_ANCHOR_PTR& aNode
if( dist_sq < distMax_sq )
{
rv = true;
rv = true;
distMax_sq = dist_sq;
aNode1 = aTestNode1;
aNode2 = aTestNode2;
*aPos1 = aTestNode1->Pos();
*aPos2 = aTestNode2->Pos();
}
};

View File

@ -46,7 +46,8 @@ class CN_CLUSTER;
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 )
return aItem->Pos().y < bItem->Pos().y;
@ -89,8 +90,7 @@ public:
const std::vector<CN_EDGE>& GetEdges() const { return m_rnEdges; }
std::vector<CN_EDGE>& GetEdges() { return m_rnEdges; }
bool NearestBicoloredPair( const RN_NET& aOtherNet, CN_ANCHOR_PTR& aNode1,
CN_ANCHOR_PTR& aNode2 ) const;
bool NearestBicoloredPair( const RN_NET& aOtherNet, VECTOR2I* aPos1, VECTOR2I* aPos2 ) const;
protected:
///< Recompute ratsnest from scratch.
@ -101,7 +101,7 @@ protected:
const std::set< std::pair<KIID, KIID> >& aExclusions );
///< 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
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() )
continue;
const CN_ANCHOR_PTR& sourceNode = edge.GetSourceNode();
const CN_ANCHOR_PTR& targetNode = edge.GetTargetNode();
const VECTOR2I source( sourceNode->Pos() );
const VECTOR2I target( targetNode->Pos() );
const std::shared_ptr<CN_ANCHOR>& sourceNode = edge.GetSourceNode();
const std::shared_ptr<CN_ANCHOR>& targetNode = edge.GetTargetNode();
const VECTOR2I source( sourceNode->Pos() );
const VECTOR2I target( targetNode->Pos() );
if( !sourceNode->Valid() || !targetNode->Valid() )
continue;