コード例 #1
0
const PNS_TOPOLOGY::JOINT_SET PNS_TOPOLOGY::ConnectedJoints( PNS_JOINT* aStart )
{
    std::deque<PNS_JOINT*> searchQueue;
    JOINT_SET processed;

    searchQueue.push_back( aStart );
    processed.insert( aStart );

    while( !searchQueue.empty() )
    {
        PNS_JOINT* current = searchQueue.front();
        searchQueue.pop_front();

        for( PNS_ITEM* item : current->LinkList() )
        {
            if( item->OfKind( PNS_ITEM::SEGMENT ) )
            {
                PNS_SEGMENT* seg = static_cast<PNS_SEGMENT*>( item );
                PNS_JOINT* a = m_world->FindJoint( seg->Seg().A, seg );
                PNS_JOINT* b = m_world->FindJoint( seg->Seg().B, seg );
                PNS_JOINT* next = ( *a == *current ) ? b : a;

                if( processed.find( next ) == processed.end() )
                {
                    processed.insert( next );
                    searchQueue.push_back( next );
                }
            }
        }
    }

    return processed;
}
コード例 #2
0
OPT_VECTOR2I PNS_DIFF_PAIR_PLACER::getDanglingAnchor( PNS_NODE* aNode, PNS_ITEM* aItem )
{
    switch( aItem->Kind() )
    {
    case PNS_ITEM::VIA:
    case PNS_ITEM::SOLID:
        return aItem->Anchor( 0 );

    case PNS_ITEM::SEGMENT:
    {
        PNS_SEGMENT* s =static_cast<PNS_SEGMENT*>( aItem );

        PNS_JOINT* jA = aNode->FindJoint( s->Seg().A, s );
        PNS_JOINT* jB = aNode->FindJoint( s->Seg().B, s );

        if( jA->LinkCount() == 1 )
            return s->Seg().A;
        else if( jB->LinkCount() == 1 )
            return s->Seg().B;
        else
            return OPT_VECTOR2I();
    }

    default:
        return OPT_VECTOR2I();
        break;
    }
}
コード例 #3
0
bool PNS_TOPOLOGY::followTrivialPath( PNS_LINE* aLine, bool aLeft, PNS_ITEMSET& aSet, std::set<PNS_ITEM*>& aVisited )
{
    VECTOR2I anchor = aLeft ? aLine->CPoint( 0 ) : aLine->CPoint( -1 );
    PNS_SEGMENT* last = aLeft ? aLine->LinkedSegments()->front() : aLine->LinkedSegments()->back();
    PNS_JOINT* jt = m_world->FindJoint( anchor, aLine );

    assert( jt != NULL );

    aVisited.insert( last );

    if( jt->IsNonFanoutVia() || jt->IsTraceWidthChange() )
    {
        PNS_ITEM* via = NULL;
        PNS_SEGMENT* next_seg = NULL;

        for( PNS_ITEM* link : jt->Links().Items() )
        {
            if( link->OfKind( PNS_ITEM::VIA ) )
                via = link;
            else if( aVisited.find( link ) == aVisited.end() )
                next_seg = static_cast<PNS_SEGMENT*>( link );
        }

        if( !next_seg )
            return false;

        PNS_LINE l = m_world->AssembleLine( next_seg );

        VECTOR2I nextAnchor = ( aLeft ? l.CLine().CPoint( -1 ) : l.CLine().CPoint( 0 ) );

        if( nextAnchor != anchor )
        {
            l.Reverse();
        }

        if( aLeft )
        {
            if( via )
                aSet.Prepend( via );

            aSet.Prepend( l );
        }
        else
        {
            if( via )
                aSet.Add( via );

            aSet.Add( l );
        }

        return followTrivialPath( &l, aLeft, aSet, aVisited );
    }

    return false;
}
コード例 #4
0
bool PNS_TOPOLOGY::LeadingRatLine( const PNS_LINE* aTrack, SHAPE_LINE_CHAIN& aRatLine )
{
    PNS_LINE track( *aTrack );
    VECTOR2I end;

    if( !track.PointCount() )
        return false;

    std::unique_ptr<PNS_NODE> tmpNode( m_world->Branch() );
    tmpNode->Add( &track );

    PNS_JOINT* jt = tmpNode->FindJoint( track.CPoint( -1 ), &track );

    if( !jt )
       return false;

    if( ( !track.EndsWithVia() && jt->LinkCount() >= 2 ) || ( track.EndsWithVia() && jt->LinkCount() >= 3 ) ) // we got something connected
    {
        end = jt->Pos();
    }
    else
    {
        int anchor;

        PNS_TOPOLOGY topo( tmpNode.get() );
        PNS_ITEM* it = topo.NearestUnconnectedItem( jt, &anchor );

        if( !it )
            return false;

        end = it->Anchor( anchor );
    }

    aRatLine.Clear();
    aRatLine.Append( track.CPoint( -1 ) );
    aRatLine.Append( end );
    return true;
}
コード例 #5
0
void PNS_LINE_PLACER::splitAdjacentSegments( PNS_NODE* aNode, PNS_ITEM* aSeg, const VECTOR2I& aP )
{
    if( aSeg && aSeg->OfKind( PNS_ITEM::SEGMENT ) )
    {
        PNS_JOINT* jt = aNode->FindJoint( aP, aSeg );

        if( jt && jt->LinkCount() >= 1 )
            return;

        PNS_SEGMENT* s_old = static_cast<PNS_SEGMENT*>( aSeg );
        PNS_SEGMENT* s_new[2];

        s_new[0] = s_old->Clone();
        s_new[1] = s_old->Clone();

        s_new[0]->SetEnds( s_old->Seg().A, aP );
        s_new[1]->SetEnds( aP, s_old->Seg().B );

        aNode->Remove( s_old );
        aNode->Add( s_new[0], true );
        aNode->Add( s_new[1], true );
    }
}