Allow shoving and springback when dragging vias (either connected or free).
Fixes: lp:1833216 * https://bugs.launchpad.net/kicad/+bug/1833216
This commit is contained in:
parent
8c77d31d4d
commit
c1fcb1d895
|
@ -89,6 +89,22 @@ public:
|
||||||
m_hasVia = false;
|
m_hasVia = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* Constructs a LINE for a lone VIA (ie a stitching via).
|
||||||
|
* @param aVia
|
||||||
|
*/
|
||||||
|
LINE( const VIA& aVia ) :
|
||||||
|
ITEM( LINE_T )
|
||||||
|
{
|
||||||
|
m_hasVia = true;
|
||||||
|
m_via = aVia;
|
||||||
|
m_width = aVia.Diameter();
|
||||||
|
m_net = aVia.Net();
|
||||||
|
m_layers = aVia.Layers();
|
||||||
|
m_rank = aVia.Rank();
|
||||||
|
}
|
||||||
|
|
||||||
~LINE();
|
~LINE();
|
||||||
|
|
||||||
static inline bool ClassOf( const ITEM* aItem )
|
static inline bool ClassOf( const ITEM* aItem )
|
||||||
|
|
|
@ -530,17 +530,20 @@ SHOVE::SHOVE_STATUS SHOVE::onCollidingSolid( LINE& aCurrent, ITEM* aObstacle )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool SHOVE::reduceSpringback( const ITEM_SET& aHeadSet )
|
/*
|
||||||
|
* Pops NODE stackframes which no longer collide with aHeadSet. Optionally sets aDraggedVia
|
||||||
|
* to the dragged via of the last unpopped state.
|
||||||
|
*/
|
||||||
|
NODE* SHOVE::reduceSpringback( const ITEM_SET& aHeadSet, VIA** aDraggedVia )
|
||||||
{
|
{
|
||||||
bool rv = false;
|
|
||||||
|
|
||||||
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 ) )
|
if( !spTag.m_node->CheckColliding( aHeadSet ) )
|
||||||
{
|
{
|
||||||
rv = true;
|
if( aDraggedVia )
|
||||||
|
*aDraggedVia = spTag.m_draggedVia;
|
||||||
|
|
||||||
delete spTag.m_node;
|
delete spTag.m_node;
|
||||||
m_nodeStack.pop_back();
|
m_nodeStack.pop_back();
|
||||||
|
@ -549,11 +552,15 @@ bool SHOVE::reduceSpringback( const ITEM_SET& aHeadSet )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return rv;
|
return m_nodeStack.empty() ? m_root : m_nodeStack.back().m_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool SHOVE::pushSpringback( NODE* aNode, const OPT_BOX2I& aAffectedArea )
|
/*
|
||||||
|
* Push the current NODE on to the stack. aDraggedVia is the dragged via *before* the push
|
||||||
|
* (which will be restored in the event the stackframe is popped).
|
||||||
|
*/
|
||||||
|
bool SHOVE::pushSpringback( NODE* aNode, const OPT_BOX2I& aAffectedArea, VIA* aDraggedVia )
|
||||||
{
|
{
|
||||||
SPRINGBACK_TAG st;
|
SPRINGBACK_TAG st;
|
||||||
OPT_BOX2I prev_area;
|
OPT_BOX2I prev_area;
|
||||||
|
@ -561,6 +568,7 @@ bool SHOVE::pushSpringback( NODE* aNode, const OPT_BOX2I& aAffectedArea )
|
||||||
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;
|
||||||
st.m_node = aNode;
|
st.m_node = aNode;
|
||||||
|
|
||||||
if( aAffectedArea )
|
if( aAffectedArea )
|
||||||
|
@ -1026,6 +1034,13 @@ SHOVE::SHOVE_STATUS SHOVE::shoveMainLoop()
|
||||||
|
|
||||||
timeLimit.Restart();
|
timeLimit.Restart();
|
||||||
|
|
||||||
|
if( m_lineStack.empty() && m_draggedVia )
|
||||||
|
{
|
||||||
|
// If we're shoving a free via then push a proxy LINE (with the via on the end) onto
|
||||||
|
// the stack.
|
||||||
|
pushLine( LINE( *m_draggedVia ) );
|
||||||
|
}
|
||||||
|
|
||||||
while( !m_lineStack.empty() )
|
while( !m_lineStack.empty() )
|
||||||
{
|
{
|
||||||
st = shoveIteration( m_iter );
|
st = shoveIteration( m_iter );
|
||||||
|
@ -1081,9 +1096,7 @@ SHOVE::SHOVE_STATUS SHOVE::ShoveLines( const LINE& aCurrentHead )
|
||||||
ITEM_SET headSet;
|
ITEM_SET headSet;
|
||||||
headSet.Add( aCurrentHead );
|
headSet.Add( aCurrentHead );
|
||||||
|
|
||||||
reduceSpringback( headSet );
|
NODE* parent = reduceSpringback( headSet, nullptr );
|
||||||
|
|
||||||
NODE* parent = m_nodeStack.empty() ? m_root : m_nodeStack.back().m_node;
|
|
||||||
|
|
||||||
m_currentNode = parent->Branch();
|
m_currentNode = parent->Branch();
|
||||||
m_currentNode->ClearRanks();
|
m_currentNode->ClearRanks();
|
||||||
|
@ -1136,7 +1149,7 @@ SHOVE::SHOVE_STATUS SHOVE::ShoveLines( const LINE& aCurrentHead )
|
||||||
|
|
||||||
if( st == SH_OK || st == SH_HEAD_MODIFIED )
|
if( st == SH_OK || st == SH_HEAD_MODIFIED )
|
||||||
{
|
{
|
||||||
pushSpringback( m_currentNode, m_affectedArea );
|
pushSpringback( m_currentNode, m_affectedArea, nullptr );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1183,9 +1196,7 @@ SHOVE::SHOVE_STATUS SHOVE::ShoveMultiLines( const ITEM_SET& aHeadSet )
|
||||||
m_optimizerQueue.clear();
|
m_optimizerQueue.clear();
|
||||||
m_logger.Clear();
|
m_logger.Clear();
|
||||||
|
|
||||||
reduceSpringback( headSet );
|
NODE* parent = reduceSpringback( headSet, nullptr );
|
||||||
|
|
||||||
NODE* parent = m_nodeStack.empty() ? m_root : m_nodeStack.back().m_node;
|
|
||||||
|
|
||||||
m_currentNode = parent->Branch();
|
m_currentNode = parent->Branch();
|
||||||
m_currentNode->ClearRanks();
|
m_currentNode->ClearRanks();
|
||||||
|
@ -1231,7 +1242,7 @@ SHOVE::SHOVE_STATUS SHOVE::ShoveMultiLines( const ITEM_SET& aHeadSet )
|
||||||
|
|
||||||
if( st == SH_OK )
|
if( st == SH_OK )
|
||||||
{
|
{
|
||||||
pushSpringback( m_currentNode, m_affectedArea );
|
pushSpringback( m_currentNode, m_affectedArea, nullptr );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1252,15 +1263,29 @@ SHOVE::SHOVE_STATUS SHOVE::ShoveDraggingVia( VIA* aVia, const VECTOR2I& aWhere,
|
||||||
m_newHead = OPT_LINE();
|
m_newHead = OPT_LINE();
|
||||||
m_draggedVia = NULL;
|
m_draggedVia = NULL;
|
||||||
|
|
||||||
NODE* parent = m_nodeStack.empty() ? m_root : m_nodeStack.back().m_node;
|
ITEM_SET headSet;
|
||||||
|
headSet.Add( *aVia );
|
||||||
|
|
||||||
|
// Pop NODEs containing previous shoves which are no longer necessary
|
||||||
|
//
|
||||||
|
NODE* parent = reduceSpringback( headSet, &aVia );
|
||||||
|
|
||||||
|
// Create a new NODE
|
||||||
|
//
|
||||||
m_currentNode = parent->Branch();
|
m_currentNode = parent->Branch();
|
||||||
m_currentNode->ClearRanks();
|
m_currentNode->ClearRanks();
|
||||||
|
|
||||||
aVia->Mark( MK_HEAD );
|
aVia->Mark( MK_HEAD );
|
||||||
|
aVia->SetRank( 100000 );
|
||||||
|
|
||||||
|
// Push the via to its new location
|
||||||
|
//
|
||||||
st = pushVia( aVia, ( aWhere - aVia->Pos() ), 0 );
|
st = pushVia( aVia, ( aWhere - aVia->Pos() ), 0 );
|
||||||
st = shoveMainLoop();
|
|
||||||
|
// Shove any colliding objects out of the way
|
||||||
|
//
|
||||||
|
if( st == SH_OK )
|
||||||
|
st = shoveMainLoop();
|
||||||
|
|
||||||
if( st == SH_OK )
|
if( st == SH_OK )
|
||||||
runOptimizer( m_currentNode );
|
runOptimizer( m_currentNode );
|
||||||
|
@ -1270,7 +1295,7 @@ SHOVE::SHOVE_STATUS SHOVE::ShoveDraggingVia( VIA* aVia, const VECTOR2I& aWhere,
|
||||||
wxLogTrace( "PNS","setNewV %p", m_draggedVia );
|
wxLogTrace( "PNS","setNewV %p", m_draggedVia );
|
||||||
*aNewVia = m_draggedVia;
|
*aNewVia = m_draggedVia;
|
||||||
|
|
||||||
pushSpringback( m_currentNode, m_affectedArea );
|
pushSpringback( m_currentNode, m_affectedArea, aVia );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -93,7 +93,7 @@ private:
|
||||||
struct SPRINGBACK_TAG
|
struct SPRINGBACK_TAG
|
||||||
{
|
{
|
||||||
int64_t m_length;
|
int64_t m_length;
|
||||||
int m_segments;
|
VIA* m_draggedVia;
|
||||||
VECTOR2I m_p;
|
VECTOR2I m_p;
|
||||||
NODE* m_node;
|
NODE* m_node;
|
||||||
OPT_BOX2I m_affectedArea;
|
OPT_BOX2I m_affectedArea;
|
||||||
|
@ -102,8 +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 );
|
||||||
|
|
||||||
bool reduceSpringback( const ITEM_SET& aHeadItems );
|
NODE* reduceSpringback( const ITEM_SET& aHeadItems, VIA** aDraggedVia );
|
||||||
bool pushSpringback( NODE* aNode, const OPT_BOX2I& aAffectedArea );
|
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 );
|
||||||
bool checkBumpDirection( const LINE& aCurrent, const LINE& aShoved ) const;
|
bool checkBumpDirection( const LINE& aCurrent, const LINE& aShoved ) const;
|
||||||
|
|
Loading…
Reference in New Issue