pcbnew: Commit polygon points to new constrained zone

Adds leader points if they are not already existing in the zone

Fixes: lp:1846028
* https://bugs.launchpad.net/kicad/+bug/1846028
This commit is contained in:
Seth Hillbrand 2019-10-20 09:27:44 -07:00
parent 70c64d93e4
commit 2e1af66a2b
5 changed files with 32 additions and 12 deletions

View File

@ -97,9 +97,9 @@ bool POLYGON_GEOM_MANAGER::IsSelfIntersecting( bool aIncludeLeaderPts ) const
} }
void POLYGON_GEOM_MANAGER::SetCursorPosition( const VECTOR2I& aPos, LEADER_MODE aModifier ) void POLYGON_GEOM_MANAGER::SetCursorPosition( const VECTOR2I& aPos )
{ {
updateLeaderPoints( aPos, aModifier ); updateLeaderPoints( aPos );
} }
@ -181,7 +181,13 @@ void POLYGON_GEOM_MANAGER::updateLeaderPoints( const VECTOR2I& aEndPoint, LEADER
m_leaderPts = SHAPE_LINE_CHAIN( lastPt, newEnd ); m_leaderPts = SHAPE_LINE_CHAIN( lastPt, newEnd );
if( pt ) if( pt )
m_leaderPts.Append( *pt ); {
// This checks for backtracking from the point to intersection
if( SEG( lastPt, newEnd ).Collinear( SEG( newEnd, *pt ) ) )
m_leaderPts = SHAPE_LINE_CHAIN( lastPt, *pt );
else
m_leaderPts.Append( *pt );
}
} }
else else
{ {

View File

@ -128,7 +128,7 @@ public:
/** /**
* Set the current cursor position * Set the current cursor position
*/ */
void SetCursorPosition( const VECTOR2I& aPos, LEADER_MODE aModifier ); void SetCursorPosition( const VECTOR2I& aPos );
/** /**
* @return true if the polygon in "in progress", i.e. it has at least * @return true if the polygon in "in progress", i.e. it has at least

View File

@ -1420,6 +1420,7 @@ int DRAWING_TOOL::DrawZone( const TOOL_EVENT& aEvent )
// the geometry manager which handles the zone geometry, and // the geometry manager which handles the zone geometry, and
// hands the calculated points over to the zone creator tool // hands the calculated points over to the zone creator tool
POLYGON_GEOM_MANAGER polyGeomMgr( zoneTool ); POLYGON_GEOM_MANAGER polyGeomMgr( zoneTool );
bool constrainAngle = false;
std::string tool = aEvent.GetCommandStr().get(); std::string tool = aEvent.GetCommandStr().get();
m_frame->PushTool( tool ); m_frame->PushTool( tool );
@ -1450,6 +1451,11 @@ int DRAWING_TOOL::DrawZone( const TOOL_EVENT& aEvent )
evt->IsPrime() ? evt->Position() : m_controls->GetMousePosition(), layers ); evt->IsPrime() ? evt->Position() : m_controls->GetMousePosition(), layers );
m_controls->ForceCursorPosition( true, cursorPos ); m_controls->ForceCursorPosition( true, cursorPos );
if( ( sourceZone && sourceZone->GetHV45() ) || constrainAngle || evt->Modifier( MD_CTRL ) )
polyGeomMgr.SetLeaderMode( POLYGON_GEOM_MANAGER::LEADER_MODE::DEG45 );
else
polyGeomMgr.SetLeaderMode( POLYGON_GEOM_MANAGER::LEADER_MODE::DIRECT );
auto cleanup = [&] () { auto cleanup = [&] () {
polyGeomMgr.Reset(); polyGeomMgr.Reset();
started = false; started = false;
@ -1524,6 +1530,8 @@ int DRAWING_TOOL::DrawZone( const TOOL_EVENT& aEvent )
if( !started ) if( !started )
{ {
started = true; started = true;
constrainAngle = ( polyGeomMgr.GetLeaderMode() ==
POLYGON_GEOM_MANAGER::LEADER_MODE::DEG45 );
m_controls->SetAutoPan( true ); m_controls->SetAutoPan( true );
m_controls->CaptureCursor( true ); m_controls->CaptureCursor( true );
} }
@ -1547,9 +1555,7 @@ int DRAWING_TOOL::DrawZone( const TOOL_EVENT& aEvent )
else if( polyGeomMgr.IsPolygonInProgress() else if( polyGeomMgr.IsPolygonInProgress()
&& ( evt->IsMotion() || evt->IsDrag( BUT_LEFT ) ) ) && ( evt->IsMotion() || evt->IsDrag( BUT_LEFT ) ) )
{ {
polyGeomMgr.SetCursorPosition( cursorPos, evt->Modifier( MD_CTRL ) polyGeomMgr.SetCursorPosition( cursorPos );
? POLYGON_GEOM_MANAGER::LEADER_MODE::DEG45
: POLYGON_GEOM_MANAGER::LEADER_MODE::DIRECT );
if( polyGeomMgr.IsSelfIntersecting( true ) ) if( polyGeomMgr.IsSelfIntersecting( true ) )
{ {

View File

@ -60,6 +60,7 @@ std::unique_ptr<ZONE_CONTAINER> ZONE_CREATE_HELPER::createNewZone( bool aKeepout
zoneInfo.m_CurrentZone_Layer = m_params.m_layer; zoneInfo.m_CurrentZone_Layer = m_params.m_layer;
zoneInfo.m_NetcodeSelection = board.GetHighLightNetCode(); zoneInfo.m_NetcodeSelection = board.GetHighLightNetCode();
zoneInfo.SetIsKeepout( m_params.m_keepout ); zoneInfo.SetIsKeepout( m_params.m_keepout );
zoneInfo.m_Zone_45_Only = ( m_params.m_leaderMode == POLYGON_GEOM_MANAGER::LEADER_MODE::DEG45 );
if( m_params.m_mode != ZONE_MODE::GRAPHIC_POLYGON ) if( m_params.m_mode != ZONE_MODE::GRAPHIC_POLYGON )
{ {
@ -285,13 +286,17 @@ void ZONE_CREATE_HELPER::OnComplete( const POLYGON_GEOM_MANAGER& aMgr )
{ {
auto pts = aMgr.GetLeaderLinePoints(); auto pts = aMgr.GetLeaderLinePoints();
if( outline->TotalVertices() > 0 )
outline->RemoveVertex( outline->TotalVertices() - 1 );
// The first 2 points of the leader are the continuation of the previous segment // The first 2 points of the leader are the continuation of the previous segment
// The third point is where it intersects with the extension from the 0-th segment // The third point is where it intersects with the extension from the 0-th segment
for( int i = 2; i < pts.PointCount(); i++ ) for( int i = 0; i < pts.PointCount(); i++ )
outline->Append( pts.CPoint( i ) ); {
auto pt = pts.CPoint( i );
// If we have at least 2 points, then we need to check if the leader points
// already exist before re-adding them to the finalized polygon
if( pts.PointCount() < 2 || ( pts.CPoint( -1 ) != pt && pts.CPoint( -2 ) != pt ) )
outline->Append( pts.CPoint( i ) );
}
} }
outline->Outline( 0 ).SetClosed( true ); outline->Outline( 0 ).SetClosed( true );

View File

@ -60,6 +60,9 @@ public:
///> Zone settings source (for similar and cutout zones) ///> Zone settings source (for similar and cutout zones)
ZONE_CONTAINER* m_sourceZone; ZONE_CONTAINER* m_sourceZone;
///> Zone leader mode
POLYGON_GEOM_MANAGER::LEADER_MODE m_leaderMode;
}; };
/** /**