P&S: cleaner placement of DP segments/vias. Speed improvements too.

This commit is contained in:
Tomasz Wlostowski 2016-08-15 17:16:49 +02:00 committed by Maciej Suminski
parent 4cbb0aebfd
commit a2ac1cd087
3 changed files with 98 additions and 57 deletions

View File

@ -34,7 +34,7 @@
#include "pns_router.h"
#include "pns_solid.h"
#include "pns_utils.h"
#include "pns_debug_decorator.h"
class PNS_LINE;
@ -121,6 +121,42 @@ DIRECTION_45 PNS_DP_PRIMITIVE_PAIR::anchorDirection( PNS_ITEM* aItem, const VECT
return DIRECTION_45( s->Seg().B - s->Seg().A );
}
void PNS_DP_PRIMITIVE_PAIR::CursorOrientation( const VECTOR2I& aCursorPos, VECTOR2I& aMidpoint, VECTOR2I& aDirection ) const
{
assert (m_primP && m_primN);
VECTOR2I aP, aN, dir, midpoint;
if ( m_primP->OfKind(PNS_ITEM::SEGMENT) && m_primN->OfKind(PNS_ITEM::SEGMENT) )
{
aP = m_primP->Anchor( 1 );
aN = m_primN->Anchor( 1 );
midpoint = ( aP + aN ) / 2;
SEG s = static_cast <PNS_SEGMENT*> (m_primP)->Seg();
if ( s.B != s.A )
{
dir = s.B - s.A;
}
else
{
dir = VECTOR2I(0, 1);
}
dir = dir.Resize( (aP - aN).EuclideanNorm() );
} else {
aP = m_primP->Anchor( 0 );
aN = m_primN->Anchor( 0 );
midpoint = ( aP + aN ) / 2;
dir = ( aP - aN ).Perpendicular();
if ( dir.Dot( aCursorPos - midpoint ) < 0 )
dir = -dir;
}
aMidpoint = midpoint;
aDirection = dir;
}
DIRECTION_45 PNS_DP_PRIMITIVE_PAIR::DirP() const
{
@ -134,19 +170,6 @@ DIRECTION_45 PNS_DP_PRIMITIVE_PAIR::DirN() const
}
static void drawGw( VECTOR2I p, int color )
{
SHAPE_LINE_CHAIN l;
l.Append( p - VECTOR2I( -50000, -50000 ) );
l.Append( p + VECTOR2I( -50000, -50000 ) );
l.Clear();
l.Append( p - VECTOR2I( 50000, -50000 ) );
l.Append( p + VECTOR2I( 50000, -50000 ) );
}
static DIRECTION_45::AngleType angle( const VECTOR2I &a, const VECTOR2I &b )
{
DIRECTION_45 dir_a( a );
@ -182,7 +205,7 @@ void PNS_DP_GATEWAY::Reverse()
}
bool PNS_DIFF_PAIR::BuildInitial( PNS_DP_GATEWAY& aEntry, PNS_DP_GATEWAY &aTarget, bool aPrefDiagonal )
bool PNS_DIFF_PAIR::BuildInitial( const PNS_DP_GATEWAY& aEntry, const 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 );
@ -314,45 +337,41 @@ void PNS_DP_GATEWAYS::BuildOrthoProjections( PNS_DP_GATEWAYS& aEntries,
bool PNS_DP_GATEWAYS::FitGateways( PNS_DP_GATEWAYS& aEntry, PNS_DP_GATEWAYS& aTarget,
bool aPrefDiagonal, PNS_DIFF_PAIR& aDp )
{
std::vector<DP_CANDIDATE> candidates;
DP_CANDIDATE best;
for( PNS_DP_GATEWAY g_entry : aEntry.Gateways() )
int n = 0;
int bestScore = -1000;
bool found = false;
for( const PNS_DP_GATEWAY& g_entry : aEntry.Gateways() )
{
for( PNS_DP_GATEWAY g_target : aTarget.Gateways() )
for( const PNS_DP_GATEWAY& g_target : aTarget.Gateways() )
{
n++;
for( int attempt = 0; attempt < 2; attempt++ )
{
int score = ( attempt == 1 ? -3 : 0 );
score += g_entry.Priority();
score += g_target.Priority();
if( score < bestScore )
continue;
PNS_DIFF_PAIR l( m_gap );
if( l.BuildInitial( g_entry, g_target, aPrefDiagonal ^ ( attempt ? true : false ) ) )
{
int score = ( attempt == 1 ? -3 : 0 );
score +=g_entry.Priority();
score +=g_target.Priority();
DP_CANDIDATE c;
c.score = score;
c.p = l.CP();
c.n = l.CN();
candidates.push_back( c );
}
}
}
}
int bestScore = -1000;
DP_CANDIDATE best;
bool found = false;
for( DP_CANDIDATE c : candidates )
{
if( c.score > bestScore )
{
bestScore = c.score;
best = c;
best.p = l.CP();
best.n = l.CN();
bestScore = score;
found = true;
}
}
}
}
if( found )
{
@ -373,6 +392,14 @@ bool PNS_DP_GATEWAYS::checkDiagonalAlignment( const VECTOR2I& a, const VECTOR2I&
}
void PNS_DP_GATEWAYS::FilterByOrientation ( int aAngleMask, DIRECTION_45 aRefOrientation )
{
std::remove_if( m_gateways.begin(), m_gateways.end(), [aAngleMask, aRefOrientation] ( const PNS_DP_GATEWAY& dp) {
DIRECTION_45 orient ( dp.AnchorP() - dp.AnchorN() );
return ! (orient.Angle ( aRefOrientation ) & aAngleMask );
} );
}
void PNS_DP_GATEWAYS::BuildFromPrimitivePair( PNS_DP_PRIMITIVE_PAIR aPair, bool aPreferDiagonal )
{
VECTOR2I majorDirection;
@ -519,8 +546,6 @@ void PNS_DP_GATEWAYS::BuildForCursor( const VECTOR2I& aCursorPos )
m_gateways.push_back( PNS_DP_GATEWAY( aCursorPos + dir,
aCursorPos - dir, attempt ? true : false ) );
drawGw ( aCursorPos + dir, 2 );
drawGw ( aCursorPos - dir, 3 );
}
}
}

