diff --git a/common/preview_items/polygon_geom_manager.cpp b/common/preview_items/polygon_geom_manager.cpp index 79701b25ad..fc735ad1fa 100644 --- a/common/preview_items/polygon_geom_manager.cpp +++ b/common/preview_items/polygon_geom_manager.cpp @@ -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 ); 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 { diff --git a/include/preview_items/polygon_geom_manager.h b/include/preview_items/polygon_geom_manager.h index a019362182..e8fa42950b 100644 --- a/include/preview_items/polygon_geom_manager.h +++ b/include/preview_items/polygon_geom_manager.h @@ -128,7 +128,7 @@ public: /** * 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 diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index 1acbaa8be3..fb356c84d5 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -1383,6 +1383,7 @@ int DRAWING_TOOL::drawZone( bool aKeepout, ZONE_MODE aMode ) // the geometry manager which handles the zone geometry, and // hands the calculated points over to the zone creator tool POLYGON_GEOM_MANAGER polyGeomMgr( zoneTool ); + bool constrainAngle = false; Activate(); // register for events @@ -1406,6 +1407,11 @@ int DRAWING_TOOL::drawZone( bool aKeepout, ZONE_MODE aMode ) VECTOR2I cursorPos = grid.BestSnapAnchor( m_controls->GetMousePosition(), layers ); 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 ); + if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) ) { // pre-empted by another tool, give up @@ -1459,6 +1465,8 @@ int DRAWING_TOOL::drawZone( bool aKeepout, ZONE_MODE aMode ) if( !started ) { started = true; + constrainAngle = ( polyGeomMgr.GetLeaderMode() == + POLYGON_GEOM_MANAGER::LEADER_MODE::DEG45 ); m_controls->SetAutoPan( true ); m_controls->CaptureCursor( true ); } @@ -1483,9 +1491,7 @@ int DRAWING_TOOL::drawZone( bool aKeepout, ZONE_MODE aMode ) else if( polyGeomMgr.IsPolygonInProgress() && ( evt->IsMotion() || evt->IsDrag( BUT_LEFT ) ) ) { - polyGeomMgr.SetCursorPosition( cursorPos, evt->Modifier( MD_CTRL ) - ? POLYGON_GEOM_MANAGER::LEADER_MODE::DEG45 - : POLYGON_GEOM_MANAGER::LEADER_MODE::DIRECT ); + polyGeomMgr.SetCursorPosition( cursorPos ); if( polyGeomMgr.IsSelfIntersecting( true ) ) { diff --git a/pcbnew/tools/zone_create_helper.cpp b/pcbnew/tools/zone_create_helper.cpp index 9ac423e20c..118c3ed12d 100644 --- a/pcbnew/tools/zone_create_helper.cpp +++ b/pcbnew/tools/zone_create_helper.cpp @@ -65,6 +65,7 @@ std::unique_ptr ZONE_CREATE_HELPER::createNewZone( bool aKeepout zoneInfo.m_CurrentZone_Layer = m_params.m_layer; zoneInfo.m_NetcodeSelection = board.GetHighLightNetCode(); 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 != DRAWING_TOOL::ZONE_MODE::GRAPHIC_POLYGON ) { @@ -302,13 +303,17 @@ void ZONE_CREATE_HELPER::OnComplete( const POLYGON_GEOM_MANAGER& aMgr ) { 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 third point is where it intersects with the extension from the 0-th segment - for( int i = 2; i < pts.PointCount(); i++ ) - outline->Append( pts.CPoint( i ) ); + for( int i = 0; i < pts.PointCount(); 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 ); diff --git a/pcbnew/tools/zone_create_helper.h b/pcbnew/tools/zone_create_helper.h index 3b56abecb0..b1a816cbe8 100644 --- a/pcbnew/tools/zone_create_helper.h +++ b/pcbnew/tools/zone_create_helper.h @@ -60,6 +60,9 @@ public: ///> Zone settings source (for similar and cutout zones) ZONE_CONTAINER* m_sourceZone; + + ///> Zone leader mode + POLYGON_GEOM_MANAGER::LEADER_MODE m_leaderMode; }; /**