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:
parent
7dc8527022
commit
e808ab7409
|
@ -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.
|
||||||
*
|
*
|
||||||
|
|
|
@ -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 )
|
||||||
|
|
|
@ -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() )
|
||||||
|
|
Loading…
Reference in New Issue