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;
    }
}
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;
}
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 );
    }
}