Add conversion of circles to zones and enable in footprint editor.

Also rule areas, of course.

Fixes https://gitlab.com/kicad/code/kicad/issues/6966
This commit is contained in:
Jeff Young 2021-01-06 17:20:54 +00:00
parent 70967bfebd
commit 2a088e5c7b
3 changed files with 61 additions and 15 deletions

View File

@ -48,6 +48,18 @@ enum RECT_CHAMFER_POSITIONS : int
};
/**
* Function TransformCircleToPolygon
* convert a circle to a polygon, using multiple straight lines
* @param aCornerBuffer = a buffer to store the polygon
* @param aCenter = the center of the circle
* @param aRadius = the radius of the circle
* @param aError = the IU allowed for error in approximation
* @param aErrorLoc = should the approximation error be placed outside or inside the polygon?
*/
void TransformCircleToPolygon( SHAPE_LINE_CHAIN& aCornerBuffer, wxPoint aCenter, int aRadius,
int aError, ERROR_LOC aErrorLoc );
/**
* Function TransformCircleToPolygon
* convert a circle to a polygon, using multiple straight lines

View File

@ -39,6 +39,7 @@
#include <tools/edit_tool.h>
#include <tools/pcb_actions.h>
#include <tools/pcb_selection_tool.h>
#include <convert_basic_shapes_to_polygon.h>
#include "convert_tool.h"
@ -72,31 +73,27 @@ bool CONVERT_TOOL::Init()
m_menu->SetTitle( _( "Convert" ) );
static KICAD_T convertableTracks[] = { PCB_TRACE_T, PCB_ARC_T, EOT };
static KICAD_T convertableZones[] = { PCB_ZONE_T, PCB_FP_ZONE_T, EOT };
static KICAD_T zones[] = { PCB_ZONE_T, PCB_FP_ZONE_T, EOT };
auto graphicLines = P_S_C::OnlyGraphicShapeTypes( { S_SEGMENT, S_RECT } ) && P_S_C::SameLayer();
auto graphicLines = P_S_C::OnlyGraphicShapeTypes( { S_SEGMENT, S_RECT, S_CIRCLE } )
&& P_S_C::SameLayer();
auto trackLines = S_C::MoreThan( 1 ) &&
S_C::OnlyTypes( convertableTracks ) && P_S_C::SameLayer();
auto trackLines = S_C::MoreThan( 1 ) && S_C::OnlyTypes( convertableTracks )
&& P_S_C::SameLayer();
auto anyLines = graphicLines || trackLines;
auto anyPolys = ( S_C::OnlyTypes( convertableZones ) ||
P_S_C::OnlyGraphicShapeTypes( { S_POLYGON, S_RECT } ) );
auto anyPolys = S_C::OnlyTypes( zones )
|| P_S_C::OnlyGraphicShapeTypes( { S_POLYGON, S_RECT } );
auto lineToArc = S_C::Count( 1 ) && ( P_S_C::OnlyGraphicShapeTypes( { S_SEGMENT } ) ||
S_C::OnlyType( PCB_TRACE_T ) );
auto lineToArc = S_C::Count( 1 ) && ( P_S_C::OnlyGraphicShapeTypes( { S_SEGMENT } )
|| S_C::OnlyType( PCB_TRACE_T ) );
auto showConvert = anyPolys || anyLines || lineToArc;
m_menu->AddItem( PCB_ACTIONS::convertToPoly, anyLines );
if( m_frame->IsType( FRAME_PCB_EDITOR ) )
m_menu->AddItem( PCB_ACTIONS::convertToZone, anyLines );
if( m_frame->IsType( FRAME_PCB_EDITOR ) )
m_menu->AddItem( PCB_ACTIONS::convertToKeepout, anyLines );
m_menu->AddItem( PCB_ACTIONS::convertToZone, anyLines );
m_menu->AddItem( PCB_ACTIONS::convertToKeepout, anyLines );
m_menu->AddItem( PCB_ACTIONS::convertToLines, anyPolys );
// Currently the code exists, but tracks are not really existing in footprints
@ -132,6 +129,7 @@ int CONVERT_TOOL::LinesToPoly( const TOOL_EVENT& aEvent )
{
case S_SEGMENT:
case S_RECT:
case S_CIRCLE:
// case S_ARC: // Not yet
break;
@ -163,6 +161,8 @@ int CONVERT_TOOL::LinesToPoly( const TOOL_EVENT& aEvent )
polySet.Append( makePolysFromRects( selection.GetItems() ) );
polySet.Append( makePolysFromCircles( selection.GetItems() ) );
if( polySet.IsEmpty() )
return 0;
@ -356,6 +356,33 @@ SHAPE_POLY_SET CONVERT_TOOL::makePolysFromRects( const std::deque<EDA_ITEM*>& aI
}
SHAPE_POLY_SET CONVERT_TOOL::makePolysFromCircles( const std::deque<EDA_ITEM*>& aItems )
{
SHAPE_POLY_SET poly;
for( EDA_ITEM* item : aItems )
{
if( item->Type() != PCB_SHAPE_T && item->Type() != PCB_FP_SHAPE_T )
continue;
PCB_SHAPE* graphic = static_cast<PCB_SHAPE*>( item );
if( graphic->GetShape() != S_CIRCLE )
continue;
BOARD_DESIGN_SETTINGS& bds = graphic->GetBoard()->GetDesignSettings();
SHAPE_LINE_CHAIN outline;
TransformCircleToPolygon( outline, graphic->GetPosition(), graphic->GetRadius(),
bds.m_MaxError, ERROR_OUTSIDE );
poly.AddOutline( outline );
}
return poly;
}
int CONVERT_TOOL::PolyToLines( const TOOL_EVENT& aEvent )
{
auto& selection = m_selectionTool->RequestSelection(

View File

@ -89,6 +89,13 @@ private:
*/
static SHAPE_POLY_SET makePolysFromRects( const std::deque<EDA_ITEM*>& aItems );
/**
* Tries to make polygons from circles
* @param aItems is a list of circle shapes to process
* @return a SHAPE_POLY_SET containing any polygons that were created
*/
static SHAPE_POLY_SET makePolysFromCircles( const std::deque<EDA_ITEM*>& aItems );
PCB_SELECTION_TOOL* m_selectionTool;
CONDITIONAL_MENU* m_menu;
PCB_BASE_FRAME* m_frame;