router: allow for insertion of a via without leading trace (e.g. in the middle of already existing trace)
This commit is contained in:
parent
a3edd9706f
commit
f96c65254c
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
|
Loading…
Reference in New Issue