Add ignore-line-widths mode to CONVERT_TOOL.
Fixes https://gitlab.com/kicad/code/kicad/issues/5911
This commit is contained in:
parent
3245aec5b5
commit
f0b9e67212
|
@ -247,7 +247,19 @@ public:
|
|||
*/
|
||||
bool IsPolyShapeValid() const;
|
||||
|
||||
void SetPolyShape( const SHAPE_POLY_SET& aShape ) { m_poly = aShape; }
|
||||
void SetPolyShape( const SHAPE_POLY_SET& aShape )
|
||||
{
|
||||
m_poly = aShape;
|
||||
|
||||
for( int ii = 0; ii < m_poly.OutlineCount(); ++ii )
|
||||
{
|
||||
if( m_poly.HoleCount( ii ) )
|
||||
{
|
||||
m_poly.Fracture( SHAPE_POLY_SET::PM_FAST );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SetPolyPoints( const std::vector<VECTOR2I>& aPoints );
|
||||
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
#include <pcb_edit_frame.h>
|
||||
#include <pcbnew_settings.h>
|
||||
#include <zones.h>
|
||||
#include <bitmaps.h>
|
||||
#include <widgets/unit_binder.h>
|
||||
#include <zone.h>
|
||||
#include <pad.h>
|
||||
|
@ -43,7 +42,8 @@
|
|||
class DIALOG_COPPER_ZONE : public DIALOG_COPPER_ZONE_BASE
|
||||
{
|
||||
public:
|
||||
DIALOG_COPPER_ZONE( PCB_BASE_FRAME* aParent, ZONE_SETTINGS* aSettings );
|
||||
DIALOG_COPPER_ZONE( PCB_BASE_FRAME* aParent, ZONE_SETTINGS* aSettings,
|
||||
CONVERT_SETTINGS* aConvertSettings );
|
||||
|
||||
private:
|
||||
using NET_FILTER = std::unique_ptr<EDA_PATTERN_MATCH>;
|
||||
|
@ -56,36 +56,6 @@ private:
|
|||
static constexpr int HIDE_ANONYMOUS_NETS{ 1 << 0 };
|
||||
static constexpr int SORT_BY_PAD_COUNT{ 1 << 1 };
|
||||
|
||||
PCB_BASE_FRAME* m_Parent;
|
||||
|
||||
bool m_settingsExported; // settings will be written to all other zones
|
||||
|
||||
ZONE_SETTINGS m_settings;
|
||||
ZONE_SETTINGS* m_ptr;
|
||||
bool m_netSortingByPadCount;
|
||||
NET_FILTER_LIST m_showNetsFilter;
|
||||
|
||||
int m_cornerSmoothingType;
|
||||
int m_maxNetCode;
|
||||
int m_currentlySelectedNetcode;
|
||||
UNIT_BINDER m_outlineHatchPitch;
|
||||
|
||||
UNIT_BINDER m_cornerRadius;
|
||||
UNIT_BINDER m_clearance;
|
||||
UNIT_BINDER m_minWidth;
|
||||
UNIT_BINDER m_antipadClearance;
|
||||
UNIT_BINDER m_spokeWidth;
|
||||
|
||||
UNIT_BINDER m_gridStyleRotation;
|
||||
UNIT_BINDER m_gridStyleThickness;
|
||||
UNIT_BINDER m_gridStyleGap;
|
||||
UNIT_BINDER m_islandThreshold;
|
||||
bool m_hideAutoGeneratedNets;
|
||||
bool m_isTeardrop;
|
||||
|
||||
std::map<wxString, int> m_netNameToNetCode;
|
||||
std::vector<NETINFO_ITEM*> m_netInfoItemList;
|
||||
|
||||
bool TransferDataToWindow() override;
|
||||
bool TransferDataFromWindow() override;
|
||||
|
||||
|
@ -127,12 +97,48 @@ private:
|
|||
void handleRemoveIslandsSelection();
|
||||
void storePersistentNetSortConfigurations();
|
||||
void loadPersistentNetSortConfigurations();
|
||||
|
||||
private:
|
||||
PCB_BASE_FRAME* m_Parent;
|
||||
|
||||
bool m_settingsExported; // settings will be written to all other zones
|
||||
|
||||
ZONE_SETTINGS m_settings;
|
||||
ZONE_SETTINGS* m_ptr;
|
||||
bool m_netSortingByPadCount;
|
||||
NET_FILTER_LIST m_showNetsFilter;
|
||||
|
||||
int m_cornerSmoothingType;
|
||||
int m_maxNetCode;
|
||||
int m_currentlySelectedNetcode;
|
||||
UNIT_BINDER m_outlineHatchPitch;
|
||||
|
||||
UNIT_BINDER m_cornerRadius;
|
||||
UNIT_BINDER m_clearance;
|
||||
UNIT_BINDER m_minWidth;
|
||||
UNIT_BINDER m_antipadClearance;
|
||||
UNIT_BINDER m_spokeWidth;
|
||||
|
||||
UNIT_BINDER m_gridStyleRotation;
|
||||
UNIT_BINDER m_gridStyleThickness;
|
||||
UNIT_BINDER m_gridStyleGap;
|
||||
UNIT_BINDER m_islandThreshold;
|
||||
bool m_hideAutoGeneratedNets;
|
||||
bool m_isTeardrop;
|
||||
|
||||
std::map<wxString, int> m_netNameToNetCode;
|
||||
std::vector<NETINFO_ITEM*> m_netInfoItemList;
|
||||
|
||||
CONVERT_SETTINGS* m_convertSettings;
|
||||
wxCheckBox* m_cbIgnoreLineWidths;
|
||||
wxCheckBox* m_cbDeleteOriginals;
|
||||
};
|
||||
|
||||
|
||||
int InvokeCopperZonesEditor( PCB_BASE_FRAME* aCaller, ZONE_SETTINGS* aSettings )
|
||||
int InvokeCopperZonesEditor( PCB_BASE_FRAME* aCaller, ZONE_SETTINGS* aSettings,
|
||||
CONVERT_SETTINGS* aConvertSettings )
|
||||
{
|
||||
DIALOG_COPPER_ZONE dlg( aCaller, aSettings );
|
||||
DIALOG_COPPER_ZONE dlg( aCaller, aSettings, aConvertSettings );
|
||||
|
||||
return dlg.ShowQuasiModal();
|
||||
}
|
||||
|
@ -164,7 +170,8 @@ static bool sortNetsByNames( const NETINFO_ITEM* a, const NETINFO_ITEM* b )
|
|||
}
|
||||
|
||||
|
||||
DIALOG_COPPER_ZONE::DIALOG_COPPER_ZONE( PCB_BASE_FRAME* aParent, ZONE_SETTINGS* aSettings ) :
|
||||
DIALOG_COPPER_ZONE::DIALOG_COPPER_ZONE( PCB_BASE_FRAME* aParent, ZONE_SETTINGS* aSettings,
|
||||
CONVERT_SETTINGS* aConvertSettings ) :
|
||||
DIALOG_COPPER_ZONE_BASE( aParent ),
|
||||
m_cornerSmoothingType( ZONE_SETTINGS::SMOOTHING_UNDEFINED ),
|
||||
m_outlineHatchPitch( aParent, m_stBorderHatchPitchText,
|
||||
|
@ -181,7 +188,8 @@ DIALOG_COPPER_ZONE::DIALOG_COPPER_ZONE( PCB_BASE_FRAME* aParent, ZONE_SETTINGS*
|
|||
m_gridStyleGap( aParent, m_staticTextGridGap, m_tcGridStyleGap, m_GridStyleGapUnits ),
|
||||
m_islandThreshold( aParent, m_islandThresholdLabel, m_tcIslandThreshold,
|
||||
m_islandThresholdUnits ),
|
||||
m_hideAutoGeneratedNets{ false }
|
||||
m_hideAutoGeneratedNets{ false },
|
||||
m_convertSettings( aConvertSettings )
|
||||
{
|
||||
m_Parent = aParent;
|
||||
|
||||
|
@ -211,6 +219,29 @@ DIALOG_COPPER_ZONE::DIALOG_COPPER_ZONE( PCB_BASE_FRAME* aParent, ZONE_SETTINGS*
|
|||
break;
|
||||
}
|
||||
|
||||
if( aConvertSettings )
|
||||
{
|
||||
wxStaticBox* bConvertBox = new wxStaticBox( this, wxID_ANY,
|
||||
_( "Conversion Settings" ) );
|
||||
wxStaticBoxSizer* bConvertSizer = new wxStaticBoxSizer( bConvertBox, wxVERTICAL );
|
||||
|
||||
m_cbIgnoreLineWidths = new wxCheckBox( this, wxID_ANY,
|
||||
_( "Ignore source object line widths" ) );
|
||||
bConvertSizer->Add( m_cbIgnoreLineWidths, 0, wxLEFT|wxRIGHT, 5 );
|
||||
|
||||
m_cbDeleteOriginals = new wxCheckBox( this, wxID_ANY,
|
||||
_( "Delete source objects after conversion" ) );
|
||||
bConvertSizer->Add( m_cbDeleteOriginals, 0, wxALL, 5 );
|
||||
|
||||
GetSizer()->Insert( 0, bConvertSizer, 0, wxALL|wxEXPAND, 10 );
|
||||
|
||||
wxStaticLine* line = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize,
|
||||
wxLI_HORIZONTAL );
|
||||
GetSizer()->Insert( 1, line, 0, wxLEFT|wxRIGHT|wxEXPAND, 10 );
|
||||
|
||||
SetTitle( _( "Convert to Copper Zone" ) );
|
||||
}
|
||||
|
||||
m_settingsExported = false;
|
||||
m_currentlySelectedNetcode = INVALID_NET_CODE;
|
||||
m_maxNetCode = INVALID_NET_CODE;
|
||||
|
@ -238,6 +269,12 @@ DIALOG_COPPER_ZONE::DIALOG_COPPER_ZONE( PCB_BASE_FRAME* aParent, ZONE_SETTINGS*
|
|||
|
||||
bool DIALOG_COPPER_ZONE::TransferDataToWindow()
|
||||
{
|
||||
if( m_convertSettings )
|
||||
{
|
||||
m_cbIgnoreLineWidths->SetValue( m_convertSettings->m_IgnoreLineWidths );
|
||||
m_cbDeleteOriginals->SetValue( m_convertSettings->m_DeleteOriginals );
|
||||
}
|
||||
|
||||
m_cbLocked->SetValue( m_settings.m_Locked );
|
||||
m_cornerSmoothingChoice->SetSelection( m_settings.GetCornerSmoothingType() );
|
||||
m_cornerRadius.SetValue( m_settings.GetCornerRadius() );
|
||||
|
@ -461,6 +498,12 @@ bool DIALOG_COPPER_ZONE::TransferDataFromWindow()
|
|||
if( !AcceptOptions() )
|
||||
return false;
|
||||
|
||||
if( m_convertSettings )
|
||||
{
|
||||
m_convertSettings->m_IgnoreLineWidths = m_cbIgnoreLineWidths->GetValue();
|
||||
m_convertSettings->m_DeleteOriginals = m_cbDeleteOriginals->GetValue();
|
||||
}
|
||||
|
||||
m_settings.m_HatchOrientation = m_gridStyleRotation.GetAngleValue();
|
||||
m_settings.m_HatchThickness = m_gridStyleThickness.GetValue();
|
||||
m_settings.m_HatchGap = m_gridStyleGap.GetValue();
|
||||
|
@ -917,12 +960,14 @@ wxString DIALOG_COPPER_ZONE::getUnescapedNetName( const NETINFO_ITEM* net )
|
|||
|
||||
void DIALOG_COPPER_ZONE::updateInfoBar()
|
||||
{
|
||||
if( m_currentlySelectedNetcode <= INVALID_NET_CODE && !m_copperZoneInfo->IsShown() )
|
||||
if( m_currentlySelectedNetcode <= INVALID_NET_CODE
|
||||
&& !m_copperZoneInfo->IsShown()
|
||||
&& !m_convertSettings )
|
||||
{
|
||||
m_copperZoneInfo->ShowMessage(
|
||||
_( "Selecting <no net> will create an isolated copper island." ), wxICON_WARNING );
|
||||
m_copperZoneInfo->ShowMessage( _( "<no net> will result in an isolated copper island." ),
|
||||
wxICON_WARNING );
|
||||
}
|
||||
else if( m_currentlySelectedNetcode > INVALID_NET_CODE && m_copperZoneInfo->IsShown() )
|
||||
else if( m_copperZoneInfo->IsShown() )
|
||||
{
|
||||
m_copperZoneInfo->Dismiss();
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <pcb_edit_frame.h>
|
||||
#include <pcbnew_settings.h>
|
||||
#include <widgets/unit_binder.h>
|
||||
#include <wx/statbox.h>
|
||||
#include <zones.h>
|
||||
|
||||
#include <dialog_non_copper_zones_properties_base.h>
|
||||
|
@ -35,18 +36,11 @@
|
|||
|
||||
class DIALOG_NON_COPPER_ZONES_EDITOR : public DIALOG_NONCOPPER_ZONES_PROPERTIES_BASE
|
||||
{
|
||||
private:
|
||||
PCB_BASE_FRAME* m_parent;
|
||||
ZONE_SETTINGS* m_ptr;
|
||||
ZONE_SETTINGS m_settings; // working copy of zone settings
|
||||
UNIT_BINDER m_outlineHatchPitch;
|
||||
UNIT_BINDER m_minWidth;
|
||||
UNIT_BINDER m_hatchRotation;
|
||||
UNIT_BINDER m_hatchWidth;
|
||||
UNIT_BINDER m_hatchGap;
|
||||
int m_cornerSmoothingType;
|
||||
UNIT_BINDER m_cornerRadius;
|
||||
public:
|
||||
DIALOG_NON_COPPER_ZONES_EDITOR( PCB_BASE_FRAME* aParent, ZONE_SETTINGS* aSettings,
|
||||
CONVERT_SETTINGS* aConvertSettings );
|
||||
|
||||
private:
|
||||
bool TransferDataToWindow() override;
|
||||
bool TransferDataFromWindow() override;
|
||||
|
||||
|
@ -54,14 +48,28 @@ private:
|
|||
void OnLayerSelection( wxDataViewEvent& event ) override;
|
||||
void OnUpdateUI( wxUpdateUIEvent& ) override;
|
||||
|
||||
public:
|
||||
DIALOG_NON_COPPER_ZONES_EDITOR( PCB_BASE_FRAME* aParent, ZONE_SETTINGS* aSettings );
|
||||
private:
|
||||
PCB_BASE_FRAME* m_parent;
|
||||
ZONE_SETTINGS* m_ptr;
|
||||
ZONE_SETTINGS m_settings; // working copy of zone settings
|
||||
UNIT_BINDER m_outlineHatchPitch;
|
||||
UNIT_BINDER m_minWidth;
|
||||
UNIT_BINDER m_hatchRotation;
|
||||
UNIT_BINDER m_hatchWidth;
|
||||
UNIT_BINDER m_hatchGap;
|
||||
int m_cornerSmoothingType;
|
||||
UNIT_BINDER m_cornerRadius;
|
||||
|
||||
CONVERT_SETTINGS* m_convertSettings;
|
||||
wxCheckBox* m_cbIgnoreLineWidths;
|
||||
wxCheckBox* m_cbDeleteOriginals;
|
||||
};
|
||||
|
||||
|
||||
int InvokeNonCopperZonesEditor( PCB_BASE_FRAME* aParent, ZONE_SETTINGS* aSettings )
|
||||
int InvokeNonCopperZonesEditor( PCB_BASE_FRAME* aParent, ZONE_SETTINGS* aSettings,
|
||||
CONVERT_SETTINGS* aConvertSettings )
|
||||
{
|
||||
DIALOG_NON_COPPER_ZONES_EDITOR dlg( aParent, aSettings );
|
||||
DIALOG_NON_COPPER_ZONES_EDITOR dlg( aParent, aSettings, aConvertSettings );
|
||||
|
||||
return dlg.ShowQuasiModal();
|
||||
}
|
||||
|
@ -69,7 +77,8 @@ int InvokeNonCopperZonesEditor( PCB_BASE_FRAME* aParent, ZONE_SETTINGS* aSetting
|
|||
#define MIN_THICKNESS 10*IU_PER_MILS
|
||||
|
||||
DIALOG_NON_COPPER_ZONES_EDITOR::DIALOG_NON_COPPER_ZONES_EDITOR( PCB_BASE_FRAME* aParent,
|
||||
ZONE_SETTINGS* aSettings ) :
|
||||
ZONE_SETTINGS* aSettings,
|
||||
CONVERT_SETTINGS* aConvertSettings ) :
|
||||
DIALOG_NONCOPPER_ZONES_PROPERTIES_BASE( aParent ),
|
||||
m_outlineHatchPitch( aParent, m_stBorderHatchPitchText,
|
||||
m_outlineHatchPitchCtrl, m_outlineHatchUnits ),
|
||||
|
@ -78,15 +87,41 @@ DIALOG_NON_COPPER_ZONES_EDITOR::DIALOG_NON_COPPER_ZONES_EDITOR( PCB_BASE_FRAME*
|
|||
m_hatchWidth( aParent, m_hatchWidthLabel, m_hatchWidthCtrl, m_hatchWidthUnits),
|
||||
m_hatchGap( aParent, m_hatchGapLabel, m_hatchGapCtrl, m_hatchGapUnits ),
|
||||
m_cornerSmoothingType( ZONE_SETTINGS::SMOOTHING_UNDEFINED ),
|
||||
m_cornerRadius( aParent, m_cornerRadiusLabel, m_cornerRadiusCtrl, m_cornerRadiusUnits )
|
||||
m_cornerRadius( aParent, m_cornerRadiusLabel, m_cornerRadiusCtrl, m_cornerRadiusUnits ),
|
||||
m_convertSettings( aConvertSettings )
|
||||
{
|
||||
m_parent = aParent;
|
||||
|
||||
m_ptr = aSettings;
|
||||
m_settings = *aSettings;
|
||||
|
||||
if( aConvertSettings )
|
||||
{
|
||||
wxStaticBox* bConvertBox = new wxStaticBox( this, wxID_ANY,
|
||||
_( "Conversion Settings" ) );
|
||||
wxStaticBoxSizer* bConvertSizer = new wxStaticBoxSizer( bConvertBox, wxVERTICAL );
|
||||
|
||||
m_cbIgnoreLineWidths = new wxCheckBox( this, wxID_ANY,
|
||||
_( "Ignore source object line widths" ) );
|
||||
bConvertSizer->Add( m_cbIgnoreLineWidths, 0, wxLEFT|wxRIGHT, 5 );
|
||||
|
||||
m_cbDeleteOriginals = new wxCheckBox( this, wxID_ANY,
|
||||
_( "Delete source objects after conversion" ) );
|
||||
bConvertSizer->Add( m_cbDeleteOriginals, 0, wxALL, 5 );
|
||||
|
||||
GetSizer()->Insert( 0, bConvertSizer, 0, wxALL|wxEXPAND, 10 );
|
||||
|
||||
wxStaticLine* line = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize,
|
||||
wxLI_HORIZONTAL );
|
||||
GetSizer()->Insert( 1, line, 0, wxLEFT|wxRIGHT|wxEXPAND, 10 );
|
||||
|
||||
SetTitle( _( "Convert to Non Copper Zone" ) );
|
||||
}
|
||||
|
||||
bool fpEditorMode = m_parent->IsType( FRAME_FOOTPRINT_EDITOR );
|
||||
|
||||
m_staticTextLayerSelection->SetFont( KIUI::GetInfoFont( this ) );
|
||||
|
||||
m_settings.SetupLayersList( m_layers, m_parent, LSET::AllNonCuMask(), fpEditorMode );
|
||||
|
||||
SetupStandardButtons();
|
||||
|
@ -113,6 +148,12 @@ void DIALOG_NON_COPPER_ZONES_EDITOR::OnUpdateUI( wxUpdateUIEvent& )
|
|||
|
||||
bool DIALOG_NON_COPPER_ZONES_EDITOR::TransferDataToWindow()
|
||||
{
|
||||
if( m_convertSettings )
|
||||
{
|
||||
m_cbIgnoreLineWidths->SetValue( m_convertSettings->m_IgnoreLineWidths );
|
||||
m_cbDeleteOriginals->SetValue( m_convertSettings->m_DeleteOriginals );
|
||||
}
|
||||
|
||||
m_cornerSmoothingChoice->SetSelection( m_settings.GetCornerSmoothingType() );
|
||||
m_cornerRadius.SetValue( m_settings.GetCornerRadius() );
|
||||
|
||||
|
@ -199,6 +240,12 @@ void DIALOG_NON_COPPER_ZONES_EDITOR::OnLayerSelection( wxDataViewEvent& event )
|
|||
|
||||
bool DIALOG_NON_COPPER_ZONES_EDITOR::TransferDataFromWindow()
|
||||
{
|
||||
if( m_convertSettings )
|
||||
{
|
||||
m_convertSettings->m_IgnoreLineWidths = m_cbIgnoreLineWidths->GetValue();
|
||||
m_convertSettings->m_DeleteOriginals = m_cbDeleteOriginals->GetValue();
|
||||
}
|
||||
|
||||
m_settings.SetCornerSmoothingType( m_cornerSmoothingChoice->GetSelection() );
|
||||
|
||||
m_settings.SetCornerRadius( m_settings.GetCornerSmoothingType() == ZONE_SETTINGS::SMOOTHING_NONE
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <zone_settings.h>
|
||||
#include <dialog_rule_area_properties_base.h>
|
||||
#include <widgets/unit_binder.h>
|
||||
#include <wx/statbox.h>
|
||||
|
||||
#define LAYER_LIST_COLUMN_CHECK 0
|
||||
#define LAYER_LIST_COLUMN_ICON 1
|
||||
|
@ -40,36 +41,44 @@
|
|||
class DIALOG_RULE_AREA_PROPERTIES : public DIALOG_RULE_AREA_PROPERTIES_BASE
|
||||
{
|
||||
public:
|
||||
DIALOG_RULE_AREA_PROPERTIES( PCB_BASE_FRAME* aParent, ZONE_SETTINGS* aSettings );
|
||||
DIALOG_RULE_AREA_PROPERTIES( PCB_BASE_FRAME* aParent, ZONE_SETTINGS* aSettings,
|
||||
CONVERT_SETTINGS* aConvertSettings );
|
||||
|
||||
private:
|
||||
UNIT_BINDER m_outlineHatchPitch;
|
||||
PCB_BASE_FRAME* m_parent;
|
||||
ZONE_SETTINGS m_zonesettings; ///< the working copy of zone settings
|
||||
ZONE_SETTINGS* m_ptr; ///< the pointer to the zone settings
|
||||
///< of the zone to edit
|
||||
bool m_isFpEditor;
|
||||
|
||||
bool TransferDataToWindow() override;
|
||||
bool TransferDataFromWindow() override;
|
||||
|
||||
void OnLayerSelection( wxDataViewEvent& event ) override;
|
||||
|
||||
private:
|
||||
UNIT_BINDER m_outlineHatchPitch;
|
||||
PCB_BASE_FRAME* m_parent;
|
||||
ZONE_SETTINGS m_zonesettings; ///< the working copy of zone settings
|
||||
ZONE_SETTINGS* m_ptr; ///< the pointer to the zone settings of the zone to edit
|
||||
bool m_isFpEditor;
|
||||
|
||||
CONVERT_SETTINGS* m_convertSettings;
|
||||
wxCheckBox* m_cbIgnoreLineWidths;
|
||||
wxCheckBox* m_cbDeleteOriginals;
|
||||
};
|
||||
|
||||
|
||||
int InvokeRuleAreaEditor( PCB_BASE_FRAME* aCaller, ZONE_SETTINGS* aSettings )
|
||||
int InvokeRuleAreaEditor( PCB_BASE_FRAME* aCaller, ZONE_SETTINGS* aZoneSettings,
|
||||
CONVERT_SETTINGS* aConvertSettings )
|
||||
{
|
||||
DIALOG_RULE_AREA_PROPERTIES dlg( aCaller, aSettings );
|
||||
DIALOG_RULE_AREA_PROPERTIES dlg( aCaller, aZoneSettings, aConvertSettings );
|
||||
|
||||
return dlg.ShowModal();
|
||||
}
|
||||
|
||||
|
||||
DIALOG_RULE_AREA_PROPERTIES::DIALOG_RULE_AREA_PROPERTIES( PCB_BASE_FRAME* aParent,
|
||||
ZONE_SETTINGS* aSettings ) :
|
||||
ZONE_SETTINGS* aSettings,
|
||||
CONVERT_SETTINGS* aConvertSettings ) :
|
||||
DIALOG_RULE_AREA_PROPERTIES_BASE( aParent ),
|
||||
m_outlineHatchPitch( aParent, m_stBorderHatchPitchText,
|
||||
m_outlineHatchPitchCtrl, m_outlineHatchUnits )
|
||||
m_outlineHatchPitchCtrl, m_outlineHatchUnits ),
|
||||
m_convertSettings( aConvertSettings )
|
||||
|
||||
{
|
||||
m_parent = aParent;
|
||||
|
@ -77,6 +86,31 @@ DIALOG_RULE_AREA_PROPERTIES::DIALOG_RULE_AREA_PROPERTIES( PCB_BASE_FRAME* aParen
|
|||
m_ptr = aSettings;
|
||||
m_zonesettings = *aSettings;
|
||||
|
||||
if( aConvertSettings )
|
||||
{
|
||||
wxBoxSizer* bConvertSizer = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
wxStaticText* conversionSettingsLabel = new wxStaticText( this, wxID_ANY,
|
||||
_( "Conversion settings:" ) );
|
||||
bConvertSizer->Add( conversionSettingsLabel, 0, wxLEFT|wxRIGHT|wxEXPAND, 5 );
|
||||
|
||||
m_cbIgnoreLineWidths = new wxCheckBox( this, wxID_ANY,
|
||||
_( "Ignore source object line widths" ) );
|
||||
bConvertSizer->Add( m_cbIgnoreLineWidths, 0, wxLEFT|wxRIGHT|wxTOP, 5 );
|
||||
|
||||
m_cbDeleteOriginals = new wxCheckBox( this, wxID_ANY,
|
||||
_( "Delete source objects after conversion" ) );
|
||||
bConvertSizer->Add( m_cbDeleteOriginals, 0, wxALL, 5 );
|
||||
|
||||
GetSizer()->Insert( 0, bConvertSizer, 0, wxALL|wxEXPAND, 10 );
|
||||
|
||||
wxStaticLine* line = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize,
|
||||
wxLI_HORIZONTAL );
|
||||
GetSizer()->Insert( 1, line, 0, wxLEFT|wxRIGHT|wxEXPAND, 10 );
|
||||
|
||||
SetTitle( _( "Convert to Rule Area" ) );
|
||||
}
|
||||
|
||||
m_isFpEditor = m_parent->IsType( FRAME_FOOTPRINT_EDITOR );
|
||||
|
||||
BOARD* board = m_parent->GetBoard();
|
||||
|
@ -92,6 +126,12 @@ DIALOG_RULE_AREA_PROPERTIES::DIALOG_RULE_AREA_PROPERTIES( PCB_BASE_FRAME* aParen
|
|||
|
||||
bool DIALOG_RULE_AREA_PROPERTIES::TransferDataToWindow()
|
||||
{
|
||||
if( m_convertSettings )
|
||||
{
|
||||
m_cbIgnoreLineWidths->SetValue( m_convertSettings->m_IgnoreLineWidths );
|
||||
m_cbDeleteOriginals->SetValue( m_convertSettings->m_DeleteOriginals );
|
||||
}
|
||||
|
||||
// Init keepout parameters:
|
||||
m_cbTracksCtrl->SetValue( m_zonesettings.GetDoNotAllowTracks() );
|
||||
m_cbViasCtrl->SetValue( m_zonesettings.GetDoNotAllowVias() );
|
||||
|
@ -147,6 +187,12 @@ void DIALOG_RULE_AREA_PROPERTIES::OnLayerSelection( wxDataViewEvent& event )
|
|||
|
||||
bool DIALOG_RULE_AREA_PROPERTIES::TransferDataFromWindow()
|
||||
{
|
||||
if( m_convertSettings )
|
||||
{
|
||||
m_convertSettings->m_IgnoreLineWidths = m_cbIgnoreLineWidths->GetValue();
|
||||
m_convertSettings->m_DeleteOriginals = m_cbDeleteOriginals->GetValue();
|
||||
}
|
||||
|
||||
// Init keepout parameters:
|
||||
m_zonesettings.SetIsRuleArea( true );
|
||||
m_zonesettings.SetDoNotAllowTracks( m_cbTracksCtrl->GetValue() );
|
||||
|
|
|
@ -31,6 +31,15 @@ namespace PNS
|
|||
}
|
||||
|
||||
|
||||
// Settings for the CONVERT_TOOL.
|
||||
struct CONVERT_SETTINGS
|
||||
{
|
||||
bool m_IgnoreLineWidths;
|
||||
bool m_DeleteOriginals;
|
||||
};
|
||||
|
||||
|
||||
|
||||
enum class MAGNETIC_OPTIONS
|
||||
{
|
||||
NO_EFFECT = 0,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* @author Jon Evans <jon@craftyjon.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
|
@ -23,6 +23,10 @@
|
|||
*/
|
||||
|
||||
#include <bitmaps.h>
|
||||
#include <dialog_shim.h>
|
||||
#include <wx/statline.h>
|
||||
#include <wx/checkbox.h>
|
||||
#include <wx/button.h>
|
||||
#include <board.h>
|
||||
#include <board_commit.h>
|
||||
#include <board_design_settings.h>
|
||||
|
@ -33,7 +37,6 @@
|
|||
#include <footprint_edit_frame.h>
|
||||
#include <fp_shape.h>
|
||||
#include <geometry/shape_compound.h>
|
||||
#include <menus_helpers.h>
|
||||
#include <pcb_edit_frame.h>
|
||||
#include <pcb_shape.h>
|
||||
#include <pcb_track.h>
|
||||
|
@ -47,6 +50,75 @@
|
|||
#include "convert_tool.h"
|
||||
|
||||
|
||||
class CONVERT_SETTINGS_DIALOG : public DIALOG_SHIM
|
||||
{
|
||||
public:
|
||||
CONVERT_SETTINGS_DIALOG( wxWindow* aParent, CONVERT_SETTINGS* aSettings ) :
|
||||
DIALOG_SHIM( aParent, wxID_ANY, _( "Conversion Settings" ), wxDefaultPosition,
|
||||
wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER ),
|
||||
m_settings( aSettings )
|
||||
{
|
||||
wxBoxSizer* mainSizer = new wxBoxSizer( wxVERTICAL );
|
||||
wxBoxSizer* topSizer = new wxBoxSizer( wxVERTICAL );
|
||||
SetSizer( mainSizer );
|
||||
|
||||
m_cbIgnoreLineWidths = new wxCheckBox( this, wxID_ANY,
|
||||
_( "Ignore source object line widths" ) );
|
||||
topSizer->Add( m_cbIgnoreLineWidths, 0, wxLEFT|wxRIGHT, 5 );
|
||||
|
||||
m_cbDeleteOriginals = new wxCheckBox( this, wxID_ANY,
|
||||
_( "Delete source objects after conversion" ) );
|
||||
topSizer->Add( m_cbDeleteOriginals, 0, wxALL, 5 );
|
||||
|
||||
wxStaticLine* line = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize,
|
||||
wxLI_HORIZONTAL );
|
||||
topSizer->Add( line, 0, wxLEFT|wxRIGHT|wxTOP|wxEXPAND, 5 );
|
||||
|
||||
mainSizer->Add( topSizer, 1, wxALL|wxEXPAND, 10 );
|
||||
|
||||
wxBoxSizer* buttonsSizer = new wxBoxSizer( wxHORIZONTAL );
|
||||
buttonsSizer->AddStretchSpacer();
|
||||
|
||||
wxStdDialogButtonSizer* sdbSizer = new wxStdDialogButtonSizer();
|
||||
wxButton* sdbSizerOK = new wxButton( this, wxID_OK );
|
||||
sdbSizer->AddButton( sdbSizerOK );
|
||||
wxButton* sdbSizerCancel = new wxButton( this, wxID_CANCEL );
|
||||
sdbSizer->AddButton( sdbSizerCancel );
|
||||
sdbSizer->Realize();
|
||||
|
||||
buttonsSizer->Add( sdbSizer, 1, 0, 5 );
|
||||
mainSizer->Add( buttonsSizer, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND, 5 );
|
||||
|
||||
SetupStandardButtons();
|
||||
|
||||
finishDialogSettings();
|
||||
}
|
||||
|
||||
~CONVERT_SETTINGS_DIALOG()
|
||||
{};
|
||||
|
||||
protected:
|
||||
bool TransferDataToWindow() override
|
||||
{
|
||||
m_cbIgnoreLineWidths->SetValue( m_settings->m_IgnoreLineWidths );
|
||||
m_cbDeleteOriginals->SetValue( m_settings->m_DeleteOriginals );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TransferDataFromWindow() override
|
||||
{
|
||||
m_settings->m_IgnoreLineWidths = m_cbIgnoreLineWidths->GetValue();
|
||||
m_settings->m_DeleteOriginals = m_cbDeleteOriginals->GetValue();
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
CONVERT_SETTINGS* m_settings;
|
||||
wxCheckBox* m_cbIgnoreLineWidths;
|
||||
wxCheckBox* m_cbDeleteOriginals;
|
||||
};
|
||||
|
||||
|
||||
CONVERT_TOOL::CONVERT_TOOL() :
|
||||
TOOL_INTERACTIVE( "pcbnew.Convert" ),
|
||||
m_selectionTool( nullptr ),
|
||||
|
@ -123,7 +195,12 @@ bool CONVERT_TOOL::Init()
|
|||
|
||||
int CONVERT_TOOL::CreatePolys( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
FOOTPRINT* parentFootprint = nullptr;
|
||||
std::vector<SHAPE_POLY_SET> polys;
|
||||
CONVERT_SETTINGS convertSettings;
|
||||
PCB_LAYER_ID destLayer = m_frame->GetActiveLayer();
|
||||
FOOTPRINT* parentFootprint = nullptr;
|
||||
bool foundChainedSegs = false;
|
||||
bool foundFilledShape = false;
|
||||
|
||||
PCB_SELECTION& selection = m_selectionTool->RequestSelection(
|
||||
[]( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
|
||||
|
@ -133,18 +210,57 @@ int CONVERT_TOOL::CreatePolys( const TOOL_EVENT& aEvent )
|
|||
if( selection.Empty() )
|
||||
return 0;
|
||||
|
||||
PCB_LAYER_ID destLayer = m_frame->GetActiveLayer();
|
||||
SHAPE_POLY_SET polySet;
|
||||
auto getPolys =
|
||||
[&]()
|
||||
{
|
||||
polys.clear();
|
||||
|
||||
if( !IsCopperLayer( destLayer ) )
|
||||
polySet = makePolysFromChainedSegs( selection.GetItems() );
|
||||
for( EDA_ITEM* item : selection )
|
||||
{
|
||||
item->ClearTempFlags();
|
||||
|
||||
polySet.Append( makePolysFromGraphics( selection.GetItems() ) );
|
||||
if( item->Type() == PCB_SHAPE_T || item->Type() == PCB_FP_SHAPE_T )
|
||||
foundFilledShape = static_cast<PCB_SHAPE*>( item )->IsFilled();
|
||||
}
|
||||
|
||||
if( polySet.IsEmpty() )
|
||||
SHAPE_POLY_SET polySet;
|
||||
|
||||
if( convertSettings.m_IgnoreLineWidths )
|
||||
{
|
||||
polySet.Append( makePolysFromChainedSegs( selection.GetItems() ) );
|
||||
foundChainedSegs = polySet.OutlineCount() > 0;
|
||||
}
|
||||
|
||||
polySet.Append( makePolysFromGraphics( selection.GetItems(),
|
||||
convertSettings.m_IgnoreLineWidths ) );
|
||||
|
||||
if( polySet.IsEmpty() )
|
||||
return false;
|
||||
|
||||
polySet.Simplify( SHAPE_POLY_SET::PM_FAST );
|
||||
|
||||
for( int ii = 0; ii < polySet.OutlineCount(); ++ii )
|
||||
{
|
||||
polys.emplace_back( SHAPE_POLY_SET( polySet.COutline( ii ) ) );
|
||||
|
||||
for( int jj = 0; jj < polySet.HoleCount( ii ); ++jj )
|
||||
polys.back().AddHole( polySet.Hole( ii, jj ) );
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
// Pre-flight getPolys(). If we find any chained segments then we default m_IgnoreLineWidths
|
||||
// to true.
|
||||
// We also use the pre-flight to keep from putting up any of the dialogs if there's nothing
|
||||
// to convert.
|
||||
convertSettings.m_IgnoreLineWidths = true;
|
||||
convertSettings.m_DeleteOriginals = false;
|
||||
|
||||
if( !getPolys() )
|
||||
return 0;
|
||||
|
||||
polySet.Simplify( SHAPE_POLY_SET::PM_FAST );
|
||||
convertSettings.m_IgnoreLineWidths = foundChainedSegs;
|
||||
|
||||
bool isFootprint = m_frame->IsType( FRAME_FOOTPRINT_EDITOR );
|
||||
|
||||
|
@ -160,33 +276,28 @@ int CONVERT_TOOL::CreatePolys( const TOOL_EVENT& aEvent )
|
|||
|
||||
BOARD_COMMIT commit( m_frame );
|
||||
|
||||
// For now, we convert each outline in the returned shape to its own polygon
|
||||
std::vector<SHAPE_POLY_SET> polys;
|
||||
|
||||
for( int ii = 0; ii < polySet.OutlineCount(); ++ii )
|
||||
{
|
||||
polys.emplace_back( SHAPE_POLY_SET( polySet.COutline( ii ) ) );
|
||||
|
||||
for( int jj = 0; jj < polySet.HoleCount( ii ); ++jj )
|
||||
polys.back().AddHole( polySet.Hole( ii, jj ) );
|
||||
}
|
||||
|
||||
if( aEvent.IsAction( &PCB_ACTIONS::convertToPoly ) )
|
||||
{
|
||||
CONVERT_SETTINGS_DIALOG dlg( m_frame, &convertSettings );
|
||||
|
||||
if( dlg.ShowModal() != wxID_OK )
|
||||
return 0;
|
||||
|
||||
if( !getPolys() )
|
||||
return 0;
|
||||
|
||||
for( const SHAPE_POLY_SET& poly : polys )
|
||||
{
|
||||
PCB_SHAPE* graphic = isFootprint ? new FP_SHAPE( parentFootprint ) : new PCB_SHAPE;
|
||||
|
||||
graphic->SetShape( SHAPE_T::POLY );
|
||||
graphic->SetFilled( false );
|
||||
graphic->SetStroke( STROKE_PARAMS( poly.Outline( 0 ).Width() ) );
|
||||
graphic->SetFilled( !convertSettings.m_IgnoreLineWidths || foundFilledShape );
|
||||
graphic->SetStroke( STROKE_PARAMS( 0, PLOT_DASH_TYPE::SOLID, COLOR4D::UNSPECIFIED ) );
|
||||
graphic->SetLayer( destLayer );
|
||||
graphic->SetPolyShape( poly );
|
||||
|
||||
commit.Add( graphic );
|
||||
}
|
||||
|
||||
commit.Push( _( "Convert shapes to polygon" ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -204,22 +315,25 @@ int CONVERT_TOOL::CreatePolys( const TOOL_EVENT& aEvent )
|
|||
if( aEvent.IsAction( &PCB_ACTIONS::convertToKeepout ) )
|
||||
{
|
||||
zoneInfo.SetIsRuleArea( true );
|
||||
ret = InvokeRuleAreaEditor( frame, &zoneInfo );
|
||||
ret = InvokeRuleAreaEditor( frame, &zoneInfo, &convertSettings );
|
||||
}
|
||||
else if( nonCopper )
|
||||
{
|
||||
zoneInfo.SetIsRuleArea( false );
|
||||
ret = InvokeNonCopperZonesEditor( frame, &zoneInfo );
|
||||
ret = InvokeNonCopperZonesEditor( frame, &zoneInfo, &convertSettings );
|
||||
}
|
||||
else
|
||||
{
|
||||
zoneInfo.SetIsRuleArea( false );
|
||||
ret = InvokeCopperZonesEditor( frame, &zoneInfo );
|
||||
ret = InvokeCopperZonesEditor( frame, &zoneInfo, &convertSettings );
|
||||
}
|
||||
|
||||
if( ret == wxID_CANCEL )
|
||||
return 0;
|
||||
|
||||
if( !getPolys() )
|
||||
return 0;
|
||||
|
||||
for( const SHAPE_POLY_SET& poly : polys )
|
||||
{
|
||||
ZONE* zone = isFootprint ? new FP_ZONE( parent ) : new ZONE( parent );
|
||||
|
@ -231,10 +345,22 @@ int CONVERT_TOOL::CreatePolys( const TOOL_EVENT& aEvent )
|
|||
|
||||
commit.Add( zone );
|
||||
}
|
||||
|
||||
commit.Push( _( "Convert shapes to zone" ) );
|
||||
}
|
||||
|
||||
if( convertSettings.m_DeleteOriginals )
|
||||
{
|
||||
for( EDA_ITEM* item : selection )
|
||||
{
|
||||
if( item->GetFlags() & SKIP_STRUCT )
|
||||
commit.Remove( item );
|
||||
}
|
||||
}
|
||||
|
||||
if( aEvent.IsAction( &PCB_ACTIONS::convertToPoly ) )
|
||||
commit.Push( _( "Convert shapes to polygon" ) );
|
||||
else
|
||||
commit.Push( _( "Convert shapes to zone" ) );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -410,7 +536,8 @@ SHAPE_POLY_SET CONVERT_TOOL::makePolysFromChainedSegs( const std::deque<EDA_ITEM
|
|||
}
|
||||
|
||||
|
||||
SHAPE_POLY_SET CONVERT_TOOL::makePolysFromGraphics( const std::deque<EDA_ITEM*>& aItems )
|
||||
SHAPE_POLY_SET CONVERT_TOOL::makePolysFromGraphics( const std::deque<EDA_ITEM*>& aItems,
|
||||
bool aIgnoreLineWidths )
|
||||
{
|
||||
BOARD_DESIGN_SETTINGS& bds = m_frame->GetBoard()->GetDesignSettings();
|
||||
SHAPE_POLY_SET poly;
|
||||
|
@ -425,16 +552,22 @@ SHAPE_POLY_SET CONVERT_TOOL::makePolysFromGraphics( const std::deque<EDA_ITEM*>&
|
|||
case PCB_SHAPE_T:
|
||||
case PCB_FP_SHAPE_T:
|
||||
{
|
||||
PCB_SHAPE* graphic = static_cast<PCB_SHAPE*>( item );
|
||||
PCB_SHAPE* temp = static_cast<PCB_SHAPE*>( item->Clone() );
|
||||
|
||||
graphic->TransformShapeWithClearanceToPolygon( poly, UNDEFINED_LAYER, 0,
|
||||
bds.m_MaxError, ERROR_INSIDE );
|
||||
if( aIgnoreLineWidths )
|
||||
temp->SetFilled( true );
|
||||
|
||||
temp->TransformShapeWithClearanceToPolygon( poly, UNDEFINED_LAYER, 0,
|
||||
bds.m_MaxError, ERROR_INSIDE,
|
||||
aIgnoreLineWidths );
|
||||
item->SetFlags( SKIP_STRUCT );
|
||||
break;
|
||||
}
|
||||
|
||||
case PCB_ZONE_T:
|
||||
case PCB_FP_ZONE_T:
|
||||
poly.Append( *static_cast<ZONE*>( item )->Outline() );
|
||||
item->SetFlags( SKIP_STRUCT );
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -90,7 +90,8 @@ private:
|
|||
* @param aItems is a list of items to process.
|
||||
* @return a #SHAPE_POLY_SET containing any polygons that were created.
|
||||
*/
|
||||
SHAPE_POLY_SET makePolysFromGraphics( const std::deque<EDA_ITEM*>& aItems );
|
||||
SHAPE_POLY_SET makePolysFromGraphics( const std::deque<EDA_ITEM*>& aItems,
|
||||
bool aIgnoreLineWidths );
|
||||
|
||||
PCB_SELECTION_TOOL* m_selectionTool;
|
||||
CONDITIONAL_MENU* m_menu;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2008-2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||
* Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -27,6 +27,8 @@
|
|||
|
||||
#include <wx/translation.h>
|
||||
|
||||
struct CONVERT_SETTINGS;
|
||||
|
||||
// Default values in mils for parameters in ZONE
|
||||
#define ZONE_THERMAL_RELIEF_GAP_MIL 20 // default value for ZONE_SETTINGS::m_ThermalReliefGap
|
||||
#define ZONE_THERMAL_RELIEF_COPPER_WIDTH_MIL 20 // default value for ZONE_SETTINGS::m_ThermalReliefCopperBridge
|
||||
|
@ -81,7 +83,8 @@ class PCB_BASE_FRAME;
|
|||
* @param aSettings points to the ZONE_SETTINGS to edit.
|
||||
* @return int - tells if user aborted, changed only one zone, or all of them.
|
||||
*/
|
||||
int InvokeNonCopperZonesEditor( PCB_BASE_FRAME* aParent, ZONE_SETTINGS* aSettings );
|
||||
int InvokeNonCopperZonesEditor( PCB_BASE_FRAME* aParent, ZONE_SETTINGS* aSettings,
|
||||
CONVERT_SETTINGS* aConvertSettings = nullptr );
|
||||
|
||||
/**
|
||||
* Function InvokeCopperZonesEditor
|
||||
|
@ -92,7 +95,8 @@ int InvokeNonCopperZonesEditor( PCB_BASE_FRAME* aParent, ZONE_SETTINGS* aSetting
|
|||
* @param aSettings points to the ZONE_SETTINGS to edit.
|
||||
* @return int - tells if user aborted, changed only one zone, or all of them.
|
||||
*/
|
||||
int InvokeCopperZonesEditor( PCB_BASE_FRAME* aCaller, ZONE_SETTINGS* aSettings );
|
||||
int InvokeCopperZonesEditor( PCB_BASE_FRAME* aCaller, ZONE_SETTINGS* aSettings,
|
||||
CONVERT_SETTINGS* aConvertSettings = nullptr );
|
||||
|
||||
/**
|
||||
* Function InvokeRuleAreaEditor
|
||||
|
@ -103,6 +107,7 @@ int InvokeCopperZonesEditor( PCB_BASE_FRAME* aCaller, ZONE_SETTINGS* aSettings )
|
|||
* @param aSettings points to the ZONE_SETTINGS to edit.
|
||||
* @return int - tells if user aborted, changed only one zone, or all of them.
|
||||
*/
|
||||
int InvokeRuleAreaEditor( PCB_BASE_FRAME* aCaller, ZONE_SETTINGS* aSettings );
|
||||
int InvokeRuleAreaEditor( PCB_BASE_FRAME* aCaller, ZONE_SETTINGS* aSettings,
|
||||
CONVERT_SETTINGS* aConvertSettings = nullptr );
|
||||
|
||||
#endif // ZONES_H_
|
||||
|
|
Loading…
Reference in New Issue