router: introduce concept of a root lines in the OPTIMIZER.
By 'root lines' we mean the oldest traceable ancestor of each track moved by the router (i.e. after shoving for a while, the root of each shoved line is it's latest non-shoved version). With this we can teach the OPTIMIZER more tricks, such as the LIMIT_CORNER_COUNT constraint. It ensures the results of the optimization will not be less cornery than the original line, reducing the feeling of the optimizer being too intrusive.
This commit is contained in:
parent
76f8861e6e
commit
3a8744d054
|
@ -272,6 +272,21 @@ bool RESTRICT_VERTEX_RANGE_CONSTRAINT::Check( int aVertex1, int aVertex2, const
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CORNER_COUNT_LIMIT_CONSTRAINT::Check( int aVertex1, int aVertex2, const LINE* aOriginLine,
|
||||
const SHAPE_LINE_CHAIN& aCurrentPath,
|
||||
const SHAPE_LINE_CHAIN& aReplacement )
|
||||
{
|
||||
LINE newPath( *aOriginLine, aCurrentPath );
|
||||
newPath.Line().Replace( aVertex1, aVertex2, aReplacement );
|
||||
int cc = newPath.CountCorners( m_angleMask );
|
||||
if( cc >= m_minCorners && cc <= m_maxCorners )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Determine if a point is located within a given polygon
|
||||
*
|
||||
|
@ -587,8 +602,16 @@ bool OPTIMIZER::mergeColinear( LINE* aLine )
|
|||
}
|
||||
|
||||
|
||||
bool OPTIMIZER::Optimize( LINE* aLine, LINE* aResult )
|
||||
bool OPTIMIZER::Optimize( LINE* aLine, LINE* aResult, LINE* aRoot )
|
||||
{
|
||||
g_dbg = ROUTER::GetInstance()->GetInterface()->GetDebugDecorator();
|
||||
|
||||
if( aRoot )
|
||||
{
|
||||
g_dbg->AddLine( aRoot->CLine(), 3, 100000 );
|
||||
}
|
||||
|
||||
|
||||
if( !aResult )
|
||||
{
|
||||
aResult = aLine;
|
||||
|
@ -602,6 +625,14 @@ bool OPTIMIZER::Optimize( LINE* aLine, LINE* aResult )
|
|||
bool hasArcs = aLine->ArcCount();
|
||||
bool rv = false;
|
||||
|
||||
if( (m_effortLevel & LIMIT_CORNER_COUNT) && aRoot )
|
||||
{
|
||||
const int angleMask = DIRECTION_45::ANG_OBTUSE;
|
||||
int rootObtuseCorners = aRoot->CountCorners( angleMask );
|
||||
auto c = new CORNER_COUNT_LIMIT_CONSTRAINT( m_world, rootObtuseCorners, aLine->SegmentCount(), angleMask );
|
||||
AddConstraint( c );
|
||||
}
|
||||
|
||||
if( m_effortLevel & PRESERVE_VERTEX )
|
||||
{
|
||||
auto c = new PRESERVE_VERTEX_CONSTRAINT( m_world, m_preservedVertex );
|
||||
|
|
|
@ -104,7 +104,9 @@ public:
|
|||
PRESERVE_VERTEX = 0x20,
|
||||
RESTRICT_VERTEX_RANGE = 0x40,
|
||||
MERGE_COLINEAR = 0x80, ///< Merge co-linear segments
|
||||
RESTRICT_AREA = 0x100
|
||||
RESTRICT_AREA = 0x100,
|
||||
LIMIT_CORNER_COUNT = 0x200 ///< Do not attempt to optimize if the resulting line's
|
||||
///< corner count is outside the predefined range
|
||||
};
|
||||
|
||||
OPTIMIZER( NODE* aWorld );
|
||||
|
@ -114,7 +116,7 @@ public:
|
|||
static bool Optimize( LINE* aLine, int aEffortLevel, NODE* aWorld,
|
||||
const VECTOR2I aV = VECTOR2I(0, 0) );
|
||||
|
||||
bool Optimize( LINE* aLine, LINE* aResult = NULL );
|
||||
bool Optimize( LINE* aLine, LINE* aResult = nullptr, LINE* aRoot = nullptr );
|
||||
bool Optimize( DIFF_PAIR* aPair );
|
||||
|
||||
|
||||
|
@ -326,6 +328,29 @@ private:
|
|||
};
|
||||
|
||||
|
||||
class CORNER_COUNT_LIMIT_CONSTRAINT: public OPT_CONSTRAINT
|
||||
{
|
||||
public:
|
||||
CORNER_COUNT_LIMIT_CONSTRAINT( NODE* aWorld, int aMinCorners, int aMaxCorners, int aAngleMask ) :
|
||||
OPT_CONSTRAINT( aWorld ),
|
||||
m_minCorners( aMinCorners ),
|
||||
m_maxCorners( aMaxCorners ),
|
||||
m_angleMask( aAngleMask )
|
||||
{
|
||||
};
|
||||
|
||||
virtual bool Check( int aVertex1, int aVertex2, const LINE* aOriginLine,
|
||||
const SHAPE_LINE_CHAIN& aCurrentPath,
|
||||
const SHAPE_LINE_CHAIN& aReplacement ) override;
|
||||
|
||||
private:
|
||||
int m_minCorners;
|
||||
int m_maxCorners;
|
||||
int m_angleMask;
|
||||
};
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // __PNS_OPTIMIZER_H
|
||||
|
|
Loading…
Reference in New Issue