router: rework ITEM ownership model.
- prerequisite for holes as first class objects code - introduced the OWNABLE_ITEM interface that defines the owning container (NODE/other ITEM/ITEM_SET) - simplified the ITEM_SET interface - constified a lot of APIs (ownership/JOINT management) as a side effect Rebased and cleaned up by Jeff Young <jeff@rokeby.ie> 5 April 2023 - some STL cover types removed
This commit is contained in:
parent
eed05191a9
commit
1283c4713f
|
@ -56,7 +56,7 @@ bool COMPONENT_DRAGGER::Start( const VECTOR2I& aP, ITEM_SET& aPrimitives )
|
|||
std::unordered_set<LINKED_ITEM*> seenItems;
|
||||
|
||||
auto addLinked =
|
||||
[&]( SOLID* aSolid, JOINT* aJoint, LINKED_ITEM* aItem, VECTOR2I aOffset = {} )
|
||||
[&]( SOLID* aSolid, const JOINT* aJoint, LINKED_ITEM* aItem, VECTOR2I aOffset = {} )
|
||||
{
|
||||
if( seenItems.count( aItem ) )
|
||||
return;
|
||||
|
@ -66,13 +66,13 @@ bool COMPONENT_DRAGGER::Start( const VECTOR2I& aP, ITEM_SET& aPrimitives )
|
|||
// Segments that go directly between two linked pads are special-cased
|
||||
VECTOR2I otherEnd = ( aJoint->Pos() == aItem->Anchor( 0 ) ) ?
|
||||
aItem->Anchor( 1 ) : aItem->Anchor( 0 );
|
||||
JOINT* otherJoint = m_world->FindJoint( otherEnd, aItem->Layer(), aItem->Net() );
|
||||
const JOINT* otherJoint = m_world->FindJoint( otherEnd, aItem->Layer(), aItem->Net() );
|
||||
|
||||
if( otherJoint && otherJoint->LinkCount( ITEM::SOLID_T ) )
|
||||
{
|
||||
for( const ITEM_SET::ENTRY& otherItem : otherJoint->LinkList() )
|
||||
for( ITEM* otherItem : otherJoint->LinkList() )
|
||||
{
|
||||
if( aPrimitives.Contains( otherItem.item ) )
|
||||
if( aPrimitives.Contains( otherItem ) )
|
||||
{
|
||||
m_fixedItems.insert( aItem );
|
||||
return;
|
||||
|
@ -89,17 +89,17 @@ bool COMPONENT_DRAGGER::Start( const VECTOR2I& aP, ITEM_SET& aPrimitives )
|
|||
|
||||
// Lines that go directly between two linked pads are also special-cased
|
||||
const SHAPE_LINE_CHAIN& line = cn.origLine.CLine();
|
||||
JOINT* jA = m_world->FindJoint( line.CPoint( 0 ), aItem->Layer(), aItem->Net() );
|
||||
JOINT* jB = m_world->FindJoint( line.CPoint( -1 ), aItem->Layer(), aItem->Net() );
|
||||
const JOINT* jA = m_world->FindJoint( line.CPoint( 0 ), aItem->Layer(), aItem->Net() );
|
||||
const JOINT* jB = m_world->FindJoint( line.CPoint( -1 ), aItem->Layer(), aItem->Net() );
|
||||
|
||||
wxASSERT( jA == aJoint || jB == aJoint );
|
||||
JOINT* jSearch = ( jA == aJoint ) ? jB : jA;
|
||||
const JOINT* jSearch = ( jA == aJoint ) ? jB : jA;
|
||||
|
||||
if( jSearch && jSearch->LinkCount( ITEM::SOLID_T ) )
|
||||
{
|
||||
for( const ITEM_SET::ENTRY& otherItem : jSearch->LinkList() )
|
||||
for( ITEM* otherItem : jSearch->LinkList() )
|
||||
{
|
||||
if( aPrimitives.Contains( otherItem.item ) )
|
||||
if( aPrimitives.Contains( otherItem ) )
|
||||
{
|
||||
for( ITEM* item : cn.origLine.Links() )
|
||||
m_fixedItems.insert( item );
|
||||
|
@ -114,22 +114,22 @@ bool COMPONENT_DRAGGER::Start( const VECTOR2I& aP, ITEM_SET& aPrimitives )
|
|||
|
||||
for( auto item : aPrimitives.Items() )
|
||||
{
|
||||
if( item.item->Kind() != ITEM::SOLID_T )
|
||||
if( item->Kind() != ITEM::SOLID_T )
|
||||
continue;
|
||||
|
||||
SOLID* solid = static_cast<SOLID*>( item.item );
|
||||
SOLID* solid = static_cast<SOLID*>( item );
|
||||
|
||||
m_solids.insert( solid );
|
||||
|
||||
if( !item.item->IsRoutable() )
|
||||
if( !item->IsRoutable() )
|
||||
continue;
|
||||
|
||||
JOINT* jt = m_world->FindJoint( solid->Pos(), solid );
|
||||
const JOINT* jt = m_world->FindJoint( solid->Pos(), solid );
|
||||
|
||||
for( auto link : jt->LinkList() )
|
||||
{
|
||||
if( link.item->OfKind( ITEM::SEGMENT_T | ITEM::ARC_T ) )
|
||||
addLinked( solid, jt, static_cast<LINKED_ITEM*>( link.item ) );
|
||||
if( item->OfKind( ITEM::SEGMENT_T | ITEM::ARC_T ) )
|
||||
addLinked( solid, jt, static_cast<LINKED_ITEM*>( item ) );
|
||||
}
|
||||
|
||||
std::vector<JOINT*> extraJoints;
|
||||
|
@ -141,7 +141,7 @@ bool COMPONENT_DRAGGER::Start( const VECTOR2I& aP, ITEM_SET& aPrimitives )
|
|||
{
|
||||
if( extraJoint->Net() == jt->Net() && extraJoint->LinkCount() == 1 )
|
||||
{
|
||||
LINKED_ITEM* li = static_cast<LINKED_ITEM*>( extraJoint->LinkList()[0].item );
|
||||
LINKED_ITEM* li = static_cast<LINKED_ITEM*>( extraJoint->LinkList().front() );
|
||||
|
||||
if( li->Collide( solid, m_world ) )
|
||||
addLinked( solid, extraJoint, li, extraJoint->Pos() - solid->Pos() );
|
||||
|
@ -160,7 +160,7 @@ bool COMPONENT_DRAGGER::Drag( const VECTOR2I& aP )
|
|||
m_world->KillChildren();
|
||||
m_currentNode = m_world->Branch();
|
||||
|
||||
for( const ITEM_SET::ENTRY& item : m_initialDraggedItems.Items() )
|
||||
for( ITEM* item : m_initialDraggedItems )
|
||||
m_currentNode->Remove( item );
|
||||
|
||||
m_draggedItems.Clear();
|
||||
|
|
|
@ -150,7 +150,7 @@ bool DIFF_PAIR_PLACER::propagateDpHeadForces ( const VECTOR2I& aP, VECTOR2I& aNe
|
|||
int iter = 0;
|
||||
bool collided = false;
|
||||
VECTOR2I force, totalForce;
|
||||
std::set<ITEM*> handled;
|
||||
std::set<const ITEM*> handled;
|
||||
|
||||
while( iter < maxIter )
|
||||
{
|
||||
|
@ -452,8 +452,8 @@ OPT_VECTOR2I getDanglingAnchor( NODE* aNode, ITEM* aItem )
|
|||
{
|
||||
ARC* a = static_cast<ARC*>( aItem );
|
||||
|
||||
JOINT* jA = aNode->FindJoint( aItem->Anchor( 0 ), aItem );
|
||||
JOINT* jB = aNode->FindJoint( aItem->Anchor( 1 ), aItem );
|
||||
const JOINT* jA = aNode->FindJoint( aItem->Anchor( 0 ), aItem );
|
||||
const JOINT* jB = aNode->FindJoint( aItem->Anchor( 1 ), aItem );
|
||||
|
||||
if( jA && jA->LinkCount() == 1 )
|
||||
return a->Arc().GetP0();
|
||||
|
@ -466,8 +466,8 @@ OPT_VECTOR2I getDanglingAnchor( NODE* aNode, ITEM* aItem )
|
|||
{
|
||||
SEGMENT* s = static_cast<SEGMENT*>( aItem );
|
||||
|
||||
JOINT* jA = aNode->FindJoint( aItem->Anchor( 0 ), aItem );
|
||||
JOINT* jB = aNode->FindJoint( aItem->Anchor( 1 ), aItem );
|
||||
const JOINT* jA = aNode->FindJoint( aItem->Anchor( 0 ), aItem );
|
||||
const JOINT* jB = aNode->FindJoint( aItem->Anchor( 1 ), aItem );
|
||||
|
||||
if( jA && jA->LinkCount() == 1 )
|
||||
return s->Seg().A;
|
||||
|
|
|
@ -90,19 +90,15 @@ VVIA* DRAGGER::checkVirtualVia( const VECTOR2D& aP, SEGMENT* aSeg )
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
JOINT *jt = m_world->FindJoint( psnap, aSeg );
|
||||
const JOINT *jt = m_world->FindJoint( psnap, aSeg );
|
||||
|
||||
if ( !jt )
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
for( auto& lnk : jt->LinkList() )
|
||||
for( ITEM* item : jt->LinkList() )
|
||||
{
|
||||
if( lnk.item->IsVirtual() && lnk.item->OfKind( ITEM::VIA_T ))
|
||||
{
|
||||
return static_cast<VVIA*>( lnk.item );
|
||||
}
|
||||
if( item->IsVirtual() && item->OfKind( ITEM::VIA_T ))
|
||||
return static_cast<VVIA*>( item );
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
@ -175,7 +171,7 @@ const ITEM_SET DRAGGER::findViaFanoutByHandle ( NODE *aNode, const VIA_HANDLE& h
|
|||
{
|
||||
ITEM_SET rv;
|
||||
|
||||
JOINT* jt = aNode->FindJoint( handle.pos, handle.layers.Start(), handle.net );
|
||||
const JOINT* jt = aNode->FindJoint( handle.pos, handle.layers.Start(), handle.net );
|
||||
|
||||
if( !jt )
|
||||
return rv;
|
||||
|
|
|
@ -56,13 +56,53 @@ struct COLLISION_SEARCH_OPTIONS
|
|||
bool m_useClearanceEpsilon = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Dummy interface for ITEMs that can own other ITEMs
|
||||
*/
|
||||
class ITEM_OWNER {};
|
||||
|
||||
/**
|
||||
* Base class for an item belonging to some container.
|
||||
*
|
||||
* Container can be another ITEM, ITEM_SET or a NODE.
|
||||
*/
|
||||
class OWNABLE_ITEM
|
||||
{
|
||||
public:
|
||||
OWNABLE_ITEM() :
|
||||
m_owner( nullptr )
|
||||
{}
|
||||
|
||||
/**
|
||||
* Return the owner of this item, or NULL if there's none.
|
||||
*/
|
||||
const ITEM_OWNER* Owner() const { return m_owner; }
|
||||
|
||||
/**
|
||||
* Set the node that owns this item. An item can belong to a single NODE or be unowned.
|
||||
*/
|
||||
void SetOwner( const ITEM_OWNER* aOwner ) { m_owner = aOwner; }
|
||||
|
||||
/**
|
||||
* @return true if the item is owned by the node aNode.
|
||||
*/
|
||||
bool BelongsTo( const ITEM_OWNER* aNode ) const
|
||||
{
|
||||
return m_owner == aNode;
|
||||
}
|
||||
|
||||
protected:
|
||||
const ITEM_OWNER *m_owner;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Base class for PNS router board items.
|
||||
*
|
||||
* Implements the shared properties of all PCB items net, spanned layers, geometric shape and
|
||||
* reference to owning model.
|
||||
*/
|
||||
class ITEM
|
||||
class ITEM : public OWNABLE_ITEM, public ITEM_OWNER
|
||||
{
|
||||
public:
|
||||
static const int UnusedNet = INT_MAX;
|
||||
|
@ -177,24 +217,6 @@ public:
|
|||
return Layers().Overlaps( aOther->Layers() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the owner of this item, or NULL if there's none.
|
||||
*/
|
||||
NODE* Owner() const { return m_owner; }
|
||||
|
||||
/**
|
||||
* Set the node that owns this item. An item can belong to a single NODE or be unowned.
|
||||
*/
|
||||
void SetOwner( NODE* aOwner ) { m_owner = aOwner; }
|
||||
|
||||
/**
|
||||
* @return true if the item is owned by the node aNode.
|
||||
*/
|
||||
bool BelongsTo( NODE* aNode ) const
|
||||
{
|
||||
return m_owner == aNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for a collision (clearance violation) with between us and item \a aOther.
|
||||
*
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* KiRouter - a push-and-(sometimes-)shove PCB router
|
||||
*
|
||||
* Copyright (C) 2013-2014 CERN
|
||||
* Copyright (C) 2016 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2016-2023 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 modify it
|
||||
|
@ -32,20 +32,22 @@ ITEM_SET::~ITEM_SET()
|
|||
void ITEM_SET::Add( const LINE& aLine )
|
||||
{
|
||||
LINE* copy = aLine.Clone();
|
||||
m_items.emplace_back( ENTRY( copy, true ) );
|
||||
copy->SetOwner( this );
|
||||
m_items.emplace_back( copy );
|
||||
}
|
||||
|
||||
|
||||
void ITEM_SET::Prepend( const LINE& aLine )
|
||||
{
|
||||
LINE* copy = aLine.Clone();
|
||||
m_items.emplace( m_items.begin(), ENTRY( copy, true ) );
|
||||
copy->SetOwner( this );
|
||||
m_items.emplace( m_items.begin(), copy );
|
||||
}
|
||||
|
||||
|
||||
ITEM_SET& ITEM_SET::FilterLayers( int aStart, int aEnd, bool aInvert )
|
||||
{
|
||||
ENTRIES newItems;
|
||||
std::vector<ITEM*> newItems;
|
||||
LAYER_RANGE l;
|
||||
|
||||
if( aEnd < 0 )
|
||||
|
@ -53,10 +55,10 @@ ITEM_SET& ITEM_SET::FilterLayers( int aStart, int aEnd, bool aInvert )
|
|||
else
|
||||
l = LAYER_RANGE( aStart, aEnd );
|
||||
|
||||
for( const ENTRY& ent : m_items )
|
||||
for( ITEM* item : m_items )
|
||||
{
|
||||
if( ent.item->Layers().Overlaps( l ) ^ aInvert )
|
||||
newItems.push_back( ent );
|
||||
if( item->Layers().Overlaps( l ) ^ aInvert )
|
||||
newItems.push_back( item );
|
||||
}
|
||||
|
||||
m_items = newItems;
|
||||
|
@ -67,12 +69,12 @@ ITEM_SET& ITEM_SET::FilterLayers( int aStart, int aEnd, bool aInvert )
|
|||
|
||||
ITEM_SET& ITEM_SET::FilterKinds( int aKindMask, bool aInvert )
|
||||
{
|
||||
ENTRIES newItems;
|
||||
std::vector<ITEM*> newItems;
|
||||
|
||||
for( const ENTRY& ent : m_items )
|
||||
for( ITEM *item : m_items )
|
||||
{
|
||||
if( ent.item->OfKind( aKindMask ) ^ aInvert )
|
||||
newItems.push_back( ent );
|
||||
if( item->OfKind( aKindMask ) ^ aInvert )
|
||||
newItems.push_back( item );
|
||||
}
|
||||
|
||||
m_items = newItems;
|
||||
|
@ -83,12 +85,12 @@ ITEM_SET& ITEM_SET::FilterKinds( int aKindMask, bool aInvert )
|
|||
|
||||
ITEM_SET& ITEM_SET::FilterMarker( int aMarker, bool aInvert )
|
||||
{
|
||||
ENTRIES newItems;
|
||||
std::vector<ITEM*> newItems;
|
||||
|
||||
for( const ENTRY& ent : m_items )
|
||||
for( ITEM* item : m_items )
|
||||
{
|
||||
if( ent.item->Marker() & aMarker )
|
||||
newItems.push_back( ent );
|
||||
if( item->Marker() & aMarker )
|
||||
newItems.push_back( item );
|
||||
}
|
||||
|
||||
m_items = newItems;
|
||||
|
@ -99,12 +101,12 @@ ITEM_SET& ITEM_SET::FilterMarker( int aMarker, bool aInvert )
|
|||
|
||||
ITEM_SET& ITEM_SET::FilterNet( int aNet, bool aInvert )
|
||||
{
|
||||
ENTRIES newItems;
|
||||
std::vector<ITEM*> newItems;
|
||||
|
||||
for( const ENTRY& ent : m_items )
|
||||
for( ITEM *item : m_items )
|
||||
{
|
||||
if( ( ent.item->Net() == aNet ) ^ aInvert )
|
||||
newItems.push_back( ent );
|
||||
if( ( item->Net() == aNet ) ^ aInvert )
|
||||
newItems.push_back( item );
|
||||
}
|
||||
|
||||
m_items = newItems;
|
||||
|
@ -115,12 +117,12 @@ ITEM_SET& ITEM_SET::FilterNet( int aNet, bool aInvert )
|
|||
|
||||
ITEM_SET& ITEM_SET::ExcludeItem( const ITEM* aItem )
|
||||
{
|
||||
ENTRIES newItems;
|
||||
std::vector<ITEM*> newItems;
|
||||
|
||||
for( const ENTRY& ent : m_items )
|
||||
for( ITEM* item : m_items )
|
||||
{
|
||||
if( ent.item != aItem )
|
||||
newItems.push_back( ent );
|
||||
if( item != aItem )
|
||||
newItems.push_back( item );
|
||||
}
|
||||
|
||||
m_items = newItems;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* KiRouter - a push-and-(sometimes-)shove PCB router
|
||||
*
|
||||
* Copyright (C) 2013-2014 CERN
|
||||
* Copyright (C) 2016-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2016-2023 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 modify it
|
||||
|
@ -33,69 +33,16 @@ namespace PNS {
|
|||
*/
|
||||
class LINE;
|
||||
|
||||
class ITEM_SET
|
||||
class ITEM_SET : public ITEM_OWNER
|
||||
{
|
||||
public:
|
||||
struct ENTRY
|
||||
{
|
||||
ENTRY( ITEM* aItem, bool aOwned = false ) :
|
||||
item( aItem ),
|
||||
owned( aOwned )
|
||||
{}
|
||||
|
||||
ENTRY( const ENTRY& aOther )
|
||||
{
|
||||
owned = aOther.owned;
|
||||
|
||||
if( aOther.owned )
|
||||
item = aOther.item->Clone();
|
||||
else
|
||||
item = aOther.item;
|
||||
}
|
||||
|
||||
~ENTRY()
|
||||
{
|
||||
if( owned )
|
||||
delete item;
|
||||
}
|
||||
|
||||
bool operator==( const ENTRY& b ) const
|
||||
{
|
||||
return item == b.item;
|
||||
}
|
||||
|
||||
bool operator<( const ENTRY& b ) const
|
||||
{
|
||||
return item < b.item;
|
||||
}
|
||||
|
||||
ENTRY& operator=( const ENTRY& aOther )
|
||||
{
|
||||
owned = aOther.owned;
|
||||
|
||||
if( aOther.owned )
|
||||
item = aOther.item->Clone();
|
||||
else
|
||||
item = aOther.item;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
operator ITEM* () const
|
||||
{
|
||||
return item;
|
||||
}
|
||||
|
||||
ITEM *item;
|
||||
bool owned;
|
||||
};
|
||||
|
||||
typedef std::vector<ENTRY> ENTRIES;
|
||||
|
||||
ITEM_SET( ITEM* aInitialItem = nullptr, bool aBecomeOwner = false )
|
||||
{
|
||||
if( aInitialItem )
|
||||
m_items.emplace_back( ENTRY( aInitialItem, aBecomeOwner ) );
|
||||
m_items.emplace_back( aInitialItem );
|
||||
|
||||
if( aBecomeOwner )
|
||||
aInitialItem->SetOwner( this );
|
||||
}
|
||||
|
||||
ITEM_SET( const ITEM_SET& aOther )
|
||||
|
@ -107,7 +54,12 @@ public:
|
|||
|
||||
ITEM_SET& operator=( const ITEM_SET& aOther )
|
||||
{
|
||||
m_items = aOther.m_items;
|
||||
m_items.clear();
|
||||
m_items.reserve( aOther.m_items.size() );
|
||||
|
||||
for( ITEM* item : aOther.m_items )
|
||||
m_items.push_back( item );
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -132,8 +84,8 @@ public:
|
|||
return m_items.empty();
|
||||
}
|
||||
|
||||
ENTRIES& Items() { return m_items; }
|
||||
const ENTRIES& CItems() const { return m_items; }
|
||||
std::vector<ITEM*>& Items() { return m_items; }
|
||||
const std::vector<ITEM*>& CItems() const { return m_items; }
|
||||
|
||||
ITEM_SET& FilterLayers( int aStart, int aEnd = -1, bool aInvert = false );
|
||||
ITEM_SET& FilterKinds( int aKindMask, bool aInvert = false );
|
||||
|
@ -167,22 +119,28 @@ public:
|
|||
|
||||
ITEM* operator[]( size_t aIndex ) const
|
||||
{
|
||||
return m_items[aIndex].item;
|
||||
return m_items[aIndex];
|
||||
}
|
||||
|
||||
ENTRIES::iterator begin() { return m_items.begin(); }
|
||||
ENTRIES::iterator end() { return m_items.end(); }
|
||||
ENTRIES::const_iterator cbegin() const { return m_items.cbegin(); }
|
||||
ENTRIES::const_iterator cend() const { return m_items.cend(); }
|
||||
std::vector<ITEM*>::iterator begin() { return m_items.begin(); }
|
||||
std::vector<ITEM*>::iterator end() { return m_items.end(); }
|
||||
std::vector<ITEM*>::const_iterator cbegin() const { return m_items.cbegin(); }
|
||||
std::vector<ITEM*>::const_iterator cend() const { return m_items.cend(); }
|
||||
|
||||
void Add( ITEM* aItem, bool aBecomeOwner = false )
|
||||
{
|
||||
m_items.emplace_back( ENTRY( aItem, aBecomeOwner ) );
|
||||
m_items.emplace_back( aItem );
|
||||
|
||||
if( aBecomeOwner )
|
||||
aItem->SetOwner( this );
|
||||
}
|
||||
|
||||
void Prepend( ITEM* aItem, bool aBecomeOwner = false )
|
||||
{
|
||||
m_items.emplace( m_items.begin(), ENTRY( aItem, aBecomeOwner ) );
|
||||
m_items.emplace( m_items.begin(), aItem );
|
||||
|
||||
if( aBecomeOwner )
|
||||
aItem->SetOwner( this );
|
||||
}
|
||||
|
||||
void Clear()
|
||||
|
@ -192,14 +150,12 @@ public:
|
|||
|
||||
bool Contains( ITEM* aItem ) const
|
||||
{
|
||||
const ENTRY ent( aItem );
|
||||
return alg::contains( m_items, ent );
|
||||
return alg::contains( m_items, aItem );
|
||||
}
|
||||
|
||||
void Erase( ITEM* aItem )
|
||||
{
|
||||
ENTRY ent( aItem );
|
||||
ENTRIES::iterator f = std::find( m_items.begin(), m_items.end(), ent );
|
||||
std::vector<ITEM*>::iterator f = std::find( m_items.begin(), m_items.end(), aItem );
|
||||
|
||||
if( f != m_items.end() )
|
||||
m_items.erase( f );
|
||||
|
@ -225,7 +181,7 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
ENTRIES m_items;
|
||||
std::vector<ITEM*> m_items;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -42,8 +42,6 @@ namespace PNS {
|
|||
class JOINT : public ITEM
|
||||
{
|
||||
public:
|
||||
typedef ITEM_SET::ENTRIES LINKED_ITEMS;
|
||||
|
||||
///< Joints are hashed by their position, layers and net.
|
||||
///< Linked items are, obviously, not hashed.
|
||||
struct HASH_TAG
|
||||
|
@ -210,12 +208,12 @@ public:
|
|||
return static_cast<LINKED_ITEM*>( m_linkedItems[m_linkedItems[0] == aCurrent ? 1 : 0] );
|
||||
}
|
||||
|
||||
VIA* Via()
|
||||
VIA* Via() const
|
||||
{
|
||||
for( ITEM* item : m_linkedItems.Items() )
|
||||
for( ITEM* item : m_linkedItems.CItems() )
|
||||
{
|
||||
if( item->OfKind( VIA_T ) )
|
||||
return static_cast<VIA*>( item );
|
||||
return static_cast<VIA*>( item ); // fixme: const correctness
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
@ -238,7 +236,7 @@ public:
|
|||
return m_tag.net;
|
||||
}
|
||||
|
||||
const LINKED_ITEMS& LinkList() const
|
||||
const std::vector<ITEM*>& LinkList() const
|
||||
{
|
||||
return m_linkedItems.CItems();
|
||||
}
|
||||
|
|
|
@ -125,7 +125,7 @@ public:
|
|||
PNS::CONSTRAINT* aConstraint ) override;
|
||||
virtual wxString NetName( int aNet ) override;
|
||||
|
||||
int ClearanceEpsilon() const { return m_clearanceEpsilon; }
|
||||
int ClearanceEpsilon() const override { return m_clearanceEpsilon; }
|
||||
|
||||
void ClearCacheForItem( const PNS::ITEM* aItem ) override;
|
||||
void ClearCaches() override;
|
||||
|
@ -570,13 +570,13 @@ bool PNS_KICAD_IFACE_BASE::inheritTrackWidth( PNS::ITEM* aItem, int* aInheritedW
|
|||
return false;
|
||||
}
|
||||
|
||||
PNS::JOINT* jt = static_cast<PNS::NODE*>( aItem->Owner() )->FindJoint( p, aItem );
|
||||
const PNS::JOINT* jt = static_cast<const PNS::NODE*>( aItem->Owner() )->FindJoint( p, aItem );
|
||||
|
||||
assert( jt != nullptr );
|
||||
|
||||
int mval = INT_MAX;
|
||||
|
||||
PNS::ITEM_SET linkedSegs = jt->Links();
|
||||
PNS::ITEM_SET linkedSegs( jt->CLinks() );
|
||||
linkedSegs.ExcludeItem( aItem ).FilterKinds( PNS::ITEM::SEGMENT_T | PNS::ITEM::ARC_T );
|
||||
|
||||
for( PNS::ITEM* item : linkedSegs.Items() )
|
||||
|
|
|
@ -935,7 +935,7 @@ bool LINE_PLACER::rhShoveOnly( const VECTOR2I& aP, LINE& aNewHead, LINE& aNewTai
|
|||
if( m_endItem )
|
||||
{
|
||||
// Make sure the springback algorithm won't erase the NODE that owns m_endItem.
|
||||
m_shove->SetSpringbackDoNotTouchNode( m_endItem->Owner() );
|
||||
m_shove->SetSpringbackDoNotTouchNode( static_cast<const NODE*>( m_endItem->Owner() ) );
|
||||
}
|
||||
|
||||
LINE newHead( walkSolids );
|
||||
|
@ -1268,7 +1268,7 @@ bool LINE_PLACER::SplitAdjacentSegments( NODE* aNode, ITEM* aSeg, const VECTOR2I
|
|||
if( !aSeg->OfKind( ITEM::SEGMENT_T ) )
|
||||
return false;
|
||||
|
||||
JOINT* jt = aNode->FindJoint( aP, aSeg );
|
||||
const JOINT* jt = aNode->FindJoint( aP, aSeg );
|
||||
|
||||
if( jt && jt->LinkCount() >= 1 )
|
||||
return false;
|
||||
|
@ -1430,7 +1430,7 @@ bool LINE_PLACER::Move( const VECTOR2I& aP, ITEM* aEndItem )
|
|||
int eiDepth = -1;
|
||||
|
||||
if( aEndItem && aEndItem->Owner() )
|
||||
eiDepth = static_cast<NODE*>( aEndItem->Owner() )->Depth();
|
||||
eiDepth = static_cast<const NODE*>( aEndItem->Owner() )->Depth();
|
||||
|
||||
if( m_lastNode )
|
||||
{
|
||||
|
@ -1783,7 +1783,7 @@ void LINE_PLACER::simplifyNewLine( NODE* aNode, LINKED_ITEM* aLatest )
|
|||
std::set<ITEM*> cleanup;
|
||||
|
||||
auto processJoint =
|
||||
[&]( JOINT* aJoint, ITEM* aItem )
|
||||
[&]( const JOINT* aJoint, ITEM* aItem )
|
||||
{
|
||||
if( !aJoint || aJoint->IsLineCorner() )
|
||||
return;
|
||||
|
@ -1792,7 +1792,7 @@ void LINE_PLACER::simplifyNewLine( NODE* aNode, LINKED_ITEM* aLatest )
|
|||
|
||||
NODE::ITEM_VECTOR toRemove;
|
||||
|
||||
for( ITEM* neighbor : aJoint->Links() )
|
||||
for( ITEM* neighbor : aJoint->CLinks().CItems() )
|
||||
{
|
||||
if( neighbor == aItem
|
||||
|| !neighbor->OfKind( ITEM::SEGMENT_T | ITEM::ARC_T )
|
||||
|
@ -1801,18 +1801,18 @@ void LINE_PLACER::simplifyNewLine( NODE* aNode, LINKED_ITEM* aLatest )
|
|||
continue;
|
||||
}
|
||||
|
||||
if( static_cast<SEGMENT*>( neighbor )->Width()
|
||||
!= static_cast<SEGMENT*>( aItem )->Width() )
|
||||
if( static_cast<const SEGMENT*>( neighbor )->Width()
|
||||
!= static_cast<const SEGMENT*>( aItem )->Width() )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const SEG& testSeg = static_cast<SEGMENT*>( neighbor )->Seg();
|
||||
const SEG& testSeg = static_cast<const SEGMENT*>( neighbor )->Seg();
|
||||
|
||||
if( refSeg.Contains( testSeg ) )
|
||||
{
|
||||
JOINT* nA = aNode->FindJoint( neighbor->Anchor( 0 ), neighbor );
|
||||
JOINT* nB = aNode->FindJoint( neighbor->Anchor( 1 ), neighbor );
|
||||
const JOINT* nA = aNode->FindJoint( neighbor->Anchor( 0 ), neighbor );
|
||||
const JOINT* nB = aNode->FindJoint( neighbor->Anchor( 1 ), neighbor );
|
||||
|
||||
if( ( nA == aJoint && nB->LinkCount() == 1 ) ||
|
||||
( nB == aJoint && nA->LinkCount() == 1 ) )
|
||||
|
@ -1828,8 +1828,8 @@ void LINE_PLACER::simplifyNewLine( NODE* aNode, LINKED_ITEM* aLatest )
|
|||
if( !item->OfKind( ITEM::SEGMENT_T ) || cleanup.count( item ) )
|
||||
continue;
|
||||
|
||||
JOINT* jA = aNode->FindJoint( item->Anchor( 0 ), item );
|
||||
JOINT* jB = aNode->FindJoint( item->Anchor( 1 ), item );
|
||||
const JOINT* jA = aNode->FindJoint( item->Anchor( 0 ), item );
|
||||
const JOINT* jB = aNode->FindJoint( item->Anchor( 1 ), item );
|
||||
|
||||
processJoint( jA, item );
|
||||
processJoint( jB, item );
|
||||
|
|
|
@ -69,7 +69,7 @@ int MEANDER_PLACER_BASE::Clearance()
|
|||
// Assumption: All tracks are part of the same net class.
|
||||
// It shouldn't matter which track we pick. They should all have the same clearance if
|
||||
// they are part of the same net class. Therefore, pick the first one on the list.
|
||||
ITEM* itemToCheck = Traces().CItems().front().item;
|
||||
ITEM* itemToCheck = Traces().CItems().front();
|
||||
PNS::CONSTRAINT constraint;
|
||||
|
||||
Router()->GetRuleResolver()->QueryConstraint( PNS::CONSTRAINT_TYPE::CT_CLEARANCE, itemToCheck,
|
||||
|
@ -308,7 +308,7 @@ int MEANDER_PLACER_BASE::GetTotalPadToDieLength( const LINE& aLine ) const
|
|||
// Extract the length of the pad to die for start and end pads
|
||||
for( auto& link : start.LinkList() )
|
||||
{
|
||||
if( const SOLID* solid = dynamic_cast<const SOLID*>( link.item ) )
|
||||
if( const SOLID* solid = dyn_cast<const SOLID*>( link ) )
|
||||
{
|
||||
// If there are overlapping pads, choose the first with a non-zero length
|
||||
if( solid->GetPadToDie() > 0 )
|
||||
|
@ -321,7 +321,7 @@ int MEANDER_PLACER_BASE::GetTotalPadToDieLength( const LINE& aLine ) const
|
|||
|
||||
for( auto& link : end.LinkList() )
|
||||
{
|
||||
if( const SOLID* solid = dynamic_cast<const SOLID*>( link.item ) )
|
||||
if( const SOLID* solid = dyn_cast<const SOLID*>( link ) )
|
||||
{
|
||||
if( solid->GetPadToDie() > 0 )
|
||||
{
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
namespace PNS {
|
||||
|
||||
#ifdef DEBUG
|
||||
static std::unordered_set<NODE*> allocNodes;
|
||||
static std::unordered_set<const NODE*> allocNodes;
|
||||
#endif
|
||||
|
||||
NODE::NODE()
|
||||
|
@ -784,13 +784,13 @@ void NODE::removeArcIndex( ARC* aArc )
|
|||
}
|
||||
|
||||
|
||||
void NODE::rebuildJoint( JOINT* aJoint, ITEM* aItem )
|
||||
void NODE::rebuildJoint( const JOINT* aJoint, const ITEM* aItem )
|
||||
{
|
||||
// We have to split a single joint (associated with a via or a pad, binding together multiple
|
||||
// layers) into multiple independent joints. As I'm a lazy bastard, I simply delete the
|
||||
// via/solid and all its links and re-insert them.
|
||||
|
||||
JOINT::LINKED_ITEMS links( aJoint->LinkList() );
|
||||
std::vector<ITEM*> links( aJoint->LinkList() );
|
||||
JOINT::HASH_TAG tag;
|
||||
int net = aItem->Net();
|
||||
|
||||
|
@ -831,7 +831,7 @@ void NODE::rebuildJoint( JOINT* aJoint, ITEM* aItem )
|
|||
|
||||
void NODE::removeViaIndex( VIA* aVia )
|
||||
{
|
||||
JOINT* jt = FindJoint( aVia->Pos(), aVia->Layers().Start(), aVia->Net() );
|
||||
const JOINT* jt = FindJoint( aVia->Pos(), aVia->Layers().Start(), aVia->Net() );
|
||||
assert( jt );
|
||||
rebuildJoint( jt, aVia );
|
||||
}
|
||||
|
@ -843,7 +843,7 @@ void NODE::removeSolidIndex( SOLID* aSolid )
|
|||
return;
|
||||
|
||||
// fixme: redundant code
|
||||
JOINT* jt = FindJoint( aSolid->Pos(), aSolid->Layers().Start(), aSolid->Net() );
|
||||
const JOINT* jt = FindJoint( aSolid->Pos(), aSolid->Layers().Start(), aSolid->Net() );
|
||||
assert( jt );
|
||||
rebuildJoint( jt, aSolid );
|
||||
}
|
||||
|
@ -1123,7 +1123,7 @@ int NODE::FindLinesBetweenJoints( const JOINT& aA, const JOINT& aB, std::vector<
|
|||
|
||||
void NODE::FixupVirtualVias()
|
||||
{
|
||||
SEGMENT* locked_seg = nullptr;
|
||||
const SEGMENT* locked_seg = nullptr;
|
||||
std::vector<VVIA*> vvias;
|
||||
|
||||
for( auto& jointPair : m_joints )
|
||||
|
@ -1139,17 +1139,17 @@ void NODE::FixupVirtualVias()
|
|||
bool is_width_change = false;
|
||||
bool is_locked = false;
|
||||
|
||||
for( const auto& lnk : joint.LinkList() )
|
||||
for( const ITEM* item : joint.LinkList() )
|
||||
{
|
||||
if( lnk.item->OfKind( ITEM::VIA_T ) )
|
||||
if( item->OfKind( ITEM::VIA_T ) )
|
||||
{
|
||||
n_vias++;
|
||||
}
|
||||
else if( lnk.item->OfKind( ITEM::SOLID_T ) )
|
||||
else if( item->OfKind( ITEM::SOLID_T ) )
|
||||
{
|
||||
n_solid++;
|
||||
}
|
||||
else if( const auto t = dyn_cast<PNS::SEGMENT*>( lnk.item ) )
|
||||
else if( const auto t = dyn_cast<const PNS::SEGMENT*>( item ) )
|
||||
{
|
||||
int w = t->Width();
|
||||
|
||||
|
@ -1192,14 +1192,14 @@ void NODE::FixupVirtualVias()
|
|||
}
|
||||
|
||||
|
||||
JOINT* NODE::FindJoint( const VECTOR2I& aPos, int aLayer, int aNet )
|
||||
const JOINT* NODE::FindJoint( const VECTOR2I& aPos, int aLayer, int aNet ) const
|
||||
{
|
||||
JOINT::HASH_TAG tag;
|
||||
|
||||
tag.net = aNet;
|
||||
tag.pos = aPos;
|
||||
|
||||
JOINT_MAP::iterator f = m_joints.find( tag ), end = m_joints.end();
|
||||
JOINT_MAP::const_iterator f = m_joints.find( tag ), end = m_joints.end();
|
||||
|
||||
if( f == end && !isRoot() )
|
||||
{
|
||||
|
@ -1524,7 +1524,7 @@ void NODE::RemoveByMarker( int aMarker )
|
|||
SEGMENT* NODE::findRedundantSegment( const VECTOR2I& A, const VECTOR2I& B, const LAYER_RANGE& lr,
|
||||
int aNet )
|
||||
{
|
||||
JOINT* jtStart = FindJoint( A, lr.Start(), aNet );
|
||||
const JOINT* jtStart = FindJoint( A, lr.Start(), aNet );
|
||||
|
||||
if( !jtStart )
|
||||
return nullptr;
|
||||
|
@ -1559,7 +1559,7 @@ SEGMENT* NODE::findRedundantSegment( SEGMENT* aSeg )
|
|||
ARC* NODE::findRedundantArc( const VECTOR2I& A, const VECTOR2I& B, const LAYER_RANGE& lr,
|
||||
int aNet )
|
||||
{
|
||||
JOINT* jtStart = FindJoint( A, lr.Start(), aNet );
|
||||
const JOINT* jtStart = FindJoint( A, lr.Start(), aNet );
|
||||
|
||||
if( !jtStart )
|
||||
return nullptr;
|
||||
|
|
|
@ -105,10 +105,7 @@ public:
|
|||
virtual void ClearCacheForItem( const ITEM* aItem ) {}
|
||||
virtual void ClearCaches() {}
|
||||
|
||||
virtual int ClearanceEpsilon() const { return m_clearanceEpsilon; }
|
||||
|
||||
protected:
|
||||
int m_clearanceEpsilon = 0;
|
||||
virtual int ClearanceEpsilon() const { return 0; }
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -161,7 +158,7 @@ protected:
|
|||
* - assembly of lines connecting joints, finding loops and unique paths.
|
||||
* - lightweight cloning/branching (for recursive optimization and shove springback).
|
||||
**/
|
||||
class NODE
|
||||
class NODE : public ITEM_OWNER
|
||||
{
|
||||
public:
|
||||
|
||||
|
@ -372,7 +369,7 @@ public:
|
|||
*
|
||||
* @return the joint, if found, otherwise empty.
|
||||
*/
|
||||
JOINT* FindJoint( const VECTOR2I& aPos, int aLayer, int aNet );
|
||||
const JOINT* FindJoint( const VECTOR2I& aPos, int aLayer, int aNet ) const;
|
||||
|
||||
void LockJoint( const VECTOR2I& aPos, const ITEM* aItem, bool aLock );
|
||||
|
||||
|
@ -381,7 +378,7 @@ public:
|
|||
*
|
||||
* @return the joint, if found, otherwise empty.
|
||||
*/
|
||||
JOINT* FindJoint( const VECTOR2I& aPos, const ITEM* aItem )
|
||||
const JOINT* FindJoint( const VECTOR2I& aPos, const ITEM* aItem ) const
|
||||
{
|
||||
return FindJoint( aPos, aItem->Layers().Start(), aItem->Net() );
|
||||
}
|
||||
|
@ -463,7 +460,7 @@ private:
|
|||
void unlinkParent();
|
||||
void releaseChildren();
|
||||
void releaseGarbage();
|
||||
void rebuildJoint( JOINT* aJoint, ITEM* aItem );
|
||||
void rebuildJoint( const JOINT* aJoint, const ITEM* aItem );
|
||||
|
||||
bool isRoot() const
|
||||
{
|
||||
|
|
|
@ -930,7 +930,7 @@ OPTIMIZER::BREAKOUT_LIST OPTIMIZER::computeBreakouts( int aWidth, const ITEM* aI
|
|||
|
||||
ITEM* OPTIMIZER::findPadOrVia( int aLayer, int aNet, const VECTOR2I& aP ) const
|
||||
{
|
||||
JOINT* jt = m_world->FindJoint( aP, aLayer, aNet );
|
||||
const JOINT* jt = m_world->FindJoint( aP, aLayer, aNet );
|
||||
|
||||
if( !jt )
|
||||
return nullptr;
|
||||
|
|
|
@ -508,7 +508,7 @@ bool ROUTER::getNearestRatnestAnchor( VECTOR2I& aOtherEnd, LAYER_RANGE& aOtherEn
|
|||
// Otherwise, find the closest anchor to our start point
|
||||
|
||||
// Get joint from placer start item
|
||||
JOINT* jt = lastNode->FindJoint( placer->CurrentStart(), placer->CurrentLayer(),
|
||||
const JOINT* jt = lastNode->FindJoint( placer->CurrentStart(), placer->CurrentLayer(),
|
||||
placer->CurrentNets()[0] );
|
||||
|
||||
if( !jt )
|
||||
|
@ -816,10 +816,8 @@ void ROUTER::GetUpdatedItems( std::vector<PNS::ITEM*>& aRemoved, std::vector<PNS
|
|||
|
||||
node->GetUpdatedItems( aRemoved, aAdded );
|
||||
|
||||
for( auto& item : current.CItems() )
|
||||
{
|
||||
aHeads.push_back( item.item->Clone() );
|
||||
}
|
||||
for( const ITEM* item : current.CItems() )
|
||||
aHeads.push_back( item->Clone() );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -369,7 +369,7 @@ SHOVE::SHOVE_STATUS SHOVE::shoveLineToHullSet( const LINE& aCurLine, const LINE&
|
|||
|
||||
if(( aCurLine.Marker() & MK_HEAD ) && !colliding )
|
||||
{
|
||||
JOINT* jtStart = m_currentNode->FindJoint( aCurLine.CPoint( 0 ), &aCurLine );
|
||||
const JOINT* jtStart = m_currentNode->FindJoint( aCurLine.CPoint( 0 ), &aCurLine );
|
||||
|
||||
for( ITEM* item : jtStart->LinkList() )
|
||||
{
|
||||
|
@ -664,7 +664,7 @@ SHOVE::SHOVE_STATUS SHOVE::onCollidingSolid( LINE& aCurrent, ITEM* aObstacle, OB
|
|||
{
|
||||
VIA vh = aCurrent.Via();
|
||||
VIA* via = nullptr;
|
||||
JOINT* jtStart = m_currentNode->FindJoint( vh.Pos(), &aCurrent );
|
||||
const JOINT* jtStart = m_currentNode->FindJoint( vh.Pos(), &aCurrent );
|
||||
|
||||
if( !jtStart )
|
||||
return SH_INCOMPLETE;
|
||||
|
@ -868,7 +868,7 @@ SHOVE::SHOVE_STATUS SHOVE::pushOrShoveVia( VIA* aVia, const VECTOR2I& aForce, in
|
|||
{
|
||||
LINE_PAIR_VEC draggedLines;
|
||||
VECTOR2I p0( aVia->Pos() );
|
||||
JOINT* jt = m_currentNode->FindJoint( p0, aVia );
|
||||
const JOINT* jt = m_currentNode->FindJoint( p0, aVia );
|
||||
VECTOR2I p0_pushed( p0 + aForce );
|
||||
|
||||
PNS_DBG( Dbg(), Message, wxString::Format( wxT( "via force [%d %d]\n" ), aForce.x, aForce.y ) );
|
||||
|
@ -893,7 +893,7 @@ SHOVE::SHOVE_STATUS SHOVE::pushOrShoveVia( VIA* aVia, const VECTOR2I& aForce, in
|
|||
// make sure pushed via does not overlap with any existing joint
|
||||
while( true )
|
||||
{
|
||||
JOINT* jt_next = m_currentNode->FindJoint( p0_pushed, aVia );
|
||||
const JOINT* jt_next = m_currentNode->FindJoint( p0_pushed, aVia );
|
||||
|
||||
if( !jt_next )
|
||||
break;
|
||||
|
@ -1070,7 +1070,7 @@ SHOVE::SHOVE_STATUS SHOVE::onReverseCollidingVia( LINE& aCurrent, VIA* aObstacle
|
|||
LINE cur( aCurrent );
|
||||
cur.ClearLinks();
|
||||
|
||||
JOINT* jt = m_currentNode->FindJoint( aObstacleVia->Pos(), aObstacleVia );
|
||||
const JOINT* jt = m_currentNode->FindJoint( aObstacleVia->Pos(), aObstacleVia );
|
||||
LINE shoved( aCurrent );
|
||||
shoved.ClearLinks();
|
||||
|
||||
|
@ -1152,7 +1152,7 @@ SHOVE::SHOVE_STATUS SHOVE::onReverseCollidingVia( LINE& aCurrent, VIA* aObstacle
|
|||
}
|
||||
|
||||
|
||||
void SHOVE::unwindLineStack( LINKED_ITEM* aSeg )
|
||||
void SHOVE::unwindLineStack( const LINKED_ITEM* aSeg )
|
||||
{
|
||||
int d = 0;
|
||||
|
||||
|
@ -1179,15 +1179,17 @@ void SHOVE::unwindLineStack( LINKED_ITEM* aSeg )
|
|||
}
|
||||
|
||||
|
||||
void SHOVE::unwindLineStack( ITEM* aItem )
|
||||
void SHOVE::unwindLineStack( const ITEM* aItem )
|
||||
{
|
||||
if( aItem->OfKind( ITEM::SEGMENT_T | ITEM::ARC_T ) )
|
||||
unwindLineStack( static_cast<LINKED_ITEM*>( aItem ) );
|
||||
{
|
||||
unwindLineStack( static_cast<const LINKED_ITEM*>( aItem ) );
|
||||
}
|
||||
else if( aItem->OfKind( ITEM::LINE_T ) )
|
||||
{
|
||||
LINE* l = static_cast<LINE*>( aItem );
|
||||
const LINE* l = static_cast<const LINE*>( aItem );
|
||||
|
||||
for( LINKED_ITEM* seg : l->Links() )
|
||||
for( const LINKED_ITEM* seg : l->Links() )
|
||||
unwindLineStack( seg );
|
||||
}
|
||||
}
|
||||
|
@ -1253,20 +1255,22 @@ bool SHOVE::fixupViaCollisions( const LINE* aCurrent, OBSTACLE& obs )
|
|||
// our colliding item is a via: just find the max width of the traces connected to it
|
||||
if( obs.m_item->OfKind( ITEM::VIA_T ) )
|
||||
{
|
||||
VIA* v = static_cast<VIA*>( obs.m_item );
|
||||
const VIA* v = static_cast<const VIA*>( obs.m_item );
|
||||
int maxw = 0;
|
||||
JOINT* jv = m_currentNode->FindJoint( v->Pos(), v );
|
||||
const JOINT* jv = m_currentNode->FindJoint( v->Pos(), v );
|
||||
|
||||
for( auto link : jv->Links() )
|
||||
ITEM_SET links( jv->CLinks() );
|
||||
|
||||
for( ITEM* link : links )
|
||||
{
|
||||
if( link.item->OfKind( ITEM::SEGMENT_T ) ) // consider segments ...
|
||||
if( link->OfKind( ITEM::SEGMENT_T ) ) // consider segments ...
|
||||
{
|
||||
auto seg = static_cast<SEGMENT*>( link.item );
|
||||
const SEGMENT* seg = static_cast<const SEGMENT*>( link );
|
||||
maxw = std::max( seg->Width(), maxw );
|
||||
}
|
||||
else if( link.item->OfKind( ITEM::ARC_T ) ) // ... or arcs
|
||||
else if( link->OfKind( ITEM::ARC_T ) ) // ... or arcs
|
||||
{
|
||||
auto arc = static_cast<ARC*>( link.item );
|
||||
const ARC* arc = static_cast<const ARC*>( link );
|
||||
maxw = std::max( arc->Width(), maxw );
|
||||
}
|
||||
}
|
||||
|
@ -1289,10 +1293,10 @@ bool SHOVE::fixupViaCollisions( const LINE* aCurrent, OBSTACLE& obs )
|
|||
if( !obs.m_item->OfKind( ITEM::SEGMENT_T ) )
|
||||
return false;
|
||||
|
||||
auto s = static_cast<SEGMENT*>( obs.m_item );
|
||||
const SEGMENT* s = static_cast<const SEGMENT*>( obs.m_item );
|
||||
|
||||
JOINT* ja = m_currentNode->FindJoint( s->Seg().A, s );
|
||||
JOINT* jb = m_currentNode->FindJoint( s->Seg().B, s );
|
||||
const JOINT* ja = m_currentNode->FindJoint( s->Seg().A, s );
|
||||
const JOINT* jb = m_currentNode->FindJoint( s->Seg().B, s );
|
||||
|
||||
VIA* vias[] = { ja->Via(), jb->Via() };
|
||||
|
||||
|
@ -1753,7 +1757,7 @@ SHOVE::SHOVE_STATUS SHOVE::ShoveMultiLines( const ITEM_SET& aHeadSet )
|
|||
|
||||
static VIA* findViaByHandle ( NODE *aNode, const VIA_HANDLE& handle )
|
||||
{
|
||||
JOINT* jt = aNode->FindJoint( handle.pos, handle.layers.Start(), handle.net );
|
||||
const JOINT* jt = aNode->FindJoint( handle.pos, handle.layers.Start(), handle.net );
|
||||
|
||||
if( !jt )
|
||||
return nullptr;
|
||||
|
@ -2045,7 +2049,7 @@ void SHOVE::DisablePostShoveOptimizations( int aMask )
|
|||
}
|
||||
|
||||
|
||||
void SHOVE::SetSpringbackDoNotTouchNode( NODE *aNode )
|
||||
void SHOVE::SetSpringbackDoNotTouchNode( const NODE *aNode )
|
||||
{
|
||||
m_springbackDoNotTouchNode = aNode;
|
||||
}
|
||||
|
|
|
@ -90,7 +90,7 @@ public:
|
|||
bool RewindSpringbackTo( NODE* aNode );
|
||||
bool RewindToLastLockedNode();
|
||||
void DisablePostShoveOptimizations( int aMask );
|
||||
void SetSpringbackDoNotTouchNode( NODE *aNode );
|
||||
void SetSpringbackDoNotTouchNode( const NODE *aNode );
|
||||
|
||||
private:
|
||||
typedef std::vector<SHAPE_LINE_CHAIN> HULL_SET;
|
||||
|
@ -139,8 +139,8 @@ private:
|
|||
|
||||
OPT_BOX2I totalAffectedArea() const;
|
||||
|
||||
void unwindLineStack( LINKED_ITEM* aSeg );
|
||||
void unwindLineStack( ITEM* aItem );
|
||||
void unwindLineStack( const LINKED_ITEM* aSeg );
|
||||
void unwindLineStack( const ITEM* aItem );
|
||||
|
||||
void runOptimizer( NODE* aNode );
|
||||
|
||||
|
@ -172,7 +172,7 @@ private:
|
|||
|
||||
NODE* m_root;
|
||||
NODE* m_currentNode;
|
||||
NODE* m_springbackDoNotTouchNode;
|
||||
const NODE* m_springbackDoNotTouchNode;
|
||||
int m_restrictSpringbackTagId;
|
||||
|
||||
OPT_LINE m_newHead;
|
||||
|
|
|
@ -59,9 +59,9 @@ bool TOPOLOGY::SimplifyLine( LINE* aLine )
|
|||
}
|
||||
|
||||
|
||||
const TOPOLOGY::JOINT_SET TOPOLOGY::ConnectedJoints( JOINT* aStart )
|
||||
const TOPOLOGY::JOINT_SET TOPOLOGY::ConnectedJoints( const JOINT* aStart )
|
||||
{
|
||||
std::deque<JOINT*> searchQueue;
|
||||
std::deque<const JOINT*> searchQueue;
|
||||
JOINT_SET processed;
|
||||
|
||||
searchQueue.push_back( aStart );
|
||||
|
@ -69,16 +69,16 @@ const TOPOLOGY::JOINT_SET TOPOLOGY::ConnectedJoints( JOINT* aStart )
|
|||
|
||||
while( !searchQueue.empty() )
|
||||
{
|
||||
JOINT* current = searchQueue.front();
|
||||
const JOINT* current = searchQueue.front();
|
||||
searchQueue.pop_front();
|
||||
|
||||
for( ITEM* item : current->LinkList() )
|
||||
{
|
||||
if( item->OfKind( ITEM::SEGMENT_T | ITEM::ARC_T ) )
|
||||
if( item->OfKind( ITEM::SEGMENT_T ) )
|
||||
{
|
||||
JOINT* a = m_world->FindJoint( item->Anchor( 0 ), item );;
|
||||
JOINT* b = m_world->FindJoint( item->Anchor( 1 ), item );;
|
||||
JOINT* next = ( *a == *current ) ? b : a;
|
||||
const JOINT* a = m_world->FindJoint( item->Anchor( 0 ), item );;
|
||||
const JOINT* b = m_world->FindJoint( item->Anchor( 1 ), item );;
|
||||
const JOINT* next = ( *a == *current ) ? b : a;
|
||||
|
||||
if( processed.find( next ) == processed.end() )
|
||||
{
|
||||
|
@ -105,7 +105,7 @@ bool TOPOLOGY::NearestUnconnectedAnchorPoint( const LINE* aTrack, VECTOR2I& aPoi
|
|||
std::unique_ptr<NODE> tmpNode( m_world->Branch() );
|
||||
tmpNode->Add( track );
|
||||
|
||||
JOINT* jt = tmpNode->FindJoint( track.CPoint( -1 ), &track );
|
||||
const JOINT* jt = tmpNode->FindJoint( track.CPoint( -1 ), &track );
|
||||
|
||||
if( !jt || jt->Net() <= 0 )
|
||||
return false;
|
||||
|
@ -154,7 +154,7 @@ bool TOPOLOGY::LeadingRatLine( const LINE* aTrack, SHAPE_LINE_CHAIN& aRatLine )
|
|||
}
|
||||
|
||||
|
||||
ITEM* TOPOLOGY::NearestUnconnectedItem( JOINT* aStart, int* aAnchor, int aKindMask )
|
||||
ITEM* TOPOLOGY::NearestUnconnectedItem( const JOINT* aStart, int* aAnchor, int aKindMask )
|
||||
{
|
||||
std::set<ITEM*> disconnected;
|
||||
|
||||
|
@ -198,13 +198,13 @@ ITEM* TOPOLOGY::NearestUnconnectedItem( JOINT* aStart, int* aAnchor, int aKindMa
|
|||
|
||||
|
||||
bool TOPOLOGY::followTrivialPath( LINE* aLine, bool aLeft, ITEM_SET& aSet,
|
||||
std::set<ITEM*>& aVisited, JOINT** aTerminalJoint )
|
||||
std::set<ITEM*>& aVisited, const JOINT** aTerminalJoint )
|
||||
{
|
||||
assert( aLine->IsLinked() );
|
||||
|
||||
VECTOR2I anchor = aLeft ? aLine->CPoint( 0 ) : aLine->CPoint( -1 );
|
||||
LINKED_ITEM* last = aLeft ? aLine->Links().front() : aLine->Links().back();
|
||||
JOINT* jt = m_world->FindJoint( anchor, aLine );
|
||||
const JOINT* jt = m_world->FindJoint( anchor, aLine );
|
||||
|
||||
assert( jt != nullptr );
|
||||
|
||||
|
@ -215,7 +215,9 @@ bool TOPOLOGY::followTrivialPath( LINE* aLine, bool aLeft, ITEM_SET& aSet,
|
|||
ITEM* via = nullptr;
|
||||
SEGMENT* next_seg = nullptr;
|
||||
|
||||
for( ITEM* link : jt->Links().Items() )
|
||||
ITEM_SET links( jt->CLinks() );
|
||||
|
||||
for( ITEM* link : links )
|
||||
{
|
||||
if( link->OfKind( ITEM::VIA_T ) )
|
||||
via = link;
|
||||
|
@ -266,7 +268,7 @@ bool TOPOLOGY::followTrivialPath( LINE* aLine, bool aLeft, ITEM_SET& aSet,
|
|||
|
||||
|
||||
const ITEM_SET TOPOLOGY::AssembleTrivialPath( ITEM* aStart,
|
||||
std::pair<JOINT*, JOINT*>* aTerminalJoints,
|
||||
std::pair<const JOINT*, const JOINT*>* aTerminalJoints,
|
||||
bool aFollowLockedSegments )
|
||||
{
|
||||
ITEM_SET path;
|
||||
|
@ -276,16 +278,18 @@ const ITEM_SET TOPOLOGY::AssembleTrivialPath( ITEM* aStart,
|
|||
if( aStart->Kind() == ITEM::VIA_T )
|
||||
{
|
||||
VIA* via = static_cast<VIA*>( aStart );
|
||||
JOINT* jt = m_world->FindJoint( via->Pos(), via );
|
||||
const JOINT* jt = m_world->FindJoint( via->Pos(), via );
|
||||
|
||||
if( !jt->IsNonFanoutVia() )
|
||||
return ITEM_SET();
|
||||
|
||||
for( const ITEM_SET::ENTRY& entry : jt->Links().Items() )
|
||||
ITEM_SET links( jt->CLinks() );
|
||||
|
||||
for( ITEM* item : links )
|
||||
{
|
||||
if( entry.item->OfKind( ITEM::SEGMENT_T | ITEM::ARC_T ) )
|
||||
if( item->OfKind( ITEM::SEGMENT_T | ITEM::ARC_T ) )
|
||||
{
|
||||
seg = static_cast<LINKED_ITEM*>( entry.item );
|
||||
seg = static_cast<LINKED_ITEM*>( item );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -304,8 +308,8 @@ const ITEM_SET TOPOLOGY::AssembleTrivialPath( ITEM* aStart,
|
|||
|
||||
path.Add( l );
|
||||
|
||||
JOINT* jointA = nullptr;
|
||||
JOINT* jointB = nullptr;
|
||||
const JOINT* jointA = nullptr;
|
||||
const JOINT* jointB = nullptr;
|
||||
|
||||
followTrivialPath( &l, false, path, visited, &jointB );
|
||||
followTrivialPath( &l, true, path, visited, &jointA );
|
||||
|
@ -322,14 +326,14 @@ const ITEM_SET TOPOLOGY::AssembleTrivialPath( ITEM* aStart,
|
|||
|
||||
const ITEM_SET TOPOLOGY::AssembleTuningPath( ITEM* aStart, SOLID** aStartPad, SOLID** aEndPad )
|
||||
{
|
||||
std::pair<JOINT*, JOINT*> joints;
|
||||
std::pair<const JOINT*, const JOINT*> joints;
|
||||
ITEM_SET initialPath = AssembleTrivialPath( aStart, &joints, true );
|
||||
|
||||
PAD* padA = nullptr;
|
||||
PAD* padB = nullptr;
|
||||
|
||||
auto getPadFromJoint =
|
||||
[]( JOINT* aJoint, PAD** aTargetPad, SOLID** aTargetSolid )
|
||||
[]( const JOINT* aJoint, PAD** aTargetPad, SOLID** aTargetSolid )
|
||||
{
|
||||
for( ITEM* item : aJoint->LinkList() )
|
||||
{
|
||||
|
@ -406,7 +410,7 @@ const ITEM_SET TOPOLOGY::AssembleTuningPath( ITEM* aStart, SOLID** aStartPad, SO
|
|||
};
|
||||
|
||||
auto processPad =
|
||||
[&]( JOINT* aJoint, PAD* aPad )
|
||||
[&]( const JOINT* aJoint, PAD* aPad )
|
||||
{
|
||||
const std::shared_ptr<SHAPE_POLY_SET>& shape = aPad->GetEffectivePolygon();
|
||||
|
||||
|
@ -444,7 +448,7 @@ const ITEM_SET TOPOLOGY::AssembleTuningPath( ITEM* aStart, SOLID** aStartPad, SO
|
|||
}
|
||||
|
||||
|
||||
const ITEM_SET TOPOLOGY::ConnectedItems( JOINT* aStart, int aKindMask )
|
||||
const ITEM_SET TOPOLOGY::ConnectedItems( const JOINT* aStart, int aKindMask )
|
||||
{
|
||||
return ITEM_SET();
|
||||
}
|
||||
|
@ -556,7 +560,7 @@ const std::set<ITEM*> TOPOLOGY::AssembleCluster( ITEM* aStart, int aLayer )
|
|||
|
||||
m_world->QueryColliding( top, obstacles, opts ); // only query touching objects
|
||||
|
||||
for( OBSTACLE& obs : obstacles )
|
||||
for( const OBSTACLE& obs : obstacles )
|
||||
{
|
||||
bool trackOnTrack = ( obs.m_item->Net() != top->Net() ) && obs.m_item->OfKind( ITEM::SEGMENT_T ) && top->OfKind( ITEM::SEGMENT_T );
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ class DIFF_PAIR;
|
|||
class TOPOLOGY
|
||||
{
|
||||
public:
|
||||
typedef std::set<JOINT*> JOINT_SET;
|
||||
typedef std::set<const JOINT*> JOINT_SET;
|
||||
|
||||
TOPOLOGY( NODE* aNode ):
|
||||
m_world( aNode ) {};
|
||||
|
@ -47,15 +47,15 @@ public:
|
|||
~TOPOLOGY() {};
|
||||
|
||||
bool SimplifyLine( LINE *aLine );
|
||||
ITEM* NearestUnconnectedItem( JOINT* aStart, int* aAnchor = nullptr,
|
||||
ITEM* NearestUnconnectedItem( const JOINT* aStart, int* aAnchor = nullptr,
|
||||
int aKindMask = ITEM::ANY_T );
|
||||
|
||||
bool NearestUnconnectedAnchorPoint( const LINE* aTrack, VECTOR2I& aPoint, LAYER_RANGE& aLayers,
|
||||
ITEM*& aItem );
|
||||
bool LeadingRatLine( const LINE* aTrack, SHAPE_LINE_CHAIN& aRatLine );
|
||||
|
||||
const JOINT_SET ConnectedJoints( JOINT* aStart );
|
||||
const ITEM_SET ConnectedItems( JOINT* aStart, int aKindMask = ITEM::ANY_T );
|
||||
const JOINT_SET ConnectedJoints( const JOINT* aStart );
|
||||
const ITEM_SET ConnectedItems( const JOINT* aStart, int aKindMask = ITEM::ANY_T );
|
||||
const ITEM_SET ConnectedItems( ITEM* aStart, int aKindMask = ITEM::ANY_T );
|
||||
int64_t ShortestConnectionLength( ITEM* aFrom, ITEM* aTo );
|
||||
|
||||
|
@ -68,7 +68,7 @@ public:
|
|||
* @return a set of items in the path.
|
||||
*/
|
||||
const ITEM_SET AssembleTrivialPath( ITEM* aStart,
|
||||
std::pair<JOINT*, JOINT*>* aTerminalJoints = nullptr,
|
||||
std::pair<const JOINT*, const JOINT*>* aTerminalJoints = nullptr,
|
||||
bool aFollowLockedSegments = false );
|
||||
|
||||
/**
|
||||
|
@ -96,7 +96,7 @@ private:
|
|||
const int DP_PARALLELITY_THRESHOLD = 5;
|
||||
|
||||
bool followTrivialPath( LINE* aLine, bool aLeft, ITEM_SET& aSet, std::set<ITEM*>& aVisited,
|
||||
JOINT** aTerminalJoint = nullptr );
|
||||
const JOINT** aTerminalJoint = nullptr );
|
||||
|
||||
NODE *m_world;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue