Cleanup (and a minor performance improvement).
This commit is contained in:
parent
597a74af9a
commit
d24b034cbc
|
@ -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<ARC>( l.Arc( arcIndex ), m_currentNet );
|
||||
std::unique_ptr<ARC> arc = std::make_unique<ARC>( 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();
|
||||
|
|
|
@ -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) ) ) )
|
||||
if( (ipNext.x ==aP.x) || ( ip.y == aP.y && ( (ipNext.x >aP.x) == (ip.x <aP.x) ) ) )
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if( (ip.y <aP.y) != (ipNext.y <aP.y) )
|
||||
{
|
||||
|
@ -391,15 +334,17 @@ static bool pointInside2( const SHAPE_LINE_CHAIN& aL, const VECTOR2I& aP )
|
|||
}
|
||||
|
||||
|
||||
bool KEEP_TOPOLOGY_CONSTRAINT::Check( int aVertex1, int aVertex2, const LINE* aOriginLine, const SHAPE_LINE_CHAIN& aCurrentPath, const SHAPE_LINE_CHAIN& aReplacement )
|
||||
{
|
||||
bool KEEP_TOPOLOGY_CONSTRAINT::Check( int aVertex1, int aVertex2, const LINE* aOriginLine,
|
||||
const SHAPE_LINE_CHAIN& aCurrentPath,
|
||||
const SHAPE_LINE_CHAIN& aReplacement )
|
||||
{
|
||||
SHAPE_LINE_CHAIN encPoly = aOriginLine->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<JOINT*> 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<bool>( 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<const SHAPE_CIRCLE*>( 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<const SHAPE_SIMPLE*>( 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<const SHAPE_RECT*>(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);
|
||||
|
|
|
@ -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<JOINT*>& 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<ITEM*> m_cache;
|
||||
private:
|
||||
SHAPE_INDEX_LIST<ITEM*> m_cache;
|
||||
std::vector<OPT_CONSTRAINT*> m_constraints;
|
||||
std::unordered_map<ITEM*, CACHED_ITEM> m_cacheTags;
|
||||
|
||||
std::vector<OPT_CONSTRAINT*> m_constraints;
|
||||
typedef std::unordered_map<ITEM*, CACHED_ITEM> 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<int, int> 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;
|
||||
};
|
||||
|
|
|
@ -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<const SHAPE_RECT*>( 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<const SHAPE_CIRCLE*>( 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();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue