PNS: re-enable optimization of colinear segs in lines with arcs
This commit is contained in:
parent
8901e71fc8
commit
8619086cf2
|
@ -628,9 +628,10 @@ public:
|
|||
* Function Simplify()
|
||||
*
|
||||
* Simplifies the line chain by removing colinear adjacent segments and duplicate vertices.
|
||||
* @param aRemoveColinear controsl the removal of colinear adjacent segments
|
||||
* @return reference to self.
|
||||
*/
|
||||
SHAPE_LINE_CHAIN& Simplify();
|
||||
SHAPE_LINE_CHAIN& Simplify( bool aRemoveColinear = true );
|
||||
|
||||
/**
|
||||
* Converts an arc to only a point chain by removing the arc and references
|
||||
|
@ -747,7 +748,14 @@ public:
|
|||
|
||||
bool isArc( size_t aSegment ) const
|
||||
{
|
||||
return aSegment < m_shapes.size() && m_shapes[aSegment] != SHAPE_IS_PT;
|
||||
/**
|
||||
* A segment is part of an arc except in the special case of two arcs next to each other
|
||||
* but without a shared vertex. Here there is a segment between the end of the first arc
|
||||
* and the start of the second arc.
|
||||
*/
|
||||
return ( aSegment < m_shapes.size() - 1
|
||||
&& m_shapes[aSegment] != SHAPE_IS_PT
|
||||
&& m_shapes[aSegment] == m_shapes[aSegment + 1] );
|
||||
}
|
||||
|
||||
virtual const VECTOR2I GetPoint( int aIndex ) const override { return CPoint(aIndex); }
|
||||
|
|
|
@ -936,7 +936,7 @@ const OPT<SHAPE_LINE_CHAIN::INTERSECTION> SHAPE_LINE_CHAIN::SelfIntersecting() c
|
|||
}
|
||||
|
||||
|
||||
SHAPE_LINE_CHAIN& SHAPE_LINE_CHAIN::Simplify()
|
||||
SHAPE_LINE_CHAIN& SHAPE_LINE_CHAIN::Simplify( bool aRemoveColinear )
|
||||
{
|
||||
std::vector<VECTOR2I> pts_unique;
|
||||
std::vector<ssize_t> shapes_unique;
|
||||
|
@ -961,11 +961,25 @@ SHAPE_LINE_CHAIN& SHAPE_LINE_CHAIN::Simplify()
|
|||
{
|
||||
int j = i + 1;
|
||||
|
||||
while( j < np && m_points[i] == m_points[j] && m_shapes[i] == m_shapes[j] )
|
||||
// We can eliminate duplicate vertices as long as they are part of the same shape, OR if
|
||||
// one of them is part of a shape and one is not.
|
||||
while( j < np && m_points[i] == m_points[j] &&
|
||||
( m_shapes[i] == m_shapes[j] ||
|
||||
m_shapes[i] == SHAPE_IS_PT ||
|
||||
m_shapes[j] == SHAPE_IS_PT ) )
|
||||
{
|
||||
j++;
|
||||
}
|
||||
|
||||
int shapeToKeep = m_shapes[i];
|
||||
|
||||
if( shapeToKeep == SHAPE_IS_PT )
|
||||
shapeToKeep = m_shapes[j - 1];
|
||||
|
||||
wxASSERT( shapeToKeep < static_cast<int>( m_arcs.size() ) );
|
||||
|
||||
pts_unique.push_back( CPoint( i ) );
|
||||
shapes_unique.push_back( m_shapes[i] );
|
||||
shapes_unique.push_back( shapeToKeep );
|
||||
|
||||
i = j;
|
||||
}
|
||||
|
@ -976,17 +990,20 @@ SHAPE_LINE_CHAIN& SHAPE_LINE_CHAIN::Simplify()
|
|||
|
||||
i = 0;
|
||||
|
||||
// stage 1: eliminate collinear segments
|
||||
// stage 2: eliminate colinear segments
|
||||
while( i < np - 2 )
|
||||
{
|
||||
const VECTOR2I p0 = pts_unique[i];
|
||||
const VECTOR2I p1 = pts_unique[i + 1];
|
||||
int n = i;
|
||||
|
||||
while( n < np - 2
|
||||
&& ( SEG( p0, p1 ).LineDistance( pts_unique[n + 2] ) <= 1
|
||||
|| SEG( p0, p1 ).Collinear( SEG( p1, pts_unique[n + 2] ) ) ) )
|
||||
n++;
|
||||
if( aRemoveColinear )
|
||||
{
|
||||
while( n < np - 2
|
||||
&& ( SEG( p0, p1 ).LineDistance( pts_unique[n + 2] ) <= 1
|
||||
|| SEG( p0, p1 ).Collinear( SEG( p1, pts_unique[n + 2] ) ) ) )
|
||||
n++;
|
||||
}
|
||||
|
||||
m_points.push_back( p0 );
|
||||
m_shapes.push_back( shapes_unique[i] );
|
||||
|
|
|
@ -1111,9 +1111,10 @@ bool LINE_PLACER::FixRoute( const VECTOR2I& aP, ITEM* aEndItem, bool aForceFinis
|
|||
else
|
||||
lastV = std::max( 1, l.SegmentCount() - 1 );
|
||||
|
||||
SEGMENT seg;
|
||||
SEGMENT* lastSeg = nullptr;
|
||||
int lastArc = -1;
|
||||
ARC arc;
|
||||
SEGMENT seg;
|
||||
LINKED_ITEM* lastItem = nullptr;
|
||||
int lastArc = -1;
|
||||
|
||||
for( int i = 0; i < lastV; i++ )
|
||||
{
|
||||
|
@ -1126,27 +1127,28 @@ bool LINE_PLACER::FixRoute( const VECTOR2I& aP, ITEM* aEndItem, bool aForceFinis
|
|||
seg.SetLayer( m_currentLayer );
|
||||
|
||||
if( m_lastNode->Add( std::make_unique<SEGMENT>( seg ) ) )
|
||||
lastSeg = &seg;
|
||||
lastItem = &seg;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( arcIndex == lastArc )
|
||||
continue;
|
||||
|
||||
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 ) );
|
||||
lastSeg = nullptr;
|
||||
lastArc = arcIndex;
|
||||
arc = ARC( l.Arc( arcIndex ), m_currentNet );
|
||||
arc.SetWidth( pl.Width() );
|
||||
arc.SetLayer( m_currentLayer );
|
||||
|
||||
m_lastNode->Add( std::make_unique<ARC>( arc ) );
|
||||
lastItem = &arc;
|
||||
lastArc = arcIndex;
|
||||
}
|
||||
}
|
||||
|
||||
if( pl.EndsWithVia() )
|
||||
m_lastNode->Add( Clone( pl.Via() ) );
|
||||
|
||||
if( realEnd && lastSeg )
|
||||
simplifyNewLine( m_lastNode, lastSeg );
|
||||
if( realEnd && lastItem )
|
||||
simplifyNewLine( m_lastNode, lastItem );
|
||||
|
||||
if( !realEnd )
|
||||
{
|
||||
|
@ -1297,8 +1299,9 @@ void LINE_PLACER::removeLoops( NODE* aNode, LINE& aLatest )
|
|||
}
|
||||
|
||||
|
||||
void LINE_PLACER::simplifyNewLine( NODE* aNode, SEGMENT* aLatest )
|
||||
void LINE_PLACER::simplifyNewLine( NODE* aNode, LINKED_ITEM* aLatest )
|
||||
{
|
||||
wxASSERT( aLatest->OfKind( ITEM::SEGMENT_T | ITEM::ARC_T ) );
|
||||
LINE l = aNode->AssembleLine( aLatest );
|
||||
|
||||
bool optimized = OPTIMIZER::Optimize( &l, OPTIMIZER::MERGE_COLINEAR, aNode );
|
||||
|
|
|
@ -320,13 +320,11 @@ private:
|
|||
void removeLoops( NODE* aNode, LINE& aLatest );
|
||||
|
||||
/**
|
||||
* Function simplifyNewLine()
|
||||
*
|
||||
* Assembles a line starting from segment aLatest, removes collinear segments
|
||||
* Assembles a line starting from segment or arc aLatest, removes collinear segments
|
||||
* and redundant vertexes. If a simplification bhas been found, replaces the
|
||||
* old line with the simplified one in aNode.
|
||||
*/
|
||||
void simplifyNewLine( NODE* aNode, SEGMENT* aLatest );
|
||||
void simplifyNewLine( NODE* aNode, LINKED_ITEM* aLatest );
|
||||
|
||||
/**
|
||||
* Function handleSelfIntersections()
|
||||
|
|
|
@ -958,7 +958,8 @@ const LINE NODE::AssembleLine( LINKED_ITEM* aSeg, int* aOriginSegmentIndex,
|
|||
prev_seg = li;
|
||||
}
|
||||
|
||||
pl.Line().Simplify();
|
||||
// Remove duplicate verts, but do NOT remove colinear segments here!
|
||||
pl.Line().Simplify( false );
|
||||
|
||||
assert( pl.SegmentCount() != 0 );
|
||||
|
||||
|
|
Loading…
Reference in New Issue