router: add VIA_HANDLE to refer to VIAs going in/out the SHOVE algorithm without raw pointers

This commit is contained in:
Tomasz Włostowski 2019-08-07 23:48:09 +02:00
parent 45e4387ed1
commit 88f2318c9c
4 changed files with 97 additions and 26 deletions

View File

@ -24,6 +24,7 @@
#include "pns_line.h" #include "pns_line.h"
#include "pns_node.h" #include "pns_node.h"
#include "pns_debug_decorator.h"
#include "pns_walkaround.h" #include "pns_walkaround.h"
#include "pns_shove.h" #include "pns_shove.h"
#include "pns_solid.h" #include "pns_solid.h"
@ -82,6 +83,7 @@ SHOVE::SHOVE( NODE* aWorld, ROUTER* aRouter ) :
m_forceClearance = -1; m_forceClearance = -1;
m_root = aWorld; m_root = aWorld;
m_currentNode = aWorld; m_currentNode = aWorld;
SetDebugDecorator( aRouter->GetInterface()->GetDebugDecorator() );
// Initialize other temporary variables: // Initialize other temporary variables:
m_draggedVia = NULL; m_draggedVia = NULL;
@ -553,16 +555,18 @@ SHOVE::SHOVE_STATUS SHOVE::onCollidingSolid( LINE& aCurrent, ITEM* aObstacle )
* Pops NODE stackframes which no longer collide with aHeadSet. Optionally sets aDraggedVia * Pops NODE stackframes which no longer collide with aHeadSet. Optionally sets aDraggedVia
* to the dragged via of the last unpopped state. * to the dragged via of the last unpopped state.
*/ */
NODE* SHOVE::reduceSpringback( const ITEM_SET& aHeadSet, VIA** aDraggedVia ) NODE* SHOVE::reduceSpringback( const ITEM_SET& aHeadSet, VIA_HANDLE& aDraggedVia )
{ {
while( !m_nodeStack.empty() ) while( !m_nodeStack.empty() )
{ {
SPRINGBACK_TAG spTag = m_nodeStack.back(); SPRINGBACK_TAG& spTag = m_nodeStack.back();
if( !spTag.m_node->CheckColliding( aHeadSet ) ) auto obs = spTag.m_node->CheckColliding( aHeadSet );
if( !obs )
{ {
if( aDraggedVia ) aDraggedVia = spTag.m_draggedVia;
*aDraggedVia = spTag.m_draggedVia; aDraggedVia.valid = true;
delete spTag.m_node; delete spTag.m_node;
m_nodeStack.pop_back(); m_nodeStack.pop_back();
@ -587,7 +591,11 @@ bool SHOVE::pushSpringback( NODE* aNode, const OPT_BOX2I& aAffectedArea, VIA* aD
if( !m_nodeStack.empty() ) if( !m_nodeStack.empty() )
prev_area = m_nodeStack.back().m_affectedArea; prev_area = m_nodeStack.back().m_affectedArea;
st.m_draggedVia = aDraggedVia; if( aDraggedVia )
{
st.m_draggedVia = aDraggedVia->MakeHandle();
}
st.m_node = aNode; st.m_node = aNode;
if( aAffectedArea ) if( aAffectedArea )
@ -1166,7 +1174,9 @@ SHOVE::SHOVE_STATUS SHOVE::ShoveLines( const LINE& aCurrentHead )
ITEM_SET headSet; ITEM_SET headSet;
headSet.Add( aCurrentHead ); headSet.Add( aCurrentHead );
NODE* parent = reduceSpringback( headSet, nullptr ); VIA_HANDLE dummyVia;
NODE* parent = reduceSpringback( headSet, dummyVia );
// Create a new NODE to store this version of the world // Create a new NODE to store this version of the world
// //
@ -1268,7 +1278,9 @@ SHOVE::SHOVE_STATUS SHOVE::ShoveMultiLines( const ITEM_SET& aHeadSet )
m_optimizerQueue.clear(); m_optimizerQueue.clear();
m_logger.Clear(); m_logger.Clear();
NODE* parent = reduceSpringback( headSet, nullptr ); VIA_HANDLE dummyVia;
NODE* parent = reduceSpringback( headSet, dummyVia );
m_currentNode = parent->Branch(); m_currentNode = parent->Branch();
m_currentNode->ClearRanks(); m_currentNode->ClearRanks();
@ -1325,8 +1337,26 @@ SHOVE::SHOVE_STATUS SHOVE::ShoveMultiLines( const ITEM_SET& aHeadSet )
return st; return st;
} }
static VIA* findViaByHandle ( NODE *aNode, const VIA_HANDLE& handle )
{
JOINT* jt = aNode->FindJoint( handle.pos, handle.layers.Start(), handle.net );
SHOVE::SHOVE_STATUS SHOVE::ShoveDraggingVia( VIA* aVia, const VECTOR2I& aWhere, VIA** aNewVia ) if( !jt )
return nullptr;
for( ITEM* item : jt->LinkList() )
{
if ( item->OfKind( ITEM::VIA_T ))
{
if( item->Net() == handle.net && item->Layers().Overlaps(handle.layers) )
return static_cast<VIA*>( item );
}
}
return nullptr;
}
SHOVE::SHOVE_STATUS SHOVE::ShoveDraggingVia( const VIA_HANDLE aOldVia, const VECTOR2I& aWhere, VIA_HANDLE& aNewVia )
{ {
SHOVE_STATUS st = SH_OK; SHOVE_STATUS st = SH_OK;
@ -1335,24 +1365,39 @@ SHOVE::SHOVE_STATUS SHOVE::ShoveDraggingVia( VIA* aVia, const VECTOR2I& aWhere,
m_newHead = OPT_LINE(); m_newHead = OPT_LINE();
m_draggedVia = NULL; m_draggedVia = NULL;
// Pop NODEs containing previous shoves which are no longer necessary auto viaToDrag = findViaByHandle( m_currentNode, aOldVia );
//
ITEM_SET headSet;
headSet.Add( *aVia );
NODE* parent = reduceSpringback( headSet, &aVia ); if( !viaToDrag )
{
return SH_INCOMPLETE;
}
// Pop NODEs containing previous shoves which are no longer necessary
ITEM_SET headSet;
VIA headVia ( *viaToDrag );
headVia.SetPos( aWhere );
headSet.Add( headVia );
VIA_HANDLE prevViaHandle;
NODE* parent = reduceSpringback( headSet, prevViaHandle );
if( prevViaHandle.valid )
{
aNewVia = prevViaHandle;
viaToDrag = findViaByHandle( parent, prevViaHandle );
}
// Create a new NODE to store this version of the world // Create a new NODE to store this version of the world
// //
m_currentNode = parent->Branch(); m_currentNode = parent->Branch();
m_currentNode->ClearRanks(); m_currentNode->ClearRanks();
aVia->Mark( MK_HEAD ); viaToDrag->Mark( MK_HEAD );
aVia->SetRank( 100000 ); viaToDrag->SetRank( 100000 );
// Push the via to its new location // Push the via to its new location
// //
st = pushOrShoveVia( aVia, ( aWhere - aVia->Pos()), 0 ); st = pushOrShoveVia( viaToDrag, ( aWhere - viaToDrag->Pos()), 0 );
// Shove any colliding objects out of the way // Shove any colliding objects out of the way
// //
@ -1365,14 +1410,16 @@ SHOVE::SHOVE_STATUS SHOVE::ShoveDraggingVia( VIA* aVia, const VECTOR2I& aWhere,
if( st == SH_OK || st == SH_HEAD_MODIFIED ) if( st == SH_OK || st == SH_HEAD_MODIFIED )
{ {
wxLogTrace( "PNS","setNewV %p", m_draggedVia ); wxLogTrace( "PNS","setNewV %p", m_draggedVia );
*aNewVia = m_draggedVia;
pushSpringback( m_currentNode, m_affectedArea, aVia ); if (!m_draggedVia)
m_draggedVia = viaToDrag;
aNewVia = m_draggedVia->MakeHandle();
pushSpringback( m_currentNode, m_affectedArea, viaToDrag );
} }
else else
{ {
*aNewVia = nullptr;
delete m_currentNode; delete m_currentNode;
m_currentNode = parent; m_currentNode = parent;
} }

View File

@ -67,7 +67,7 @@ public:
SHOVE_STATUS ShoveLines( const LINE& aCurrentHead ); SHOVE_STATUS ShoveLines( const LINE& aCurrentHead );
SHOVE_STATUS ShoveMultiLines( const ITEM_SET& aHeadSet ); SHOVE_STATUS ShoveMultiLines( const ITEM_SET& aHeadSet );
SHOVE_STATUS ShoveDraggingVia( VIA* aVia, const VECTOR2I& aWhere, VIA** aNewVia ); SHOVE_STATUS ShoveDraggingVia( const VIA_HANDLE aOldVia, const VECTOR2I& aWhere, VIA_HANDLE& aNewVia );
SHOVE_STATUS ProcessSingleLine( LINE& aCurrent, LINE& aObstacle, LINE& aShoved ); SHOVE_STATUS ProcessSingleLine( LINE& aCurrent, LINE& aObstacle, LINE& aShoved );
void ForceClearance ( bool aEnabled, int aClearance ) void ForceClearance ( bool aEnabled, int aClearance )
@ -93,7 +93,7 @@ private:
struct SPRINGBACK_TAG struct SPRINGBACK_TAG
{ {
int64_t m_length; int64_t m_length;
VIA* m_draggedVia; VIA_HANDLE m_draggedVia;
VECTOR2I m_p; VECTOR2I m_p;
NODE* m_node; NODE* m_node;
OPT_BOX2I m_affectedArea; OPT_BOX2I m_affectedArea;
@ -102,7 +102,8 @@ private:
SHOVE_STATUS processHullSet( LINE& aCurrent, LINE& aObstacle, SHOVE_STATUS processHullSet( LINE& aCurrent, LINE& aObstacle,
LINE& aShoved, const HULL_SET& hulls ); LINE& aShoved, const HULL_SET& hulls );
NODE* reduceSpringback( const ITEM_SET& aHeadItems, VIA** aDraggedVia ); NODE* reduceSpringback( const ITEM_SET& aHeadSet, VIA_HANDLE& aDraggedVia );
bool pushSpringback( NODE* aNode, const OPT_BOX2I& aAffectedArea, VIA* aDraggedVia ); bool pushSpringback( NODE* aNode, const OPT_BOX2I& aAffectedArea, VIA* aDraggedVia );
SHOVE_STATUS walkaroundLoneVia( LINE& aCurrent, LINE& aObstacle, LINE& aShoved ); SHOVE_STATUS walkaroundLoneVia( LINE& aCurrent, LINE& aObstacle, LINE& aShoved );

View File

@ -112,4 +112,14 @@ OPT_BOX2I VIA::ChangedArea( const VIA* aOther ) const
return OPT_BOX2I(); return OPT_BOX2I();
} }
const VIA_HANDLE VIA::MakeHandle() const
{
VIA_HANDLE h;
h.pos = Pos();
h.layers = Layers();
h.net = Net();
h.valid = true;
return h;
}
} }

View File

@ -33,6 +33,17 @@ namespace PNS {
class NODE; class NODE;
// uniquely identifies a VIA within a NODE without using pointers. Used to
// simplify (or complexifiy, depending on the point of view) the pointer management
// in PNS::NODE. Sooner or later I'll have to fix it for good using smart pointers - twl
struct VIA_HANDLE
{
bool valid = false;
VECTOR2I pos;
LAYER_RANGE layers;
int net;
};
class VIA : public ITEM class VIA : public ITEM
{ {
public: public:
@ -154,6 +165,8 @@ public:
OPT_BOX2I ChangedArea( const VIA* aOther ) const; OPT_BOX2I ChangedArea( const VIA* aOther ) const;
const VIA_HANDLE MakeHandle() const;
private: private:
int m_diameter; int m_diameter;
int m_drill; int m_drill;