const DIRECTION_45 PNS_ROUTING_SETTINGS::InitialDirection() const
{
    if( m_startDiagonal )
        return DIRECTION_45( DIRECTION_45::NE );
    else
        return DIRECTION_45( DIRECTION_45::N );
}
Esempio n. 2
0
bool PNS_DIFF_PAIR::BuildInitial( PNS_DP_GATEWAY& aEntry, PNS_DP_GATEWAY &aTarget, bool aPrefDiagonal )
{
    SHAPE_LINE_CHAIN p = DIRECTION_45().BuildInitialTrace ( aEntry.AnchorP(), aTarget.AnchorP(), aPrefDiagonal );
    SHAPE_LINE_CHAIN n = DIRECTION_45().BuildInitialTrace ( aEntry.AnchorN(), aTarget.AnchorN(), aPrefDiagonal );

    int mask = aEntry.AllowedAngles() | DIRECTION_45::ANG_STRAIGHT | DIRECTION_45::ANG_OBTUSE;

    SHAPE_LINE_CHAIN sum_n, sum_p;
    m_p = p;
    m_n = n;

    if( aEntry.HasEntryLines() )
    {
        if( !aEntry.Entry().CheckConnectionAngle( *this, mask ) )
            return false;

        sum_p = aEntry.Entry().CP();
        sum_n = aEntry.Entry().CN();
        sum_p.Append( p );
        sum_n.Append( n );
    }
    else
    {
        sum_p = p;
        sum_n = n;
    }

    mask = aTarget.AllowedAngles() | DIRECTION_45::ANG_STRAIGHT | DIRECTION_45::ANG_OBTUSE;

    m_p = sum_p;
    m_n = sum_n;

    if( aTarget.HasEntryLines() )
    {
        PNS_DP_GATEWAY t(aTarget) ;
        t.Reverse();

        if( !CheckConnectionAngle( t.Entry(), mask ) )
            return false;

        sum_p.Append( t.Entry().CP() );
        sum_n.Append( t.Entry().CN() );
    }

    m_p = sum_p;
    m_n = sum_n;

    if( !checkGap ( p, n, m_gapConstraint ) )
        return false;

    if( p.SelfIntersecting() || n.SelfIntersecting() )
        return false;

    if( p.Intersects( n ) )
        return false;

    return true;
}
Esempio n. 3
0
DIRECTION_45 PNS_DP_PRIMITIVE_PAIR::anchorDirection( PNS_ITEM* aItem, const VECTOR2I& aP ) const
{
    if( !aItem->OfKind ( PNS_ITEM::SEGMENT ) )
        return DIRECTION_45();

    PNS_SEGMENT* s = static_cast<PNS_SEGMENT*>( aItem );

    if( s->Seg().A == aP )
        return DIRECTION_45( s->Seg().A - s->Seg().B );
    else
        return DIRECTION_45( s->Seg().B - s->Seg().A );
}
Esempio n. 4
0
    void AddDirections( VECTOR2D aP, int aMask, int aColor )
    {
        BOX2I b( aP - VECTOR2I( 10000, 10000 ), VECTOR2I( 20000, 20000 ) );

        AddBox( b, aColor );
        for( int i = 0; i < 8; i++ )
        {
            if( ( 1 << i ) & aMask )
            {
                VECTOR2I v = DIRECTION_45( ( DIRECTION_45::Directions ) i ).ToVector() * 100000;
                AddSegment( SEG( aP, aP + v ), aColor );
            }
        }
    }
