const DIRECTION_45 PNS_ROUTING_SETTINGS::InitialDirection() const { if( m_startDiagonal ) return DIRECTION_45( DIRECTION_45::NE ); else return DIRECTION_45( DIRECTION_45::N ); }
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; }
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 ); }
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; }