Add Convert Shapes tool to footprint editor

This commit is contained in:
Jon Evans 2020-10-02 18:42:32 -04:00
parent 3b252c696d
commit a25d091b6c
5 changed files with 50 additions and 19 deletions

View File

@ -642,15 +642,19 @@ void ZONE_CONTAINER::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PA
if( m_FilledPolysList.count( pcbframe->GetActiveLayer() ) )
layer = pcbframe->GetActiveLayer();
#endif
auto layer_it = m_FilledPolysList.find( layer );
if( layer_it == m_FilledPolysList.end() )
layer_it = m_FilledPolysList.begin();
if( layer_it != m_FilledPolysList.end() )
if( !GetIsRuleArea() )
{
msg.Printf( wxT( "%d" ), layer_it->second.TotalVertices() );
aList.emplace_back( MSG_PANEL_ITEM( _( "Corner Count" ), msg, BLUE ) );
auto layer_it = m_FilledPolysList.find( layer );
if( layer_it == m_FilledPolysList.end() )
layer_it = m_FilledPolysList.begin();
if( layer_it != m_FilledPolysList.end() )
{
msg.Printf( wxT( "%d" ), layer_it->second.TotalVertices() );
aList.emplace_back( MSG_PANEL_ITEM( _( "Corner Count" ), msg, BLUE ) );
}
}
}
@ -1313,6 +1317,9 @@ double MODULE_ZONE_CONTAINER::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const
if( !aView )
return 0;
if( !aView->IsLayerVisible( LAYER_ZONES ) )
return HIDE;
bool flipped = GetParent() && GetParent()->GetLayer() == B_Cu;
// Handle Render tab switches

View File

@ -20,6 +20,7 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "tools/convert_tool.h"
#include "tools/drawing_tool.h"
#include "tools/edit_tool.h"
#include "tools/footprint_editor_tools.h"
@ -861,6 +862,7 @@ void FOOTPRINT_EDIT_FRAME::setupTools()
m_toolManager->RegisterTool( new PCBNEW_PICKER_TOOL );
m_toolManager->RegisterTool( new POSITION_RELATIVE_TOOL );
m_toolManager->RegisterTool( new PCB_VIEWER_TOOLS );
m_toolManager->RegisterTool( new CONVERT_TOOL );
m_toolManager->GetTool<SELECTION_TOOL>()->SetEditModules( true );
m_toolManager->GetTool<EDIT_TOOL>()->SetEditModules( true );

View File