bool PNS_DIFF_PAIR_PLACER::FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem )
{
    if( !m_fitOk )
        return false;

    if( m_currentTrace.CP().SegmentCount() < 1 ||
            m_currentTrace.CN().SegmentCount() < 1 )
        return false;

    if( m_currentTrace.CP().SegmentCount() > 1 )
        m_initialDiagonal = !DIRECTION_45( m_currentTrace.CP().CSegment( -2 ) ).IsDiagonal();

    PNS_TOPOLOGY topo( m_lastNode );

    if( !m_snapOnTarget && !m_currentTrace.EndsWithVias() )
    {
        SHAPE_LINE_CHAIN newP( m_currentTrace.CP() );
        SHAPE_LINE_CHAIN newN( m_currentTrace.CN() );

        if( newP.SegmentCount() > 1 && newN.SegmentCount() > 1 )
        {
            newP.Remove( -1, -1 );
            newN.Remove( -1, -1 );
        }

        m_currentTrace.SetShape( newP, newN );
    }

    if( m_currentTrace.EndsWithVias() )
    {
        m_lastNode->Add( m_currentTrace.PLine().Via().Clone() );
        m_lastNode->Add( m_currentTrace.NLine().Via().Clone() );
        m_chainedPlacement = false;
    }
    else
    {
        m_chainedPlacement = !m_snapOnTarget;
    }

    PNS_LINE lineP( m_currentTrace.PLine() );
    PNS_LINE lineN( m_currentTrace.NLine() );

    m_lastNode->Add( &lineP );
    m_lastNode->Add( &lineN );

    topo.SimplifyLine( &lineP );
    topo.SimplifyLine( &lineN );

    m_prevPair = m_currentTrace.EndingPrimitives();

    Router()->CommitRouting( m_lastNode );

    m_lastNode = NULL;
    m_placingVia = false;

    if( m_snapOnTarget )
    {
        m_idle = true;
        return true;
    }
    else
    {
        initPlacement();
        return false;
    }
}
bool PNS_DIFF_PAIR_PLACER::routeHead( const VECTOR2I& aP )
{
    m_fitOk = false;

    PNS_DP_GATEWAYS gwsEntry( gap() );
    PNS_DP_GATEWAYS gwsTarget( gap() );

    if( !m_prevPair )
        m_prevPair = m_start;

    gwsEntry.BuildFromPrimitivePair( *m_prevPair, m_startDiagonal );

    PNS_DP_PRIMITIVE_PAIR target;

    if( findDpPrimitivePair( aP, m_currentEndItem, target ) )
    {
        gwsTarget.BuildFromPrimitivePair( target, m_startDiagonal );
        m_snapOnTarget = true;
    }
    else
    {
        VECTOR2I fp;

        if( !propagateDpHeadForces( aP, fp ) )
            return false;

        VECTOR2I midp, dirV;
        m_prevPair->CursorOrientation( fp, midp, dirV );

        VECTOR2I fpProj = SEG( midp, midp + dirV ).LineProject( fp );
        int lead_dist = ( fpProj - fp ).EuclideanNorm();

        gwsTarget.SetFitVias( m_placingVia, m_sizes.ViaDiameter(), viaGap() );

        if( lead_dist > m_sizes.DiffPairGap() + m_sizes.DiffPairWidth() )
        {
            gwsTarget.BuildForCursor( fp );
        }
        else
        {
            gwsTarget.BuildForCursor( fpProj );
            gwsTarget.FilterByOrientation( DIRECTION_45::ANG_STRAIGHT | DIRECTION_45::ANG_HALF_FULL, DIRECTION_45( dirV ) );
        }

        m_snapOnTarget = false;
    }

    m_currentTrace = PNS_DIFF_PAIR();
    m_currentTrace.SetGap( gap() );
    m_currentTrace.SetLayer( m_currentLayer );

    bool result = gwsEntry.FitGateways( gwsEntry, gwsTarget, m_startDiagonal, m_currentTrace );

    if( result )
    {
        m_currentTrace.SetNets( m_netP, m_netN );
        m_currentTrace.SetWidth( m_sizes.DiffPairWidth() );
        m_currentTrace.SetGap( m_sizes.DiffPairGap() );

        if( m_placingVia )
        {
            m_currentTrace.AppendVias ( makeVia( m_currentTrace.CP().CPoint( -1 ), m_netP ),
                                        makeVia( m_currentTrace.CN().CPoint( -1 ), m_netN ) );
        }

        return true;
    }

    return false;
}