Re-add routine to remove duplicate points

The router needs to elimitate duplicate points but keep colinear
segments.  This re-creates the partial routine from the old Simplify()
function

Fixes https://gitlab.com/kicad/code/kicad/-/issues/17582

(cherry picked from commit 59f99d9a6a)
This commit is contained in:
Seth Hillbrand 2024-04-09 13:15:19 -07:00 committed by Alex Shvartzkop
parent 7dc8527022
commit e808ab7409
3 changed files with 68 additions and 1 deletions

View File

@ -298,6 +298,11 @@ public:
int ShapeCount() const; int ShapeCount() const;
/**
* Remove the duplicate points from the line chain.
*/
void RemoveDuplicatePoints();
/** /**
* Simplify the line chain by removing colinear adjacent segments and duplicate vertices. * Simplify the line chain by removing colinear adjacent segments and duplicate vertices.
* *

View File

@ -2087,6 +2087,68 @@ double SHAPE_LINE_CHAIN::Area( bool aAbsolute ) const
} }
void SHAPE_LINE_CHAIN::RemoveDuplicatePoints()
{
std::vector<VECTOR2I> pts_unique;
std::vector<std::pair<ssize_t, ssize_t>> shapes_unique;
// Always try to keep at least 2 points otherwise, we're not really a line
if( PointCount() < 3 )
{
return;
}
else if( PointCount() == 3 )
{
if( m_points[0] == m_points[1] )
Remove( 1 );
return;
}
int i = 0;
while( i < PointCount() )
{
int j = i + 1;
// 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 < PointCount() && m_points[i] == m_points[j] &&
( m_shapes[i] == m_shapes[j] ||
m_shapes[i] == SHAPES_ARE_PT ||
m_shapes[j] == SHAPES_ARE_PT ) )
{
j++;
}
std::pair<ssize_t,ssize_t> shapeToKeep = m_shapes[i];
if( shapeToKeep == SHAPES_ARE_PT )
shapeToKeep = m_shapes[j - 1];
assert( shapeToKeep.first < static_cast<int>( m_arcs.size() ) );
assert( shapeToKeep.second < static_cast<int>( m_arcs.size() ) );
pts_unique.push_back( CPoint( i ) );
shapes_unique.push_back( shapeToKeep );
i = j;
}
m_points.clear();
m_shapes.clear();
for( size_t ii = 0; ii < pts_unique.size(); ++ii )
{
const VECTOR2I p0 = pts_unique[ii];
m_points.push_back( p0 );
m_shapes.push_back( shapes_unique[ii] );
}
}
void SHAPE_LINE_CHAIN::Simplify( int aMaxError ) void SHAPE_LINE_CHAIN::Simplify( int aMaxError )
{ {
if( PointCount() < 3 ) if( PointCount() < 3 )

View File

@ -1085,7 +1085,7 @@ const LINE NODE::AssembleLine( LINKED_ITEM* aSeg, int* aOriginSegmentIndex,
} }
// Remove duplicate verts, but do NOT remove colinear segments here! // Remove duplicate verts, but do NOT remove colinear segments here!
pl.Line().Simplify( false ); pl.Line().RemoveDuplicatePoints();
// TODO: maintain actual segment index under simplification system // TODO: maintain actual segment index under simplification system
if( aOriginSegmentIndex && *aOriginSegmentIndex >= pl.SegmentCount() ) if( aOriginSegmentIndex && *aOriginSegmentIndex >= pl.SegmentCount() )