router: allow for insertion of a via without leading trace (e.g. in the middle of already existing trace)

This commit is contained in:
Tomasz Wlostowski 2015-07-02 16:09:24 +02:00 committed by Maciej Suminski
parent a3edd9706f
commit f96c65254c
5 changed files with 82 additions and 70 deletions

View File

@ -707,10 +707,7 @@ void PNS_LINE::Reverse()
void PNS_LINE::AppendVia( const PNS_VIA& aVia )
{
if( m_line.PointCount() == 0 )
return;
if( aVia.Pos() == m_line.CPoint( 0 ) )
if( m_line.PointCount() > 1 && aVia.Pos() == m_line.CPoint( 0 ) )
{
Reverse();
}

View File

@ -357,42 +357,16 @@ bool PNS_LINE_PLACER::mergeHead()
}
bool PNS_LINE_PLACER::handleViaPlacement( PNS_LINE& aHead )
{
if( !m_placingVia )
return true;
PNS_VIA v ( makeVia ( aHead.CPoint( -1 ) ) );
v.SetNet ( aHead.Net() );
VECTOR2I force;
VECTOR2I lead = aHead.CPoint( -1 ) - aHead.CPoint( 0 );
bool solidsOnly = ( m_currentMode != RM_Walkaround );
if( v.PushoutForce( m_currentNode, lead, force, solidsOnly, 40 ) )
{
SHAPE_LINE_CHAIN line = m_direction.BuildInitialTrace(
aHead.CPoint( 0 ),
aHead.CPoint( -1 ) + force );
aHead = PNS_LINE( aHead, line );
v.SetPos( v.Pos() + force );
return true;
}
return false;
}
bool PNS_LINE_PLACER::rhWalkOnly( const VECTOR2I& aP, PNS_LINE& aNewHead )
{
SHAPE_LINE_CHAIN line = buildInitialLine( aP );
PNS_LINE initTrack( m_head, line ), walkFull;
PNS_LINE initTrack( m_head );
PNS_LINE walkFull;
int effort = 0;
bool viaOk = handleViaPlacement( initTrack );
bool rv = true;
bool rv = true, viaOk;
viaOk = buildInitialLine ( aP, initTrack );
PNS_WALKAROUND walkaround( m_currentNode, Router() );
@ -428,10 +402,8 @@ bool PNS_LINE_PLACER::rhWalkOnly( const VECTOR2I& aP, PNS_LINE& aNewHead )
PNS_OPTIMIZER::Optimize( &walkFull, effort, m_currentNode );
if( m_currentNode->CheckColliding( &walkFull ) )
{
TRACEn(0, "strange, walk line colliding\n");
}
if ( m_currentNode->CheckColliding( &walkFull ) )
return false;
m_head = walkFull;
aNewHead = walkFull;
@ -442,26 +414,18 @@ bool PNS_LINE_PLACER::rhWalkOnly( const VECTOR2I& aP, PNS_LINE& aNewHead )
bool PNS_LINE_PLACER::rhMarkObstacles( const VECTOR2I& aP, PNS_LINE& aNewHead )
{
m_head.SetShape( buildInitialLine( aP ) );
if( m_placingVia )
{
m_head.AppendVia( makeVia ( m_head.CPoint( -1 ) ) );
}
buildInitialLine( aP, m_head );
aNewHead = m_head;
return m_currentNode->CheckColliding( &m_head );
}
bool PNS_LINE_PLACER::rhShoveOnly ( const VECTOR2I& aP, PNS_LINE& aNewHead )
{
SHAPE_LINE_CHAIN line = buildInitialLine( aP );
PNS_LINE initTrack( m_head, line );
PNS_LINE initTrack( m_head );
PNS_LINE walkSolids, l2;
handleViaPlacement( initTrack );
bool viaOk = buildInitialLine( aP, initTrack );
m_currentNode = m_shove->CurrentNode();
PNS_OPTIMIZER optimizer( m_currentNode );
@ -485,7 +449,7 @@ bool PNS_LINE_PLACER::rhShoveOnly ( const VECTOR2I& aP, PNS_LINE& aNewHead )
l.Line().Append( l2.CLine() );
l.Line().Simplify();
if( m_placingVia )
if( m_placingVia && viaOk )
{
PNS_VIA v1( makeVia ( l.CPoint( -1 ) ) );
PNS_VIA v2( makeVia ( l2.CPoint( -1 ) ) );
@ -892,7 +856,15 @@ bool PNS_LINE_PLACER::FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem )
const SHAPE_LINE_CHAIN& l = pl.CLine();
if( !l.SegmentCount() )
{
if( pl.EndsWithVia() )
{
m_lastNode->Add( pl.Via().Clone() );
Router()->CommitRouting( m_lastNode );
m_idle = true;
}
return true;
}
VECTOR2I p_pre_last = l.CPoint( -1 );
const VECTOR2I p_last = l.CPoint( -1 );
@ -955,6 +927,9 @@ void PNS_LINE_PLACER::removeLoops( PNS_NODE* aNode, PNS_LINE* aLatest )
if( !aLatest->SegmentCount() )
return;
if (aLatest->CLine().CPoint(0) == aLatest->CLine().CPoint(-1))
return;
aNode->Add( aLatest, true );
for( int s = 0; s < aLatest->SegmentCount(); s++ )
@ -1046,22 +1021,56 @@ void PNS_LINE_PLACER::SetOrthoMode( bool aOrthoMode )
Move( m_currentEnd, NULL );
}
const SHAPE_LINE_CHAIN PNS_LINE_PLACER::buildInitialLine( const VECTOR2I& aP )
bool PNS_LINE_PLACER::buildInitialLine( const VECTOR2I& aP, PNS_LINE& aHead )
{
SHAPE_LINE_CHAIN l( m_direction.BuildInitialTrace( m_p_start, aP ) );
SHAPE_LINE_CHAIN l;
if( l.SegmentCount() <= 1 )
return l;
if( m_orthoMode )
if(m_p_start == aP)
{
VECTOR2I newLast = l.CSegment( 0 ).LineProject( l.CPoint( -1 ) );
l.Clear();
} else {
l = m_direction.BuildInitialTrace( m_p_start, aP );
l.Remove( -1, -1 );
l.Point( 1 ) = newLast;
if( l.SegmentCount() > 1 && m_orthoMode )
{
VECTOR2I newLast = l.CSegment( 0 ).LineProject( l.CPoint( -1 ) );
l.Remove( -1, -1 );
l.Point( 1 ) = newLast;
}
}
return l;
aHead.SetShape( l );
if( !m_placingVia )
return true;
PNS_VIA v ( makeVia ( aP ) );
v.SetNet ( aHead.Net() );
if ( m_currentMode == RM_MarkObstacles )
{
aHead.AppendVia ( v );
return true;
}
VECTOR2I force;
VECTOR2I lead = aP - m_p_start;
bool solidsOnly = ( m_currentMode != RM_Walkaround );
if( v.PushoutForce( m_currentNode, lead, force, solidsOnly, 40 ) )
{
SHAPE_LINE_CHAIN line = m_direction.BuildInitialTrace(
m_p_start,
aP + force );
aHead = PNS_LINE( aHead, line );
v.SetPos( v.Pos() + force );
return true;
}
return false; // via placement unsuccessful
}

View File

@ -253,13 +253,6 @@ private:
*/
void simplifyNewLine( PNS_NODE* aNode, PNS_SEGMENT* aLatest );
/**
* Function handleViaPlacement()
*
* Attempts to find a spot to place the via at the end of line aHead.
*/
bool handleViaPlacement( PNS_LINE& aHead );
/**
* Function checkObtusity()
*
@ -347,7 +340,7 @@ private:
const PNS_VIA makeVia ( const VECTOR2I& aP );
const SHAPE_LINE_CHAIN buildInitialLine( const VECTOR2I& aP );
bool buildInitialLine( const VECTOR2I& aP, PNS_LINE& aHead );
///> current routing direction
DIRECTION_45 m_direction;

View File

@ -986,7 +986,7 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::ShoveLines( const PNS_LINE& aCurrentHead )
m_multiLineMode = false;
// empty head? nothing to shove...
if( !aCurrentHead.SegmentCount() )
if( !aCurrentHead.SegmentCount() && !aCurrentHead.EndsWithVia() )
return SH_INCOMPLETE;
PNS_LINE* head = clone( &aCurrentHead );
@ -1183,6 +1183,9 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::ShoveDraggingVia( PNS_VIA* aVia, const VECTOR
void PNS_SHOVE::runOptimizer( PNS_NODE* aNode, PNS_LINE* aHead )
{
if(!aHead->SegmentCount())
return;
PNS_OPTIMIZER optimizer( aNode );
int optFlags = 0, n_passes = 0;

View File

@ -139,6 +139,16 @@ PNS_WALKAROUND::WALKAROUND_STATUS PNS_WALKAROUND::Route( const PNS_LINE& aInitia
WALKAROUND_STATUS s_cw = IN_PROGRESS, s_ccw = IN_PROGRESS;
SHAPE_LINE_CHAIN best_path;
// special case for via-in-the-middle-of-track placement
if( aInitialPath.PointCount() <= 1 )
{
if(aInitialPath.EndsWithVia() && m_world->CheckColliding( &aInitialPath.Via(), m_itemMask ) )
return STUCK;
aWalkPath = aInitialPath;
return DONE;
}
start( aInitialPath );
m_currentObstacle[0] = m_currentObstacle[1] = nearestObstacle( aInitialPath );