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; }
const PNS_ITEMSET PNS_DIFF_PAIR_PLACER::Traces() { PNS_ITEMSET t; t.Add( const_cast<PNS_LINE*>( &m_currentTrace.PLine() ) ); t.Add( const_cast<PNS_LINE*>( &m_currentTrace.NLine() ) ); return t; }
const PNS_ITEMSET PNS_TOPOLOGY::AssembleTrivialPath( PNS_SEGMENT* aStart ) { PNS_ITEMSET path; std::set<PNS_ITEM*> visited; PNS_LINE l = m_world->AssembleLine( aStart ); path.Add( l ); followTrivialPath( &l, false, path, visited ); followTrivialPath( &l, true, path, visited ); return path; }
bool PNS_DIFF_PAIR_PLACER::rhShoveOnly( const VECTOR2I& aP ) { m_currentNode = m_shove->CurrentNode(); bool ok = routeHead( aP ); m_fitOk = false; if( !ok ) return false; if( !tryWalkDp( m_currentNode, m_currentTrace, true ) ) return false; PNS_LINE pLine( m_currentTrace.PLine() ); PNS_LINE nLine( m_currentTrace.NLine() ); PNS_ITEMSET head; head.Add( &pLine ); head.Add( &nLine ); PNS_SHOVE::SHOVE_STATUS status = m_shove->ShoveMultiLines( head ); m_currentNode = m_shove->CurrentNode(); if( status == PNS_SHOVE::SH_OK ) { m_currentNode = m_shove->CurrentNode(); if( !m_currentNode->CheckColliding( &m_currentTrace.PLine() ) && !m_currentNode->CheckColliding( &m_currentTrace.NLine() ) ) { m_fitOk = true; } } return m_fitOk; }