diff --git a/pcbnew/router/pns_line_placer.cpp b/pcbnew/router/pns_line_placer.cpp index 45e71b6431..496c6aac1b 100644 --- a/pcbnew/router/pns_line_placer.cpp +++ b/pcbnew/router/pns_line_placer.cpp @@ -368,18 +368,19 @@ bool LINE_PLACER::mergeHead() VECTOR2I closestProjectedPoint( const SHAPE_LINE_CHAIN& line, const VECTOR2I& p ) { - int min_dist = INT_MAX; - VECTOR2I closest; + // Keep distances squared for performance + SEG::ecoord min_dist_sq = VECTOR2I::ECOORD_MAX; + VECTOR2I closest; - for(int i = 0; i < line.SegmentCount(); i++ ) + for( int i = 0; i < line.SegmentCount(); i++ ) { - const auto& s = line.CSegment(i); - auto a = s.NearestPoint( p ); - auto d = (a - p).EuclideanNorm(); + const SEG& s = line.CSegment(i); + VECTOR2I a = s.NearestPoint( p ); + int d_sq = (a - p).SquaredEuclideanNorm(); - if( d < min_dist ) + if( d_sq < min_dist_sq ) { - min_dist = d; + min_dist_sq = d_sq; closest = a; } } @@ -407,14 +408,14 @@ bool LINE_PLACER::rhWalkOnly( const VECTOR2I& aP, LINE& aNewHead ) WALKAROUND::RESULT wr = walkaround.Route( initTrack ); //WALKAROUND::WALKAROUND_STATUS wf = walkaround.Route( initTrack, walkFull, false ); - auto l_cw = wr.lineCw.CLine(); - auto l_ccw = wr.lineCcw.CLine(); + SHAPE_LINE_CHAIN l_cw = wr.lineCw.CLine(); + SHAPE_LINE_CHAIN l_ccw = wr.lineCcw.CLine(); if( wr.statusCcw == WALKAROUND::ALMOST_DONE || wr.statusCw == WALKAROUND::ALMOST_DONE ) { - auto p_cw = closestProjectedPoint( l_cw, aP ); - auto p_ccw = closestProjectedPoint( l_ccw, aP ); + VECTOR2I p_cw = closestProjectedPoint( l_cw, aP ); + VECTOR2I p_ccw = closestProjectedPoint( l_ccw, aP ); int idx_cw = l_cw.Split( p_cw ); int idx_ccw = l_ccw.Split( p_ccw ); @@ -1097,7 +1098,7 @@ bool LINE_PLACER::FixRoute( const VECTOR2I& aP, ITEM* aEndItem, bool aForceFinis if( arcIndex == lastArc ) continue; - auto arc = std::make_unique( l.Arc( arcIndex ), m_currentNet ); + std::unique_ptr arc = std::make_unique( l.Arc( arcIndex ), m_currentNet ); arc->SetWidth( pl.Width() ); arc->SetLayer( m_currentLayer ); m_lastNode->Add( std::move( arc ) ); @@ -1481,7 +1482,7 @@ void POSTURE_SOLVER::AddTrailPoint( const VECTOR2I& aP ) for( int i = 0; i < m_trail.SegmentCount() - 1; i++ ) { - const auto& s_trail = m_trail.CSegment( i ); + const SEG& s_trail = m_trail.CSegment( i ); if( s_trail.Distance( s_new ) <= m_tolerance ) { @@ -1495,9 +1496,7 @@ void POSTURE_SOLVER::AddTrailPoint( const VECTOR2I& aP ) m_trail.Simplify(); - auto dbg = ROUTER::GetInstance()->GetInterface()->GetDebugDecorator(); - - dbg->AddLine( m_trail, 5, 100000 ); + ROUTER::GetInstance()->GetInterface()->GetDebugDecorator()->AddLine( m_trail, 5, 100000 ); } @@ -1526,13 +1525,11 @@ DIRECTION_45 POSTURE_SOLVER::GetPosture( const VECTOR2I& aP ) return m_direction; } - auto dbg = ROUTER::GetInstance()->GetInterface()->GetDebugDecorator(); - - auto p0 = m_trail.CPoint( 0 ); - - double refLength = SEG( p0, aP ).Length(); - + DEBUG_DECORATOR* dbg = ROUTER::GetInstance()->GetInterface()->GetDebugDecorator(); + VECTOR2I p0 = m_trail.CPoint( 0 ); + double refLength = SEG( p0, aP ).Length(); SHAPE_LINE_CHAIN straight( DIRECTION_45().BuildInitialTrace( p0, aP, false, false ) ); + straight.SetClosed( true ); straight.Append( m_trail.Reverse() ); straight.Simplify(); diff --git a/pcbnew/router/pns_optimizer.cpp b/pcbnew/router/pns_optimizer.cpp index 563235707d..25873696b7 100644 --- a/pcbnew/router/pns_optimizer.cpp +++ b/pcbnew/router/pns_optimizer.cpp @@ -51,23 +51,12 @@ int COST_ESTIMATOR::CornerCost( const SEG& aA, const SEG& aB ) switch( dir_a.Angle( dir_b ) ) { - case DIRECTION_45::ANG_OBTUSE: - return 10; - - case DIRECTION_45::ANG_STRAIGHT: - return 5; - - case DIRECTION_45::ANG_ACUTE: - return 50; - - case DIRECTION_45::ANG_RIGHT: - return 30; - - case DIRECTION_45::ANG_HALF_FULL: - return 60; - - default: - return 100; + case DIRECTION_45::ANG_OBTUSE: return 10; + case DIRECTION_45::ANG_STRAIGHT: return 5; + case DIRECTION_45::ANG_ACUTE: return 50; + case DIRECTION_45::ANG_RIGHT: return 30; + case DIRECTION_45::ANG_HALF_FULL: return 60; + default: return 100; } } @@ -112,9 +101,8 @@ void COST_ESTIMATOR::Replace( const LINE& aOldLine, const LINE& aNewLine ) } -bool COST_ESTIMATOR::IsBetter( const COST_ESTIMATOR& aOther, - double aLengthTolerance, - double aCornerTolerance ) const +bool COST_ESTIMATOR::IsBetter( const COST_ESTIMATOR& aOther, double aLengthTolerance, + double aCornerTolerance ) const { if( aOther.m_cornerCost < m_cornerCost && aOther.m_lengthCost < m_lengthCost ) return true; @@ -133,8 +121,7 @@ bool COST_ESTIMATOR::IsBetter( const COST_ESTIMATOR& aOther, OPTIMIZER::OPTIMIZER( NODE* aWorld ) : m_world( aWorld ), m_collisionKindMask( ITEM::ANY_T ), - m_effortLevel( MERGE_SEGMENTS ), - m_keepPostures( false ) + m_effortLevel( MERGE_SEGMENTS ) { } @@ -208,12 +195,6 @@ void OPTIMIZER::CacheRemove( ITEM* aItem ) } -void OPTIMIZER::CacheStaticItem( ITEM* aItem ) -{ - cacheAdd( aItem, true ); -} - - void OPTIMIZER::ClearCache( bool aStaticOnly ) { if( !aStaticOnly ) @@ -223,7 +204,7 @@ void OPTIMIZER::ClearCache( bool aStaticOnly ) return; } - for( CachedItemTags::iterator i = m_cacheTags.begin(); i!= m_cacheTags.end(); ++i ) + for( auto i = m_cacheTags.begin(); i!= m_cacheTags.end(); ++i ) { if( i->second.m_isStatic ) { @@ -234,65 +215,30 @@ void OPTIMIZER::ClearCache( bool aStaticOnly ) } -bool ANGLE_CONSTRAINT_45::Check( int aVertex1, int aVertex2, const LINE* aOriginLine, const SHAPE_LINE_CHAIN& aCurrentPath, const SHAPE_LINE_CHAIN& aReplacement ) +bool AREA_CONSTRAINT::Check( int aVertex1, int aVertex2, const LINE* aOriginLine, + const SHAPE_LINE_CHAIN& aCurrentPath, + const SHAPE_LINE_CHAIN& aReplacement ) { - auto dir_orig0 = DIRECTION_45( aOriginLine->CSegment( aVertex1 ) ); - auto dir_orig1 = DIRECTION_45( aOriginLine->CSegment( aVertex2 - 1) ); + const VECTOR2I& p1 = aOriginLine->CPoint( aVertex1 ); + const VECTOR2I& p2 = aOriginLine->CPoint( aVertex2 ); - if( aVertex1 == 0 ) - { - if( ( dir_orig0.Mask() & m_entryDirectionMask ) == 0 ) - return false; // disallowed entry angle - } - - if( aVertex2 == aOriginLine->SegmentCount() - 1 ) - { - if( ( dir_orig1.Mask() & m_exitDirectionMask ) == 0 ) - return false; // disallowed exit ngle - } - - - - /*auto ang_rep0 = DIRECTION_45( aReplacement.CSegment(0) ).Angle( dir_orig0 ); - auto ang_rep1 = DIRECTION_45( aReplacement.CSegment(-1) ).Angle( dir_orig1 );*/ - - return true; -} - -bool AREA_CONSTRAINT::Check( int aVertex1, int aVertex2, const LINE* aOriginLine, const SHAPE_LINE_CHAIN& aCurrentPath, const SHAPE_LINE_CHAIN& aReplacement ) -{ - auto p1 = aOriginLine->CPoint( aVertex1 ); - auto p2 = aOriginLine->CPoint( aVertex2 ); - - auto p1_in = m_allowedArea.Contains( p1 ); - auto p2_in = m_allowedArea.Contains( p2 ); + bool p1_in = m_allowedArea.Contains( p1 ); + bool p2_in = m_allowedArea.Contains( p2 ); return p1_in || p2_in; } -class JOINT_CACHE - { - public: - JOINT_CACHE( NODE *aWorld, int aLayer, int aMaxJoints ); - bool CheckInside( const VECTOR2I& aPos ) const; - - private: - - struct ENTRY { - JOINT* joint; - int score; - }; -}; - - -bool PRESERVE_VERTEX_CONSTRAINT::Check( int aVertex1, int aVertex2, const LINE* aOriginLine, const SHAPE_LINE_CHAIN& aCurrentPath, const SHAPE_LINE_CHAIN& aReplacement ) +bool PRESERVE_VERTEX_CONSTRAINT::Check( int aVertex1, int aVertex2, const LINE* aOriginLine, + const SHAPE_LINE_CHAIN& aCurrentPath, + const SHAPE_LINE_CHAIN& aReplacement ) { bool cv = false; for( int i = aVertex1; i < aVertex2; i++ ) { - int dist = aCurrentPath.CSegment(i).Distance( m_v ); + SEG::ecoord dist = aCurrentPath.CSegment(i).SquaredDistance( m_v ); + if ( dist <= 1 ) { cv = true; @@ -300,26 +246,24 @@ bool PRESERVE_VERTEX_CONSTRAINT::Check( int aVertex1, int aVertex2, const LINE* } } - if(!cv) - { + if( !cv ) return true; - } for( int i = 0; i < aReplacement.SegmentCount(); i++ ) { - int dist = aReplacement.CSegment(i).Distance( m_v ); + SEG::ecoord dist = aReplacement.CSegment(i).SquaredDistance( m_v ); if ( dist <= 1 ) - { return true; - } } return false; } -bool RESTRICT_VERTEX_RANGE_CONSTRAINT::Check( int aVertex1, int aVertex2, const LINE* aOriginLine, const SHAPE_LINE_CHAIN& aCurrentPath, const SHAPE_LINE_CHAIN& aReplacement ) +bool RESTRICT_VERTEX_RANGE_CONSTRAINT::Check( int aVertex1, int aVertex2, const LINE* aOriginLine, + const SHAPE_LINE_CHAIN& aCurrentPath, + const SHAPE_LINE_CHAIN& aReplacement ) { return true; } @@ -335,18 +279,17 @@ static bool pointInside2( const SHAPE_LINE_CHAIN& aL, const VECTOR2I& aP ) int result = 0; size_t cnt = aL.PointCount(); - auto ip = aL.CPoint( 0 ); + VECTOR2I ip = aL.CPoint( 0 ); for( size_t i = 1; i <= cnt; ++i ) { - auto ipNext = (i == cnt ? aL.CPoint( 0 ) : aL.CPoint( i )); + VECTOR2I ipNext = (i == cnt ? aL.CPoint( 0 ) : aL.CPoint( i )); if( ipNext.y == aP.y ) { - if( (ipNext.x ==aP.x) || ( ip.y ==aP.y - && ( (ipNext.x >aP.x) == (ip.x aP.x) == (ip.x CLine().Slice( aVertex1, aVertex2 ); // fixme: this is a remarkably shitty implementation... encPoly.Append( aReplacement.Reverse() ); encPoly.SetClosed( true ); - auto bb = encPoly.BBox(); + BOX2I bb = encPoly.BBox(); std::vector joints; int cnt = m_world->QueryJoints( bb, joints, aOriginLine->Layers(), ITEM::SOLID_T ); @@ -407,7 +352,7 @@ bool KEEP_TOPOLOGY_CONSTRAINT::Check( int aVertex1, int aVertex2, const LINE* aO if( !cnt ) return true; - for( auto j : joints ) + for( JOINT* j : joints ) { if( j->Net() == aOriginLine->Net() ) continue; @@ -435,6 +380,7 @@ bool KEEP_TOPOLOGY_CONSTRAINT::Check( int aVertex1, int aVertex2, const LINE* aO return true; } + bool OPTIMIZER::checkColliding( ITEM* aItem, bool aUpdateCache ) { CACHE_VISITOR v( aItem, m_world, m_collisionKindMask ); @@ -442,26 +388,30 @@ bool OPTIMIZER::checkColliding( ITEM* aItem, bool aUpdateCache ) return static_cast( m_world->CheckColliding( aItem ) ); } + void OPTIMIZER::ClearConstraints() { - for( auto c : m_constraints) + for( OPT_CONSTRAINT* c : m_constraints ) delete c; + m_constraints.clear(); } + void OPTIMIZER::AddConstraint ( OPT_CONSTRAINT *aConstraint ) { - m_constraints.push_back(aConstraint); + m_constraints.push_back( aConstraint ); } -bool OPTIMIZER::checkConstraints( int aVertex1, int aVertex2, LINE* aOriginLine, const SHAPE_LINE_CHAIN& aCurrentPath, const SHAPE_LINE_CHAIN& aReplacement ) + +bool OPTIMIZER::checkConstraints( int aVertex1, int aVertex2, LINE* aOriginLine, + const SHAPE_LINE_CHAIN& aCurrentPath, + const SHAPE_LINE_CHAIN& aReplacement ) { - for( auto c: m_constraints) + for( OPT_CONSTRAINT* c : m_constraints ) { if( !c->Check( aVertex1, aVertex2, aOriginLine, aCurrentPath, aReplacement ) ) - { return false; - } } return true; @@ -618,15 +568,15 @@ bool OPTIMIZER::mergeColinear( LINE* aLine ) bool OPTIMIZER::Optimize( LINE* aLine, LINE* aResult ) { if( !aResult ) + { aResult = aLine; + } else { *aResult = *aLine; aResult->ClearLinks(); } - m_keepPostures = false; - bool rv = false; if( m_effortLevel & PRESERVE_VERTEX ) @@ -637,7 +587,8 @@ bool OPTIMIZER::Optimize( LINE* aLine, LINE* aResult ) if( m_effortLevel & RESTRICT_VERTEX_RANGE ) { - auto c = new RESTRICT_VERTEX_RANGE_CONSTRAINT( m_world, m_restrictedVertexRange.first, m_restrictedVertexRange.second ); + auto c = new RESTRICT_VERTEX_RANGE_CONSTRAINT( m_world, m_restrictedVertexRange.first, + m_restrictedVertexRange.second ); AddConstraint( c ); } @@ -730,17 +681,18 @@ bool OPTIMIZER::mergeStep( LINE* aLine, SHAPE_LINE_CHAIN& aCurrentPath, int step } -OPTIMIZER::BREAKOUT_LIST OPTIMIZER::circleBreakouts( int aWidth, - const SHAPE* aShape, bool aPermitDiagonal ) const +OPTIMIZER::BREAKOUT_LIST OPTIMIZER::circleBreakouts( int aWidth, const SHAPE* aShape, + bool aPermitDiagonal ) const { BREAKOUT_LIST breakouts; for( int angle = 0; angle < 360; angle += 45 ) { const SHAPE_CIRCLE* cir = static_cast( aShape ); - SHAPE_LINE_CHAIN l; - VECTOR2I p0 = cir->GetCenter(); - VECTOR2I v0( cir->GetRadius() * M_SQRT2, 0 ); + SHAPE_LINE_CHAIN l; + VECTOR2I p0 = cir->GetCenter(); + VECTOR2I v0( cir->GetRadius() * M_SQRT2, 0 ); + l.Append( p0 ); l.Append( p0 + v0.Rotate( angle * M_PI / 180.0 ) ); breakouts.push_back( l ); @@ -750,8 +702,8 @@ OPTIMIZER::BREAKOUT_LIST OPTIMIZER::circleBreakouts( int aWidth, } -OPTIMIZER::BREAKOUT_LIST OPTIMIZER::customBreakouts( int aWidth, - const ITEM* aItem, bool aPermitDiagonal ) const +OPTIMIZER::BREAKOUT_LIST OPTIMIZER::customBreakouts( int aWidth, const ITEM* aItem, + bool aPermitDiagonal ) const { BREAKOUT_LIST breakouts; const SHAPE_SIMPLE* convex = static_cast( aItem->Shape() ); @@ -792,8 +744,8 @@ OPTIMIZER::BREAKOUT_LIST OPTIMIZER::customBreakouts( int aWidth, } -OPTIMIZER::BREAKOUT_LIST OPTIMIZER::rectBreakouts( int aWidth, - const SHAPE* aShape, bool aPermitDiagonal ) const +OPTIMIZER::BREAKOUT_LIST OPTIMIZER::rectBreakouts( int aWidth, const SHAPE* aShape, + bool aPermitDiagonal ) const { const SHAPE_RECT* rect = static_cast(aShape); VECTOR2I s = rect->GetSize(); @@ -847,8 +799,8 @@ OPTIMIZER::BREAKOUT_LIST OPTIMIZER::rectBreakouts( int aWidth, } -OPTIMIZER::BREAKOUT_LIST OPTIMIZER::computeBreakouts( int aWidth, - const ITEM* aItem, bool aPermitDiagonal ) const +OPTIMIZER::BREAKOUT_LIST OPTIMIZER::computeBreakouts( int aWidth, const ITEM* aItem, + bool aPermitDiagonal ) const { switch( aItem->Kind() ) { @@ -943,10 +895,12 @@ int OPTIMIZER::smartPadsSingle( LINE* aLine, ITEM* aPad, bool aEnd, int aEndVert // If the line is contained inside the pad, don't optimize if( solid && solid->Shape() && !solid->Shape()->Collide( SEG( line.CPoint( 0 ), line.CPoint( p ) ), aLine->Width() / 2 ) ) + { continue; + } - for( SHAPE_LINE_CHAIN & breakout : breakouts ) { - + for( SHAPE_LINE_CHAIN & breakout : breakouts ) + { for( int diag = 0; diag < 2; diag++ ) { SHAPE_LINE_CHAIN v; @@ -1125,15 +1079,17 @@ bool OPTIMIZER::fanoutCleanup( LINE* aLine ) } -int findCoupledVertices( const VECTOR2I& aVertex, const SEG& aOrigSeg, const SHAPE_LINE_CHAIN& aCoupled, DIFF_PAIR* aPair, int* aIndices ) +int findCoupledVertices( const VECTOR2I& aVertex, const SEG& aOrigSeg, + const SHAPE_LINE_CHAIN& aCoupled, DIFF_PAIR* aPair, int* aIndices ) { int count = 0; - for ( int i = 0; i < aCoupled.SegmentCount(); i++ ) + + for( int i = 0; i < aCoupled.SegmentCount(); i++ ) { SEG s = aCoupled.CSegment( i ); VECTOR2I projOverCoupled = s.LineProject ( aVertex ); - if( s.ApproxParallel ( aOrigSeg ) ) + if( s.ApproxParallel( aOrigSeg ) ) { int64_t dist = int64_t{(( projOverCoupled - aVertex ).EuclideanNorm())} - aPair->Width(); @@ -1149,7 +1105,8 @@ int findCoupledVertices( const VECTOR2I& aVertex, const SEG& aOrigSeg, const SHA } -bool verifyDpBypass( NODE* aNode, DIFF_PAIR* aPair, bool aRefIsP, const SHAPE_LINE_CHAIN& aNewRef, const SHAPE_LINE_CHAIN& aNewCoupled ) +bool verifyDpBypass( NODE* aNode, DIFF_PAIR* aPair, bool aRefIsP, const SHAPE_LINE_CHAIN& aNewRef, + const SHAPE_LINE_CHAIN& aNewCoupled ) { LINE refLine ( aRefIsP ? aPair->PLine() : aPair->NLine(), aNewRef ); LINE coupledLine ( aRefIsP ? aPair->NLine() : aPair->PLine(), aNewCoupled ); @@ -1167,17 +1124,19 @@ bool verifyDpBypass( NODE* aNode, DIFF_PAIR* aPair, bool aRefIsP, const SHAPE_LI } -bool coupledBypass( NODE* aNode, DIFF_PAIR* aPair, bool aRefIsP, const SHAPE_LINE_CHAIN& aRef, const SHAPE_LINE_CHAIN& aRefBypass, const SHAPE_LINE_CHAIN& aCoupled, SHAPE_LINE_CHAIN& aNewCoupled ) +bool coupledBypass( NODE* aNode, DIFF_PAIR* aPair, bool aRefIsP, const SHAPE_LINE_CHAIN& aRef, + const SHAPE_LINE_CHAIN& aRefBypass, const SHAPE_LINE_CHAIN& aCoupled, + SHAPE_LINE_CHAIN& aNewCoupled ) { - int vStartIdx[1024]; // fixme: possible overflow + int vStartIdx[1024]; // fixme: possible overflow + int nStarts = findCoupledVertices( aRefBypass.CPoint( 0 ), aRefBypass.CSegment( 0 ), + aCoupled, aPair, vStartIdx ); + DIRECTION_45 dir( aRefBypass.CSegment( 0 ) ); - int nStarts = findCoupledVertices( aRefBypass.CPoint( 0 ), aRefBypass.CSegment( 0 ), aCoupled, aPair, vStartIdx ); - DIRECTION_45 dir( aRefBypass.CSegment( 0 ) ); - - int64_t bestLength = -1; - bool found = false; + int64_t bestLength = -1; + bool found = false; SHAPE_LINE_CHAIN bestBypass; - int si, ei; + int si, ei; for( int i=0; i< nStarts; i++ ) { @@ -1188,7 +1147,8 @@ bool coupledBypass( NODE* aNode, DIFF_PAIR* aPair, bool aRefIsP, const SHAPE_LIN if( delta > 1 ) { const VECTOR2I& vs = aCoupled.CPoint( vStartIdx[i] ); - SHAPE_LINE_CHAIN bypass = dir.BuildInitialTrace( vs, aCoupled.CPoint(j), dir.IsDiagonal() ); + SHAPE_LINE_CHAIN bypass = dir.BuildInitialTrace( vs, aCoupled.CPoint(j), + dir.IsDiagonal() ); int64_t coupledLength = aPair->CoupledLength( aRef, bypass ); @@ -1202,7 +1162,8 @@ bool coupledBypass( NODE* aNode, DIFF_PAIR* aPair, bool aRefIsP, const SHAPE_LIN else newCoupled.Replace( ei, si, bypass.Reverse() ); - if(coupledLength > bestLength && verifyDpBypass( aNode, aPair, aRefIsP, aRef, newCoupled) ) + if( coupledLength > bestLength && verifyDpBypass( aNode, aPair, aRefIsP, aRef, + newCoupled) ) { bestBypass = newCoupled; bestLength = coupledLength; @@ -1260,7 +1221,7 @@ bool OPTIMIZER::mergeDpStep( DIFF_PAIR* aPair, bool aTryP, int step ) deltaUni = aPair->CoupledLength ( newRef, coupledPath ) - clenPre + budget; - if ( coupledBypass( m_world, aPair, aTryP, newRef, bypass, coupledPath, newCoup ) ) + if( coupledBypass( m_world, aPair, aTryP, newRef, bypass, coupledPath, newCoup ) ) { deltaCoupled = aPair->CoupledLength( newRef, newCoup ) - clenPre + budget; @@ -1273,7 +1234,7 @@ bool OPTIMIZER::mergeDpStep( DIFF_PAIR* aPair, bool aTryP, int step ) return true; } } - else if( deltaUni >= 0 && verifyDpBypass ( m_world, aPair, aTryP, newRef, coupledPath ) ) + else if( deltaUni >= 0 && verifyDpBypass( m_world, aPair, aTryP, newRef, coupledPath ) ) { newRef.Simplify(); coupledPath.Simplify(); @@ -1336,6 +1297,7 @@ bool OPTIMIZER::Optimize( DIFF_PAIR* aPair ) return mergeDpSegments( aPair ); } + static int64_t shovedArea( const SHAPE_LINE_CHAIN& aOld, const SHAPE_LINE_CHAIN& aNew ) { int64_t area = 0; @@ -1347,16 +1309,18 @@ static int64_t shovedArea( const SHAPE_LINE_CHAIN& aOld, const SHAPE_LINE_CHAIN& { int i_next = (i + 1 == total ? 0 : i + 1); - const VECTOR2I &v0 = ( i < oc ? aOld.CPoint(i) : aNew.CPoint( nc - 1 - (i - oc) ) ); - const VECTOR2I &v1 = ( i_next < oc ? aOld.CPoint ( i_next ) : aNew.CPoint( nc - 1 - (i_next - oc) ) ); + const VECTOR2I &v0 = i < oc ? aOld.CPoint(i) + : aNew.CPoint( nc - 1 - (i - oc) ); + const VECTOR2I &v1 = i_next < oc ? aOld.CPoint ( i_next ) + : aNew.CPoint( nc - 1 - (i_next - oc) ); area += -(int64_t) v0.y * v1.x + (int64_t) v0.x * v1.y; } return std::abs(area / 2); } -bool tightenSegment( bool dir, NODE *aNode, const LINE& cur, - const SHAPE_LINE_CHAIN& in, SHAPE_LINE_CHAIN& out ) +bool tightenSegment( bool dir, NODE *aNode, const LINE& cur, const SHAPE_LINE_CHAIN& in, + SHAPE_LINE_CHAIN& out ) { SEG a = in.CSegment(0); SEG center = in.CSegment(1); @@ -1380,10 +1344,10 @@ bool tightenSegment( bool dir, NODE *aNode, const LINE& cur, return false; { - //auto rC = *a.IntersectLines( b ); - // dbg->AddSegment ( SEG( center.A, rC ), 1 ); - // dbg->AddSegment ( SEG( center.B, rC ), 2 ); /* + auto rC = *a.IntersectLines( b ); + dbg->AddSegment ( SEG( center.A, rC ), 1 ); + dbg->AddSegment ( SEG( center.B, rC ), 2 ); auto perp = dirCenter.Left().Left(); SEG sperp ( center.A, center.A + perp.ToVector() ); @@ -1399,15 +1363,14 @@ bool tightenSegment( bool dir, NODE *aNode, const LINE& cur, dbg->AddSegment ( SEG( vpc, vp ), 5 ); - guide = SEG ( vpc, vp );*/ - - + guide = SEG ( vpc, vp ); + */ } int da = a.Length(); int db = b.Length(); - if ( da < db ) + if( da < db ) guide = a; else guide = b; @@ -1419,9 +1382,9 @@ bool tightenSegment( bool dir, NODE *aNode, const LINE& cur, int current = step; SHAPE_LINE_CHAIN snew; - while (step > 1) + while( step > 1 ) { - LINE l ( cur ); + LINE l( cur ); snew.Clear(); snew.Append( a.A ); @@ -1432,14 +1395,13 @@ bool tightenSegment( bool dir, NODE *aNode, const LINE& cur, step /= 2; l.SetShape(snew); + if( aNode->CheckColliding(&l) ) - { current -= step; - } else if ( current + step >= initial ) { + else if ( current + step >= initial ) current = initial; - } else { + else current += step; - } //dbg->AddSegment ( SEG( center.A , a.LineProject( center.A + gr ) ), 3 ); @@ -1477,6 +1439,7 @@ void Tighten( NODE *aNode, const SHAPE_LINE_CHAIN& aOldLine, const LINE& aNewLin SHAPE_LINE_CHAIN l_in, l_out; l_in = current.Slice(i, i+3); + for( int dir = 0; dir < 1; dir++) { if( tightenSegment( dir ? true : false, aNode, aNewLine, l_in, l_out ) ) @@ -1487,15 +1450,12 @@ void Tighten( NODE *aNode, const SHAPE_LINE_CHAIN& aOldLine, const LINE& aNewLin auto prevArea = std::abs(shovedArea( aOldLine, current )); if( optArea < prevArea ) - { current = opt; - } + break; } - } } - } aOptimized = LINE(aNewLine, current); diff --git a/pcbnew/router/pns_optimizer.h b/pcbnew/router/pns_optimizer.h index df61e95c3e..9d3585ceaa 100644 --- a/pcbnew/router/pns_optimizer.h +++ b/pcbnew/router/pns_optimizer.h @@ -111,14 +111,14 @@ public: ~OPTIMIZER(); ///> a quick shortcut to optmize a line without creating and setting up an optimizer - static bool Optimize( LINE* aLine, int aEffortLevel, NODE* aWorld, const VECTOR2I aV = VECTOR2I(0, 0) ); + static bool Optimize( LINE* aLine, int aEffortLevel, NODE* aWorld, + const VECTOR2I aV = VECTOR2I(0, 0) ); bool Optimize( LINE* aLine, LINE* aResult = NULL ); bool Optimize( DIFF_PAIR* aPair ); void SetWorld( NODE* aNode ) { m_world = aNode; } - void CacheStaticItem( ITEM* aItem ); void CacheRemove( ITEM* aItem ); void ClearCache( bool aStaticOnly = false ); @@ -132,7 +132,6 @@ public: m_effortLevel = aEffort; } - void SetPreserveVertex( const VECTOR2I& aV ) { m_preservedVertex = aV; @@ -154,9 +153,6 @@ public: void ClearConstraints(); void AddConstraint ( OPT_CONSTRAINT *aConstraint ); - bool extractPadGrids( std::vector& aPadJoints ); - void BuildPadGrids(); - private: static const int MaxCachedItems = 256; @@ -173,7 +169,6 @@ private: bool mergeObtuse( LINE* aLine ); bool mergeFull( LINE* aLine ); bool mergeColinear( LINE* aLine ); - bool removeUglyCorners( LINE* aLine ); bool runSmartPads( LINE* aLine ); bool mergeStep( LINE* aLine, SHAPE_LINE_CHAIN& aCurrentLine, int step ); bool fanoutCleanup( LINE * aLine ); @@ -186,13 +181,12 @@ private: void cacheAdd( ITEM* aItem, bool aIsStatic ); void removeCachedSegments( LINE* aLine, int aStartVertex = 0, int aEndVertex = -1 ); - bool checkConstraints( int aVertex1, int aVertex2, LINE* aOriginLine, const SHAPE_LINE_CHAIN& aCurrentPath, const SHAPE_LINE_CHAIN& aReplacement ); - - + bool checkConstraints( int aVertex1, int aVertex2, LINE* aOriginLine, + const SHAPE_LINE_CHAIN& aCurrentPath, + const SHAPE_LINE_CHAIN& aReplacement ); BREAKOUT_LIST circleBreakouts( int aWidth, const SHAPE* aShape, bool aPermitDiagonal ) const; BREAKOUT_LIST rectBreakouts( int aWidth, const SHAPE* aShape, bool aPermitDiagonal ) const; - BREAKOUT_LIST ovalBreakouts( int aWidth, const SHAPE* aShape, bool aPermitDiagonal ) const; BREAKOUT_LIST customBreakouts( int aWidth, const ITEM* aItem, bool aPermitDiagonal ) const; BREAKOUT_LIST computeBreakouts( int aWidth, const ITEM* aItem, bool aPermitDiagonal ) const; @@ -200,20 +194,18 @@ private: ITEM* findPadOrVia( int aLayer, int aNet, const VECTOR2I& aP ) const; - SHAPE_INDEX_LIST m_cache; +private: + SHAPE_INDEX_LIST m_cache; + std::vector m_constraints; + std::unordered_map m_cacheTags; - std::vector m_constraints; - typedef std::unordered_map CachedItemTags; - CachedItemTags m_cacheTags; - NODE* m_world; - int m_collisionKindMask; - int m_effortLevel; - bool m_keepPostures; + NODE* m_world; + int m_collisionKindMask; + int m_effortLevel; - - VECTOR2I m_preservedVertex; + VECTOR2I m_preservedVertex; std::pair m_restrictedVertexRange; - BOX2I m_restrictArea; + BOX2I m_restrictArea; }; class OPT_CONSTRAINT @@ -221,87 +213,76 @@ class OPT_CONSTRAINT public: OPT_CONSTRAINT( NODE* aWorld ) : m_world( aWorld ) - { - m_priority = 0; - }; - - virtual ~OPT_CONSTRAINT() {}; - - virtual bool Check( int aVertex1, int aVertex2, const LINE* aOriginLine, const SHAPE_LINE_CHAIN& aCurrentPath, const SHAPE_LINE_CHAIN& aReplacement ) = 0; - - int GetPriority() const { - return m_priority; - } + m_priority = 0; + }; - void SetPriority( int aPriority ) + virtual ~OPT_CONSTRAINT() { - m_priority = aPriority; - } + }; + + virtual bool Check( int aVertex1, int aVertex2, const LINE* aOriginLine, + const SHAPE_LINE_CHAIN& aCurrentPath, + const SHAPE_LINE_CHAIN& aReplacement ) = 0; + + int GetPriority() const { return m_priority; } + void SetPriority( int aPriority ) { m_priority = aPriority; } protected: NODE* m_world; - int m_priority; + int m_priority; }; -class ANGLE_CONSTRAINT_45: public OPT_CONSTRAINT -{ -public: - ANGLE_CONSTRAINT_45( NODE* aWorld, int aEntryDirectionMask = -1, int aExitDirectionMask = -1 ) : - OPT_CONSTRAINT( aWorld ), - m_entryDirectionMask( aEntryDirectionMask ), - m_exitDirectionMask( aExitDirectionMask ) - { - - } - - virtual ~ANGLE_CONSTRAINT_45() {}; - - virtual bool Check( int aVertex1, int aVertex2, const LINE* aOriginLine, const SHAPE_LINE_CHAIN& aCurrentPath, const SHAPE_LINE_CHAIN& aReplacement ) override; - -private: - int m_entryDirectionMask; - int m_exitDirectionMask; -}; class AREA_CONSTRAINT : public OPT_CONSTRAINT { public: AREA_CONSTRAINT( NODE* aWorld, const BOX2I& aAllowedArea ) : OPT_CONSTRAINT( aWorld ), - m_allowedArea ( aAllowedArea ) {}; + m_allowedArea ( aAllowedArea ) + { + }; - virtual bool Check( int aVertex1, int aVertex2, const LINE* aOriginLine, const SHAPE_LINE_CHAIN& aCurrentPath, const SHAPE_LINE_CHAIN& aReplacement ) override; + bool Check( int aVertex1, int aVertex2, const LINE* aOriginLine, + const SHAPE_LINE_CHAIN& aCurrentPath, + const SHAPE_LINE_CHAIN& aReplacement ) override; private: BOX2I m_allowedArea; - }; + class KEEP_TOPOLOGY_CONSTRAINT: public OPT_CONSTRAINT { public: KEEP_TOPOLOGY_CONSTRAINT( NODE* aWorld ) : OPT_CONSTRAINT( aWorld ) - {}; + { + }; - virtual bool Check( int aVertex1, int aVertex2, const LINE* aOriginLine, const SHAPE_LINE_CHAIN& aCurrentPath, const SHAPE_LINE_CHAIN& aReplacement ) override; + bool Check( int aVertex1, int aVertex2, const LINE* aOriginLine, + const SHAPE_LINE_CHAIN& aCurrentPath, + const SHAPE_LINE_CHAIN& aReplacement ) override; }; + class PRESERVE_VERTEX_CONSTRAINT: public OPT_CONSTRAINT { public: PRESERVE_VERTEX_CONSTRAINT( NODE* aWorld, const VECTOR2I& aV ) : OPT_CONSTRAINT( aWorld ), m_v( aV ) - {}; + { + }; - virtual bool Check( int aVertex1, int aVertex2, const LINE* aOriginLine, const SHAPE_LINE_CHAIN& aCurrentPath, const SHAPE_LINE_CHAIN& aReplacement ) override; + bool Check( int aVertex1, int aVertex2, const LINE* aOriginLine, + const SHAPE_LINE_CHAIN& aCurrentPath, + const SHAPE_LINE_CHAIN& aReplacement ) override; private: - VECTOR2I m_v; }; + class RESTRICT_VERTEX_RANGE_CONSTRAINT: public OPT_CONSTRAINT { public: @@ -309,11 +290,13 @@ public: OPT_CONSTRAINT( aWorld ), m_start( aStart ), m_end( aEnd ) - {}; + { + }; - virtual bool Check( int aVertex1, int aVertex2, const LINE* aOriginLine, const SHAPE_LINE_CHAIN& aCurrentPath, const SHAPE_LINE_CHAIN& aReplacement ) override; + virtual bool Check( int aVertex1, int aVertex2, const LINE* aOriginLine, + const SHAPE_LINE_CHAIN& aCurrentPath, + const SHAPE_LINE_CHAIN& aReplacement ) override; private: - int m_start; int m_end; }; diff --git a/pcbnew/router/pns_solid.cpp b/pcbnew/router/pns_solid.cpp index 40f11924a2..e69148a9ea 100644 --- a/pcbnew/router/pns_solid.cpp +++ b/pcbnew/router/pns_solid.cpp @@ -34,7 +34,8 @@ namespace PNS { -static const SHAPE_LINE_CHAIN buildHullForPrimitiveShape( const SHAPE* aShape, int aClearance, int aWalkaroundThickness ) +static const SHAPE_LINE_CHAIN buildHullForPrimitiveShape( const SHAPE* aShape, int aClearance, + int aWalkaroundThickness ) { int cl = aClearance + ( aWalkaroundThickness + 1 )/ 2; @@ -43,15 +44,20 @@ static const SHAPE_LINE_CHAIN buildHullForPrimitiveShape( const SHAPE* aShape, i case SH_RECT: { const SHAPE_RECT* rect = static_cast( aShape ); - return OctagonalHull( rect->GetPosition(), rect->GetSize(), cl + 1, 0.2 * cl ); + return OctagonalHull( rect->GetPosition(), + rect->GetSize(), + cl + 1, + 0.2 * cl ); } case SH_CIRCLE: { const SHAPE_CIRCLE* circle = static_cast( aShape ); int r = circle->GetRadius(); - return OctagonalHull( circle->GetCenter() - VECTOR2I( r, r ), VECTOR2I( 2 * r, 2 * r ), - cl + 1, 0.52 * ( r + cl ) ); + return OctagonalHull( circle->GetCenter() - VECTOR2I( r, r ), + VECTOR2I( 2 * r, 2 * r ), + cl + 1, + 0.52 * ( r + cl ) ); } case SH_SEGMENT: @@ -91,12 +97,13 @@ const SHAPE_LINE_CHAIN SOLID::Hull( int aClearance, int aWalkaroundThickness, in if ( cmpnd->Shapes().size() == 1 ) { - return buildHullForPrimitiveShape( cmpnd->Shapes()[0], aClearance, aWalkaroundThickness ); + return buildHullForPrimitiveShape( cmpnd->Shapes()[0], aClearance, + aWalkaroundThickness ); } else { - // fixme - shouldn't happen but one day we should move TransformShapeWithClearanceToPolygon() - // to the Geometry Library + // fixme - shouldn't happen but one day we should move + // TransformShapeWithClearanceToPolygon() to the Geometry Library return SHAPE_LINE_CHAIN(); } } @@ -118,12 +125,13 @@ const SHAPE_LINE_CHAIN SOLID::HoleHull( int aClearance, int aWalkaroundThickness if ( cmpnd->Shapes().size() == 1 ) { - return buildHullForPrimitiveShape( cmpnd->Shapes()[0], aClearance, aWalkaroundThickness ); + return buildHullForPrimitiveShape( cmpnd->Shapes()[0], aClearance, + aWalkaroundThickness ); } else { - // fixme - shouldn't happen but one day we should move TransformShapeWithClearanceToPolygon() - // to the Geometry Library + // fixme - shouldn't happen but one day we should move + // TransformShapeWithClearanceToPolygon() to the Geometry Library return SHAPE_LINE_CHAIN(); } }