pcbnew: Unify connected lists between items/zones
Keep the zoneitems in the same list as the rest of the items.
This commit is contained in:
parent
f87cb64d65
commit
284c39acac
|
@ -195,7 +195,7 @@ bool CN_CONNECTIVITY_ALGO::Remove( BOARD_ITEM* aItem )
|
|||
{
|
||||
m_itemMap[ static_cast<BOARD_CONNECTED_ITEM*>( aItem ) ].MarkItemsAsInvalid();
|
||||
m_itemMap.erase ( static_cast<BOARD_CONNECTED_ITEM*>( aItem ) );
|
||||
m_zoneList.SetDirty( true );
|
||||
m_itemList.SetDirty( true );
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -205,7 +205,6 @@ bool CN_CONNECTIVITY_ALGO::Remove( BOARD_ITEM* aItem )
|
|||
|
||||
// Once we delete an item, it may connect between lists, so mark both as potentially invalid
|
||||
m_itemList.SetHasInvalid( true );
|
||||
m_zoneList.SetHasInvalid( true );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -292,7 +291,7 @@ bool CN_CONNECTIVITY_ALGO::Add( BOARD_ITEM* aItem )
|
|||
|
||||
m_itemMap[zone] = ITEM_MAP_ENTRY();
|
||||
|
||||
for( auto zitem : m_zoneList.Add( zone ) )
|
||||
for( auto zitem : m_itemList.Add( zone ) )
|
||||
m_itemMap[zone].Link(zitem);
|
||||
|
||||
break;
|
||||
|
@ -319,7 +318,6 @@ void CN_CONNECTIVITY_ALGO::searchConnections()
|
|||
garbage.reserve( 1024 );
|
||||
|
||||
m_itemList.RemoveInvalidItems( garbage );
|
||||
m_zoneList.RemoveInvalidItems( garbage );
|
||||
|
||||
for( auto item : garbage )
|
||||
delete item;
|
||||
|
@ -332,8 +330,7 @@ void CN_CONNECTIVITY_ALGO::searchConnections()
|
|||
|
||||
if( m_progressReporter )
|
||||
{
|
||||
m_progressReporter->SetMaxProgress(
|
||||
m_zoneList.Size() + ( m_itemList.IsDirty() ? m_itemList.Size() : 0 ) );
|
||||
m_progressReporter->SetMaxProgress( m_itemList.IsDirty() ? m_itemList.Size() : 0 );
|
||||
}
|
||||
|
||||
#ifdef USE_OPENMP
|
||||
|
@ -355,7 +352,6 @@ void CN_CONNECTIVITY_ALGO::searchConnections()
|
|||
{
|
||||
CN_VISITOR visitor( item, &m_listLock );
|
||||
m_itemList.FindNearby( item, visitor );
|
||||
m_zoneList.FindNearby( item, visitor );
|
||||
}
|
||||
|
||||
if( m_progressReporter )
|
||||
|
@ -367,30 +363,10 @@ void CN_CONNECTIVITY_ALGO::searchConnections()
|
|||
search_basic.Show();
|
||||
#endif
|
||||
|
||||
#ifdef USE_OPENMP
|
||||
#pragma omp parallel for
|
||||
#endif
|
||||
for( int i = 0; i < m_zoneList.Size(); i++ )
|
||||
{
|
||||
auto item = m_zoneList[i];
|
||||
auto zoneItem = static_cast<CN_ZONE *>( item );
|
||||
|
||||
if( zoneItem->Dirty() )
|
||||
{
|
||||
CN_VISITOR visitor( item, &m_listLock );
|
||||
m_itemList.FindNearby( item, visitor );
|
||||
m_zoneList.FindNearby( item, visitor );
|
||||
}
|
||||
|
||||
if( m_progressReporter )
|
||||
m_progressReporter->AdvanceProgress();
|
||||
}
|
||||
|
||||
#ifdef USE_OPENMP
|
||||
}
|
||||
#endif
|
||||
|
||||
m_zoneList.ClearDirtyFlags();
|
||||
m_itemList.ClearDirtyFlags();
|
||||
|
||||
#ifdef CONNECTIVITY_DEBUG
|
||||
|
@ -405,11 +381,13 @@ void CN_CONNECTIVITY_ALGO::searchConnections()
|
|||
|
||||
void CN_ITEM::RemoveInvalidRefs()
|
||||
{
|
||||
auto lastConn = std::remove_if(m_connected.begin(), m_connected.end(), [] ( CN_ITEM * item) {
|
||||
return !item->Valid();
|
||||
} );
|
||||
|
||||
m_connected.resize( lastConn - m_connected.begin() );
|
||||
for( auto it = m_connected.begin(); it != m_connected.end(); )
|
||||
{
|
||||
if( !(*it)->Valid() )
|
||||
it = m_connected.erase( it );
|
||||
else
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -444,21 +422,25 @@ void CN_LIST::RemoveInvalidItems( std::vector<CN_ITEM*>& aGarbage )
|
|||
|
||||
bool CN_CONNECTIVITY_ALGO::isDirty() const
|
||||
{
|
||||
return m_itemList.IsDirty() || m_zoneList.IsDirty();
|
||||
return m_itemList.IsDirty();
|
||||
}
|
||||
|
||||
|
||||
const CN_CONNECTIVITY_ALGO::CLUSTERS CN_CONNECTIVITY_ALGO::SearchClusters( CLUSTER_SEARCH_MODE aMode )
|
||||
{
|
||||
constexpr KICAD_T types[] = { PCB_TRACE_T, PCB_PAD_T, PCB_VIA_T, PCB_ZONE_AREA_T, PCB_MODULE_T, EOT };
|
||||
return SearchClusters( aMode, types, -1 );
|
||||
constexpr KICAD_T no_zones[] = { PCB_TRACE_T, PCB_PAD_T, PCB_VIA_T, PCB_MODULE_T, EOT };
|
||||
|
||||
if( aMode == CSM_PROPAGATE )
|
||||
return SearchClusters( aMode, no_zones, -1 );
|
||||
else
|
||||
return SearchClusters( aMode, types, -1 );
|
||||
}
|
||||
|
||||
|
||||
const CN_CONNECTIVITY_ALGO::CLUSTERS CN_CONNECTIVITY_ALGO::SearchClusters( CLUSTER_SEARCH_MODE aMode,
|
||||
const KICAD_T aTypes[], int aSingleNet )
|
||||
{
|
||||
bool includeZones = ( aMode != CSM_PROPAGATE );
|
||||
bool withinAnyNet = ( aMode != CSM_PROPAGATE );
|
||||
|
||||
std::deque<CN_ITEM*> Q;
|
||||
|
@ -504,12 +486,6 @@ const CN_CONNECTIVITY_ALGO::CLUSTERS CN_CONNECTIVITY_ALGO::SearchClusters( CLUST
|
|||
|
||||
std::for_each( m_itemList.begin(), m_itemList.end(), addToSearchList );
|
||||
|
||||
if( includeZones )
|
||||
{
|
||||
std::for_each( m_zoneList.begin(), m_zoneList.end(), addToSearchList );
|
||||
}
|
||||
|
||||
|
||||
while( head )
|
||||
{
|
||||
CN_CLUSTER_PTR cluster ( new CN_CLUSTER() );
|
||||
|
@ -835,6 +811,12 @@ bool CN_VISITOR::operator()( CN_ITEM* aCandidate )
|
|||
if( !( parentA->GetLayerSet() & parentB->GetLayerSet() ).any() )
|
||||
return true;
|
||||
|
||||
// If both m_item and aCandidate are marked dirty, they will both be searched
|
||||
// Since we are reciprocal in our connection, we arbitrarily pick one of the connections
|
||||
// to conduct the expensive search
|
||||
if( aCandidate->Dirty() && aCandidate < m_item )
|
||||
return true;
|
||||
|
||||
// We should handle zone-zone connection separately
|
||||
if ( ( parentA->Type() == PCB_ZONE_AREA_T || parentA->Type() == PCB_ZONE_T ) &&
|
||||
( parentB->Type() == PCB_ZONE_AREA_T || parentB->Type() == PCB_ZONE_T ) )
|
||||
|
@ -968,19 +950,14 @@ void CN_CONNECTIVITY_ALGO::Clear()
|
|||
m_connClusters.clear();
|
||||
m_itemMap.clear();
|
||||
m_itemList.Clear();
|
||||
m_zoneList.Clear();
|
||||
|
||||
}
|
||||
|
||||
|
||||
void CN_CONNECTIVITY_ALGO::ForEachItem( const std::function<void( CN_ITEM& )>& aFunc )
|
||||
{
|
||||
|
||||
for( auto item : m_itemList )
|
||||
aFunc( *item );
|
||||
|
||||
for( auto item : m_zoneList )
|
||||
aFunc( *item );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -268,7 +268,7 @@ class CN_ITEM : public INTRUSIVE_LIST<CN_ITEM>
|
|||
private:
|
||||
BOARD_CONNECTED_ITEM* m_parent;
|
||||
|
||||
using CONNECTED_ITEMS = std::vector<CN_ITEM*>;
|
||||
using CONNECTED_ITEMS = std::set<CN_ITEM*>;
|
||||
|
||||
///> list of items physically connected (touching)
|
||||
CONNECTED_ITEMS m_connected;
|
||||
|
@ -431,33 +431,15 @@ public:
|
|||
return m_canChangeNet;
|
||||
}
|
||||
|
||||
bool isConnected( CN_ITEM* aItem ) const
|
||||
{
|
||||
return ( m_connected.find( aItem ) != m_connected.end() );
|
||||
}
|
||||
|
||||
static void Connect( CN_ITEM* a, CN_ITEM* b )
|
||||
{
|
||||
bool foundA = false, foundB = false;
|
||||
|
||||
for( auto item : a->m_connected )
|
||||
{
|
||||
if( item == b )
|
||||
{
|
||||
foundA = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for( auto item : b->m_connected )
|
||||
{
|
||||
if( item == a )
|
||||
{
|
||||
foundB = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( !foundA )
|
||||
a->m_connected.push_back( b );
|
||||
|
||||
if( !foundB )
|
||||
b->m_connected.push_back( a );
|
||||
a->m_connected.insert( b );
|
||||
b->m_connected.insert( a );
|
||||
}
|
||||
|
||||
void RemoveInvalidRefs();
|
||||
|
@ -470,6 +452,53 @@ public:
|
|||
|
||||
typedef std::shared_ptr<CN_ITEM> CN_ITEM_PTR;
|
||||
|
||||
class CN_ZONE : public CN_ITEM
|
||||
{
|
||||
public:
|
||||
CN_ZONE( ZONE_CONTAINER* aParent, bool aCanChangeNet, int aSubpolyIndex ) :
|
||||
CN_ITEM( aParent, aCanChangeNet ),
|
||||
m_subpolyIndex( aSubpolyIndex )
|
||||
{
|
||||
SHAPE_LINE_CHAIN outline = aParent->GetFilledPolysList().COutline( aSubpolyIndex );
|
||||
|
||||
outline.SetClosed( true );
|
||||
outline.Simplify();
|
||||
|
||||
m_cachedPoly.reset( new POLY_GRID_PARTITION( outline, 16 ) );
|
||||
}
|
||||
|
||||
int SubpolyIndex() const
|
||||
{
|
||||
return m_subpolyIndex;
|
||||
}
|
||||
|
||||
bool ContainsAnchor( const CN_ANCHOR_PTR anchor ) const
|
||||
{
|
||||
return ContainsPoint( anchor->Pos() );
|
||||
}
|
||||
|
||||
bool ContainsPoint( const VECTOR2I p ) const
|
||||
{
|
||||
auto zone = static_cast<ZONE_CONTAINER*> ( Parent() );
|
||||
return m_cachedPoly->ContainsPoint( p, zone->GetMinThickness() );
|
||||
}
|
||||
|
||||
const BOX2I& BBox()
|
||||
{
|
||||
if( m_dirty )
|
||||
m_bbox = m_cachedPoly->BBox();
|
||||
|
||||
return m_bbox;
|
||||
}
|
||||
|
||||
virtual int AnchorCount() const override;
|
||||
virtual const VECTOR2I GetAnchor( int n ) const override;
|
||||
|
||||
private:
|
||||
std::vector<VECTOR2I> m_testOutlinePoints;
|
||||
std::unique_ptr<POLY_GRID_PARTITION> m_cachedPoly;
|
||||
int m_subpolyIndex;
|
||||
};
|
||||
|
||||
class CN_LIST
|
||||
{
|
||||
|
@ -608,62 +637,6 @@ public:
|
|||
SetDirty();
|
||||
return item;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class CN_ZONE : public CN_ITEM
|
||||
{
|
||||
public:
|
||||
CN_ZONE( ZONE_CONTAINER* aParent, bool aCanChangeNet, int aSubpolyIndex ) :
|
||||
CN_ITEM( aParent, aCanChangeNet ),
|
||||
m_subpolyIndex( aSubpolyIndex )
|
||||
{
|
||||
SHAPE_LINE_CHAIN outline = aParent->GetFilledPolysList().COutline( aSubpolyIndex );
|
||||
|
||||
outline.SetClosed( true );
|
||||
outline.Simplify();
|
||||
|
||||
m_cachedPoly.reset( new POLY_GRID_PARTITION( outline, 16 ) );
|
||||
}
|
||||
|
||||
int SubpolyIndex() const
|
||||
{
|
||||
return m_subpolyIndex;
|
||||
}
|
||||
|
||||
bool ContainsAnchor( const CN_ANCHOR_PTR anchor ) const
|
||||
{
|
||||
return ContainsPoint( anchor->Pos() );
|
||||
}
|
||||
|
||||
bool ContainsPoint( const VECTOR2I p ) const
|
||||
{
|
||||
auto zone = static_cast<ZONE_CONTAINER*> ( Parent() );
|
||||
return m_cachedPoly->ContainsPoint( p, zone->GetMinThickness() );
|
||||
}
|
||||
|
||||
const BOX2I& BBox()
|
||||
{
|
||||
if( m_dirty )
|
||||
m_bbox = m_cachedPoly->BBox();
|
||||
|
||||
return m_bbox;
|
||||
}
|
||||
|
||||
virtual int AnchorCount() const override;
|
||||
virtual const VECTOR2I GetAnchor( int n ) const override;
|
||||
|
||||
private:
|
||||
std::vector<VECTOR2I> m_testOutlinePoints;
|
||||
std::unique_ptr<POLY_GRID_PARTITION> m_cachedPoly;
|
||||
int m_subpolyIndex;
|
||||
};
|
||||
|
||||
|
||||
class CN_ZONE_LIST : public CN_LIST
|
||||
{
|
||||
public:
|
||||
CN_ZONE_LIST() {}
|
||||
|
||||
const std::vector<CN_ITEM*> Add( ZONE_CONTAINER* zone )
|
||||
{
|
||||
|
@ -742,7 +715,6 @@ public:
|
|||
|
||||
std::mutex m_listLock;
|
||||
CN_LIST m_itemList;
|
||||
CN_ZONE_LIST m_zoneList;
|
||||
|
||||
using ITEM_MAP_PAIR = std::pair <const BOARD_CONNECTED_ITEM*, ITEM_MAP_ENTRY>;
|
||||
|
||||
|
|
Loading…
Reference in New Issue