PNS: Fix yet more arc edge cases

Fixes https://gitlab.com/kicad/code/kicad/-/issues/8150
This commit is contained in:
Jon Evans 2021-04-12 19:46:34 -04:00
parent dec5734ff2
commit 715c61ac9f
2 changed files with 34 additions and 6 deletions

View File

@ -318,21 +318,26 @@ void SHAPE_LINE_CHAIN::Replace( int aStartIndex, int aEndIndex, const SHAPE_LINE
if( startShape >= 0 )
{
wxASSERT( newLine.m_points.front() == m_points[aStartIndex] &&
aStartIndex < m_points.size() - 1 );
wxASSERT( !newLine.PointCount() ||
( newLine.m_points.front() == m_points[aStartIndex] &&
aStartIndex < m_points.size() - 1 ) );
aStartIndex++;
newLine.Remove( 0 );
}
if( endShape >= 0 )
{
wxASSERT( newLine.m_points.back() == m_points[aEndIndex] && aEndIndex > 0 );
wxASSERT( !newLine.PointCount() ||
( newLine.m_points.back() == m_points[aEndIndex] && aEndIndex > 0 ) );
aEndIndex--;
newLine.Remove( -1 );
}
Remove( aStartIndex, aEndIndex );
if( !aLine.PointCount() )
return;
// The total new arcs index is added to the new arc indices
size_t prev_arc_count = m_arcs.size();
std::vector<ssize_t> new_shapes = newLine.m_shapes;

View File

@ -574,6 +574,10 @@ void LINE::dragCorner45( const VECTOR2I& aP, int aIndex )
path = dragCornerInternal( m_line, snapped );
else
{
// Are we next to an arc? Insert a new point so we slice correctly
if( m_line.CShapes()[aIndex + 1] >= 0 )
m_line.Insert( aIndex + 1, m_line.CPoint( aIndex + 1 ) );
// fixme: awkward behaviour for "outwards" drags
path = dragCornerInternal( m_line.Slice( 0, aIndex ), snapped );
SHAPE_LINE_CHAIN path_rev =
@ -594,7 +598,7 @@ void LINE::dragCornerFree( const VECTOR2I& aP, int aIndex )
{
if( aIndex > 0 && shapes[aIndex - 1] == -1 )
m_line.Insert( aIndex, m_line.GetPoint( aIndex ) );
else if( aIndex < shapes.size() - 1 && shapes[aIndex + 1] == -1 )
else if( aIndex < shapes.size() - 1 && shapes[aIndex + 1] != shapes[aIndex] )
{
aIndex++;
m_line.Insert( aIndex, m_line.GetPoint( aIndex ) );
@ -730,9 +734,16 @@ void LINE::dragSegment45( const VECTOR2I& aP, int aIndex )
target = snapToNeighbourSegments( path, aP, aIndex );
if( index == 0 )
const std::vector<ssize_t>& shapes = path.CShapes();
// We require a valid s_prev and s_next. If we are at the start or end of the line, we insert
// a new point at the start or end so there is a zero-length segment for prev or next (we will
// resize it as part of the drag operation). If we are next to an arc, we do this also, as we
// cannot drag away one of the arc's points.
if( index == 0 || shapes[index] >= 0 )
{
path.Insert( 0, path.CPoint( 0 ) );
path.Insert( index > 0 ? index + 1 : 0, path.CPoint( index ) );
index++;
}
@ -740,6 +751,10 @@ void LINE::dragSegment45( const VECTOR2I& aP, int aIndex )
{
path.Insert( path.PointCount() - 1, path.CPoint( -1 ) );
}
else if( shapes[index + 1] >= 0 )
{
path.Insert( index + 1, path.CPoint( index + 1 ) );
}
SEG dragged = path.CSegment( index );
DIRECTION_45 drag_dir( dragged );
@ -756,12 +771,20 @@ void LINE::dragSegment45( const VECTOR2I& aP, int aIndex )
path.Insert( index, path.CPoint( index ) );
index++;
}
else if( dir_prev == DIRECTION_45::UNDEFINED )
{
dir_prev = drag_dir.Left();
}
if( dir_next == drag_dir )
{
dir_next = dir_next.Right();
path.Insert( index + 1, path.CPoint( index + 1 ) );
}
else if( dir_next == DIRECTION_45::UNDEFINED )
{
dir_next = drag_dir.Right();
}
s_prev = path.CSegment( index - 1 );
s_next = path.CSegment( index + 1 );