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()
|
* Function Simplify()
|
||||||
*
|
*
|
||||||
* Simplifies the line chain by removing colinear adjacent segments and duplicate vertices.
|
* 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.
|
* @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
|
* 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
|
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); }
|
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<VECTOR2I> pts_unique;
|
||||||
std::vector<ssize_t> shapes_unique;
|
std::vector<ssize_t> shapes_unique;
|
||||||
|
@ -961,11 +961,25 @@ SHAPE_LINE_CHAIN& SHAPE_LINE_CHAIN::Simplify()
|
||||||
{
|
{
|
||||||
int j = i + 1;
|
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++;
|
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 ) );
|
pts_unique.push_back( CPoint( i ) );
|
||||||
shapes_unique.push_back( m_shapes[i] );
|
shapes_unique.push_back( shapeToKeep );
|
||||||
|
|
||||||
i = j;
|
i = j;
|
||||||
}
|
}
|
||||||
|
@ -976,17 +990,20 @@ SHAPE_LINE_CHAIN& SHAPE_LINE_CHAIN::Simplify()
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
|
|
||||||
// stage 1: eliminate collinear segments
|
// stage 2: eliminate colinear segments
|
||||||
while( i < np - 2 )
|
while( i < np - 2 )
|
||||||
{
|
{
|
||||||
const VECTOR2I p0 = pts_unique[i];
|
const VECTOR2I p0 = pts_unique[i];
|
||||||
const VECTOR2I p1 = pts_unique[i + 1];
|
const VECTOR2I p1 = pts_unique[i + 1];
|
||||||
int n = i;
|
int n = i;
|
||||||
|
|
||||||
while( n < np - 2
|
if( aRemoveColinear )
|
||||||
&& ( SEG( p0, p1 ).LineDistance( pts_unique[n + 2] ) <= 1
|
{
|
||||||
|| SEG( p0, p1 ).Collinear( SEG( p1, pts_unique[n + 2] ) ) ) )
|
while( n < np - 2
|
||||||
n++;
|
&& ( 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_points.push_back( p0 );
|
||||||
m_shapes.push_back( shapes_unique[i] );
|
m_shapes.push_back( shapes_unique[i] );
|
||||||
|
|
|
@ -1111,9 +1111,10 @@ bool LINE_PLACER::FixRoute( const VECTOR2I& aP, ITEM* aEndItem, bool aForceFinis
|
||||||
else
|
else
|
||||||
lastV = std::max( 1, l.SegmentCount() - 1 );
|
lastV = std::max( 1, l.SegmentCount() - 1 );
|
||||||
|
|
||||||
SEGMENT seg;
|
ARC arc;
|
||||||
SEGMENT* lastSeg = nullptr;
|
SEGMENT seg;
|
||||||
int lastArc = -1;
|
LINKED_ITEM* lastItem = nullptr;
|
||||||
|
int lastArc = -1;
|
||||||
|
|
||||||
for( int i = 0; i < lastV; i++ )
|
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 );
|
seg.SetLayer( m_currentLayer );
|
||||||
|
|
||||||
if( m_lastNode->Add( std::make_unique<SEGMENT>( seg ) ) )
|
if( m_lastNode->Add( std::make_unique<SEGMENT>( seg ) ) )
|
||||||
lastSeg = &seg;
|
lastItem = &seg;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if( arcIndex == lastArc )
|
if( arcIndex == lastArc )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
std::unique_ptr<ARC> arc = std::make_unique<ARC>( l.Arc( arcIndex ), m_currentNet );
|
arc = ARC( l.Arc( arcIndex ), m_currentNet );
|
||||||
arc->SetWidth( pl.Width() );
|
arc.SetWidth( pl.Width() );
|
||||||
arc->SetLayer( m_currentLayer );
|
arc.SetLayer( m_currentLayer );
|
||||||
m_lastNode->Add( std::move( arc ) );
|
|
||||||
lastSeg = nullptr;
|
m_lastNode->Add( std::make_unique<ARC>( arc ) );
|
||||||
lastArc = arcIndex;
|
lastItem = &arc;
|
||||||
|
lastArc = arcIndex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( pl.EndsWithVia() )
|
if( pl.EndsWithVia() )
|
||||||
m_lastNode->Add( Clone( pl.Via() ) );
|
m_lastNode->Add( Clone( pl.Via() ) );
|
||||||
|
|
||||||
if( realEnd && lastSeg )
|
if( realEnd && lastItem )
|
||||||
simplifyNewLine( m_lastNode, lastSeg );
|
simplifyNewLine( m_lastNode, lastItem );
|
||||||
|
|
||||||
if( !realEnd )
|
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 );
|
LINE l = aNode->AssembleLine( aLatest );
|
||||||
|
|
||||||
bool optimized = OPTIMIZER::Optimize( &l, OPTIMIZER::MERGE_COLINEAR, aNode );
|
bool optimized = OPTIMIZER::Optimize( &l, OPTIMIZER::MERGE_COLINEAR, aNode );
|
||||||
|
|
|
@ -320,13 +320,11 @@ private:
|
||||||
void removeLoops( NODE* aNode, LINE& aLatest );
|
void removeLoops( NODE* aNode, LINE& aLatest );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function simplifyNewLine()
|
* Assembles a line starting from segment or arc aLatest, removes collinear segments
|
||||||
*
|
|
||||||
* Assembles a line starting from segment aLatest, removes collinear segments
|
|
||||||
* and redundant vertexes. If a simplification bhas been found, replaces the
|
* and redundant vertexes. If a simplification bhas been found, replaces the
|
||||||
* old line with the simplified one in aNode.
|
* old line with the simplified one in aNode.
|
||||||
*/
|
*/
|
||||||
void simplifyNewLine( NODE* aNode, SEGMENT* aLatest );
|
void simplifyNewLine( NODE* aNode, LINKED_ITEM* aLatest );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function handleSelfIntersections()
|
* Function handleSelfIntersections()
|
||||||
|
|
|
@ -958,7 +958,8 @@ const LINE NODE::AssembleLine( LINKED_ITEM* aSeg, int* aOriginSegmentIndex,
|
||||||
prev_seg = li;
|
prev_seg = li;
|
||||||
}
|
}
|
||||||
|
|
||||||
pl.Line().Simplify();
|
// Remove duplicate verts, but do NOT remove colinear segments here!
|
||||||
|
pl.Line().Simplify( false );
|
||||||
|
|
||||||
assert( pl.SegmentCount() != 0 );
|
assert( pl.SegmentCount() != 0 );
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue