From a90656900a78e8cfa3f3db245bf39ae0e85bf08a Mon Sep 17 00:00:00 2001 From: Jon Evans Date: Sun, 8 Aug 2021 20:28:47 -0400 Subject: [PATCH] Allow creating polygon types from polygons Fixes https://gitlab.com/kicad/code/kicad/-/issues/7302 --- pcbnew/tools/convert_tool.cpp | 66 ++++++++++++++++++++++++++++------- pcbnew/tools/convert_tool.h | 10 ++++-- 2 files changed, 62 insertions(+), 14 deletions(-) diff --git a/pcbnew/tools/convert_tool.cpp b/pcbnew/tools/convert_tool.cpp index 28ee04e4be..1ff31f454d 100644 --- a/pcbnew/tools/convert_tool.cpp +++ b/pcbnew/tools/convert_tool.cpp @@ -88,7 +88,6 @@ bool CONVERT_TOOL::Init() && P_S_C::SameLayer(); auto anyLines = graphicLines || trackLines; - auto anyPolys = S_C::OnlyTypes( zones ) || P_S_C::OnlyGraphicShapeTypes( { SHAPE_T::POLY, SHAPE_T::RECT } ); @@ -96,11 +95,12 @@ bool CONVERT_TOOL::Init() && ( P_S_C::OnlyGraphicShapeTypes( { SHAPE_T::SEGMENT } ) || S_C::OnlyType( PCB_TRACE_T ) ); - auto showConvert = anyPolys || anyLines || lineToArc; + auto showConvert = anyPolys || anyLines || lineToArc; + auto canCreatePolyType = anyLines || anyPolys; - m_menu->AddItem( PCB_ACTIONS::convertToPoly, anyLines ); - m_menu->AddItem( PCB_ACTIONS::convertToZone, anyLines ); - m_menu->AddItem( PCB_ACTIONS::convertToKeepout, anyLines ); + m_menu->AddItem( PCB_ACTIONS::convertToPoly, canCreatePolyType ); + m_menu->AddItem( PCB_ACTIONS::convertToZone, canCreatePolyType ); + m_menu->AddItem( PCB_ACTIONS::convertToKeepout, canCreatePolyType ); m_menu->AddItem( PCB_ACTIONS::convertToLines, anyPolys ); // Currently the code exists, but tracks are not really existing in footprints @@ -117,7 +117,7 @@ bool CONVERT_TOOL::Init() } -int CONVERT_TOOL::LinesToPoly( const TOOL_EVENT& aEvent ) +int CONVERT_TOOL::CreatePolys( const TOOL_EVENT& aEvent ) { FOOTPRINT* parentFootprint = nullptr; @@ -138,6 +138,7 @@ int CONVERT_TOOL::LinesToPoly( const TOOL_EVENT& aEvent ) case SHAPE_T::RECT: case SHAPE_T::CIRCLE: case SHAPE_T::ARC: + case SHAPE_T::POLY: break; default: @@ -150,6 +151,10 @@ int CONVERT_TOOL::LinesToPoly( const TOOL_EVENT& aEvent ) case PCB_ARC_T: break; + case PCB_ZONE_T: + case PCB_FP_ZONE_T: + break; + default: aCollector.Remove( item ); } @@ -166,6 +171,8 @@ int CONVERT_TOOL::LinesToPoly( const TOOL_EVENT& aEvent ) polySet.Append( makePolysFromCircles( selection.GetItems() ) ); + polySet.Append( extractPolygons( selection.GetItems() ) ); + if( polySet.IsEmpty() ) return 0; @@ -443,7 +450,42 @@ SHAPE_POLY_SET CONVERT_TOOL::makePolysFromCircles( const std::deque& } -int CONVERT_TOOL::PolyToLines( const TOOL_EVENT& aEvent ) +SHAPE_POLY_SET CONVERT_TOOL::extractPolygons( const std::deque& aItems ) +{ + SHAPE_POLY_SET poly; + + for( EDA_ITEM* item : aItems ) + { + switch( item->Type() ) + { + case PCB_SHAPE_T: + switch( static_cast( item )->GetShape() ) + { + case SHAPE_T::POLY: + poly.Append( static_cast( item )->GetPolyShape() ); + break; + + default: + continue; + } + + break; + + case PCB_ZONE_T: + case PCB_FP_ZONE_T: + poly.Append( *static_cast( item )->Outline() ); + break; + + default: + continue; + } + } + + return poly; +} + + +int CONVERT_TOOL::CreateLines( const TOOL_EVENT& aEvent ) { auto& selection = m_selectionTool->RequestSelection( []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool ) @@ -789,10 +831,10 @@ OPT CONVERT_TOOL::getStartEndPoints( EDA_ITEM* aItem, int* aWidth ) void CONVERT_TOOL::setTransitions() { - Go( &CONVERT_TOOL::LinesToPoly, PCB_ACTIONS::convertToPoly.MakeEvent() ); - Go( &CONVERT_TOOL::LinesToPoly, PCB_ACTIONS::convertToZone.MakeEvent() ); - Go( &CONVERT_TOOL::LinesToPoly, PCB_ACTIONS::convertToKeepout.MakeEvent() ); - Go( &CONVERT_TOOL::PolyToLines, PCB_ACTIONS::convertToLines.MakeEvent() ); - Go( &CONVERT_TOOL::PolyToLines, PCB_ACTIONS::convertToTracks.MakeEvent() ); + Go( &CONVERT_TOOL::CreatePolys, PCB_ACTIONS::convertToPoly.MakeEvent() ); + Go( &CONVERT_TOOL::CreatePolys, PCB_ACTIONS::convertToZone.MakeEvent() ); + Go( &CONVERT_TOOL::CreatePolys, PCB_ACTIONS::convertToKeepout.MakeEvent() ); + Go( &CONVERT_TOOL::CreateLines, PCB_ACTIONS::convertToLines.MakeEvent() ); + Go( &CONVERT_TOOL::CreateLines, PCB_ACTIONS::convertToTracks.MakeEvent() ); Go( &CONVERT_TOOL::SegmentToArc, PCB_ACTIONS::convertToArc.MakeEvent() ); } diff --git a/pcbnew/tools/convert_tool.h b/pcbnew/tools/convert_tool.h index b714287ca6..e0629a9c8d 100644 --- a/pcbnew/tools/convert_tool.h +++ b/pcbnew/tools/convert_tool.h @@ -48,12 +48,12 @@ public: /** * Convert selected lines to a polygon, if possible. */ - int LinesToPoly( const TOOL_EVENT& aEvent ); + int CreatePolys( const TOOL_EVENT& aEvent ); /** * Convert selected polygon-like object to graphic lines, if possible. */ - int PolyToLines( const TOOL_EVENT& aEvent ); + int CreateLines( const TOOL_EVENT& aEvent ); /** * Convert selected segment (graphic or track) to an arc of the same type @@ -100,6 +100,12 @@ private: */ static SHAPE_POLY_SET makePolysFromCircles( const std::deque& aItems ); + /** + * For any polygon shapes (zones, keepouts, graphic polys) in aItems, extracts + * the polygon outlines into the returned #SHAPE_POLY_SET. + */ + static SHAPE_POLY_SET extractPolygons( const std::deque& aItems ); + PCB_SELECTION_TOOL* m_selectionTool; CONDITIONAL_MENU* m_menu; PCB_BASE_FRAME* m_frame;