@ -26,6 +26,7 @@
#include <board_commit.h>
#include <class_board.h>
#include <class_drawsegment.h>
#include <class_edge_mod.h>
#include <class_track.h>
#include <class_zone.h>
#include <collectors.h>
@ -68,6 +69,7 @@ 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_AREA_T, PCB_MODULE_ZONE_AREA_T, EOT };
auto graphicLines = P_S_C::OnlyGraphicShapeTypes( { S_SEGMENT, S_RECT } ) && P_S_C::SameLayer();
@ -76,16 +78,19 @@ bool CONVERT_TOOL::Init()
auto anyLines = graphicLines || trackLines;
auto anyPolys = ( S_C::OnlyType( PCB_ZONE_AREA_T ) ||
auto anyPolys = ( S_C::OnlyTypes( convertableZones ) ||
P_S_C::OnlyGraphicShapeTypes( { S_POLYGON, S_RECT } ) );
auto lineToArc = 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 );
m_menu->AddItem( PCB_ACTIONS::convertToZone, anyLines );
if( m_frame->IsType( FRAME_PCB_EDITOR ) )
m_menu->AddItem( PCB_ACTIONS::convertToZone, anyLines );
m_menu->AddItem( PCB_ACTIONS::convertToKeepout, anyLines );
m_menu->AddItem( PCB_ACTIONS::convertToLines, anyPolys );
m_menu->AddItem( PCB_ACTIONS::convertToTracks, anyPolys );
@ -94,7 +99,7 @@ bool CONVERT_TOOL::Init()
for( std::shared_ptr<ACTION_MENU>& subMenu : m_selectionTool->GetToolMenu().GetSubMenus() )
{
if( dynamic_cast<SPECIAL_TOOLS_CONTEXT_MENU*>( subMenu.get() ) )
static_cast<CONDITIONAL_MENU*>( subMenu.get() )->AddMenu( m_menu, showConvert );
static_cast<CONDITIONAL_MENU*>( subMenu.get() )->AddMenu( m_menu, SELECTION_CONDITIONS::ShowAlways );
}
return true;
@ -103,6 +108,8 @@ bool CONVERT_TOOL::Init()
int CONVERT_TOOL::LinesToPoly( const TOOL_EVENT& aEvent )
{
MODULE* mod = nullptr;
auto& selection = m_selectionTool->RequestSelection(
[]( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, SELECTION_TOOL* sTool )
{
@ -116,11 +123,12 @@ int CONVERT_TOOL::LinesToPoly( const TOOL_EVENT& aEvent )
switch( item->Type() )
{
case PCB_LINE_T:
case PCB_MODULE_EDGE_T:
switch( static_cast<DRAWSEGMENT*>( item )->GetShape() )
{
case S_SEGMENT:
case S_RECT:
//case S_ARC: // Not yet
// case S_ARC: // Not yet
break;
default:
@ -154,6 +162,11 @@ int CONVERT_TOOL::LinesToPoly( const TOOL_EVENT& aEvent )
if( polySet.IsEmpty() )
return 0;
bool isFootprint = m_frame->IsType( FRAME_FOOTPRINT_EDITOR );
if( EDGE_MODULE* edge_mod = dynamic_cast<EDGE_MODULE*>( selection.Front() ) )
mod = edge_mod->GetParentModule();
BOARD_COMMIT commit( m_frame );
// For now, we convert each outline in the returned shape to its own polygon
@ -166,7 +179,7 @@ int CONVERT_TOOL::LinesToPoly( const TOOL_EVENT& aEvent )
{
for( const SHAPE_POLY_SET& poly : polys )
{
DRAWSEGMENT* graphic = new DRAWSEGMENT;
DRAWSEGMENT* graphic = isFootprint ? new EDGE_MODULE( mod ) : new DRAWSEGMENT;
graphic->SetShape( S_POLYGON );
graphic->SetLayer( destLayer );
@ -196,7 +209,8 @@ int CONVERT_TOOL::LinesToPoly( const TOOL_EVENT& aEvent )
for( const SHAPE_POLY_SET& poly : polys )
{
ZONE_CONTAINER* zone = new ZONE_CONTAINER( parent );
ZONE_CONTAINER* zone = isFootprint ? new MODULE_ZONE_CONTAINER( parent )
: new ZONE_CONTAINER( parent );
*zone->Outline() = poly;
zone->HatchBorder();
@ -313,7 +327,7 @@ SHAPE_POLY_SET CONVERT_TOOL::makePolysFromRects( const std::deque<EDA_ITEM*>& aI
for( EDA_ITEM* item : aItems )
{
if( item->Type() != PCB_LINE_T )
if( item->Type() != PCB_LINE_T && item->Type() != PCB_MODULE_EDGE_T )
continue;
DRAWSEGMENT* graphic = static_cast<DRAWSEGMENT*>( item );
@ -353,6 +367,7 @@ int CONVERT_TOOL::PolyToLines( const TOOL_EVENT& aEvent )
switch( item->Type() )
{
case PCB_LINE_T:
case PCB_MODULE_EDGE_T:
switch( static_cast<DRAWSEGMENT*>( item )->GetShape() )
{
case S_POLYGON:
@ -368,6 +383,7 @@ int CONVERT_TOOL::PolyToLines( const TOOL_EVENT& aEvent )
break;
case PCB_ZONE_AREA_T:
case PCB_MODULE_ZONE_AREA_T:
break;
default:
@ -387,10 +403,12 @@ int CONVERT_TOOL::PolyToLines( const TOOL_EVENT& aEvent )
switch( aItem->Type() )
{
case PCB_ZONE_AREA_T:
case PCB_MODULE_ZONE_AREA_T:
set = *static_cast<ZONE_CONTAINER*>( aItem )->Outline();
break;
case PCB_LINE_T:
case PCB_MODULE_EDGE_T:
{
DRAWSEGMENT* graphic = static_cast<DRAWSEGMENT*>( aItem );
@ -506,7 +524,9 @@ int CONVERT_TOOL::SegmentToArc( const TOOL_EVENT& aEvent )
{
BOARD_ITEM* item = aCollector[i];
if( !( item->Type() == PCB_LINE_T || item->Type() == PCB_TRACE_T ) )
if( !( item->Type() == PCB_LINE_T ||
item->Type() == PCB_TRACE_T ||
item->Type() == PCB_MODULE_EDGE_T ) )
aCollector.Remove( item );
}
} );
@ -541,7 +561,7 @@ int CONVERT_TOOL::SegmentToArc( const TOOL_EVENT& aEvent )
BOARD_COMMIT commit( m_frame );
if( source->Type() == PCB_LINE_T )
if( source->Type() == PCB_LINE_T || source->Type() == PCB_MODULE_EDGE_T )
{
DRAWSEGMENT* line = static_cast<DRAWSEGMENT*>( source );
DRAWSEGMENT* arc = new DRAWSEGMENT( parent );
@ -585,6 +605,7 @@ OPT<SEG> CONVERT_TOOL::getStartEndPoints( EDA_ITEM* aItem )
switch( aItem->Type() )
{
case PCB_LINE_T:
case PCB_MODULE_EDGE_T:
{
DRAWSEGMENT* line = static_cast<DRAWSEGMENT*>( aItem );
return boost::make_optional<SEG>( { VECTOR2I( line->GetStart() ),

View File

@ -25,6 +25,7 @@
#ifndef CONVERT_TOOL_H_
#define CONVERT_TOOL_H_
#include <geometry/shape_poly_set.h>
#include <tool/tool_interactive.h>
class CONDITIONAL_MENU;

View File

@ -144,7 +144,7 @@ bool PCB_SELECTION_CONDITIONS::onlyGraphicShapeTypesFunc( const SELECTION& aSele
for( const EDA_ITEM* item : aSelection )
{
if( item->Type() != PCB_LINE_T )
if( item->Type() != PCB_LINE_T && item->Type() != PCB_MODULE_EDGE_T )
return false;
STROKE_T shape = static_cast<const DRAWSEGMENT*>( item )->GetShape();