View File

@ -157,6 +157,9 @@ public:
DIRECTION_45 DirP() const;
DIRECTION_45 DirN() const;
void CursorOrientation( const VECTOR2I& aCursorPos, VECTOR2I& aMidpoint, VECTOR2I& aDirection ) const;
void dump()
{
printf("-- Prim-P %p anchor [%d, %d]\n", m_primP, m_anchorP.x, m_anchorP.y);
@ -223,6 +226,13 @@ class PNS_DP_GATEWAYS
return m_gateways;
}
const std::vector<PNS_DP_GATEWAY>& CGateways() const
{
return m_gateways;
}
void FilterByOrientation ( int aAngleMask, DIRECTION_45 aRefOrientation );
private:
struct DP_CANDIDATE
@ -460,7 +470,7 @@ public:
const SHAPE_LINE_CHAIN& CP() const { return m_p; }
const SHAPE_LINE_CHAIN& CN() const { return m_n; }
bool BuildInitial ( PNS_DP_GATEWAY& aEntry, PNS_DP_GATEWAY& aTarget, bool aPrefDiagonal );
bool BuildInitial ( const PNS_DP_GATEWAY& aEntry, const PNS_DP_GATEWAY& aTarget, bool aPrefDiagonal );
bool CheckConnectionAngle ( const PNS_DIFF_PAIR &aOther, int allowedAngles ) const;
int CoupledLength ( const SEG& aP, const SEG& aN ) const;

View File

@ -18,9 +18,6 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <boost/optional.hpp>
#include <colors.h>
#include <class_board.h>
#include <class_board_item.h>
#include <class_netinfo.h>
@ -37,8 +34,6 @@
#include "pns_topology.h"
#include "pns_debug_decorator.h"
using boost::optional;
PNS_DIFF_PAIR_PLACER::PNS_DIFF_PAIR_PLACER( PNS_ROUTER* aRouter ) :
PNS_PLACEMENT_ALGO( aRouter )
{
@ -664,10 +659,6 @@ bool PNS_DIFF_PAIR_PLACER::routeHead( const VECTOR2I& aP )
gwsEntry.BuildFromPrimitivePair( *m_prevPair, m_startDiagonal );
// m_prevPair->dump();
// printf("Entry %d\n", gwsEntry.Gateways().size());
PNS_DP_PRIMITIVE_PAIR target;
if( findDpPrimitivePair ( aP, m_currentEndItem, target ) )
@ -680,10 +671,23 @@ bool PNS_DIFF_PAIR_PLACER::routeHead( const VECTOR2I& aP )
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 );
gwsTarget.BuildOrthoProjections( gwsEntry, fp, m_orthoMode ? 200 : -200 );
// printf("Target %d\n", gwsTarget.Gateways().size());
} else {
gwsTarget.BuildForCursor( fpProj );
gwsTarget.FilterByOrientation ( DIRECTION_45::ANG_STRAIGHT | DIRECTION_45::ANG_HALF_FULL, DIRECTION_45 ( dirV ) );
}
m_snapOnTarget = false;
}
@ -691,7 +695,9 @@ bool PNS_DIFF_PAIR_PLACER::routeHead( const VECTOR2I& aP )
m_currentTrace.SetGap( gap() );
m_currentTrace.SetLayer( m_currentLayer );
if ( gwsEntry.FitGateways( gwsEntry, gwsTarget, m_startDiagonal, m_currentTrace ) )
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() );