Add zone corner smoothing to pcbnew.
This commit is contained in:
parent
75f332aefc
commit
cbee247737
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include "protos.h"
|
||||
#include "richio.h"
|
||||
#include "class_zone_setting.h"
|
||||
|
||||
/************************/
|
||||
/* class ZONE_CONTAINER */
|
||||
|
@ -30,6 +31,9 @@ ZONE_CONTAINER::ZONE_CONTAINER( BOARD* parent ) :
|
|||
m_CornerSelection = -1;
|
||||
m_IsFilled = false; // fill status : true when the zone is filled
|
||||
m_FillMode = 0; // How to fill areas: 0 = use filled polygons, != 0 fill with segments
|
||||
smoothedPoly = NULL;
|
||||
cornerSmoothingType = ZONE_SETTING::SMOOTHING_NONE;
|
||||
cornerRadius = 0;
|
||||
utility = 0; // flags used in polygon calculations
|
||||
utility2 = 0; // flags used in polygon calculations
|
||||
m_Poly = new CPolyLine(); // Outlines
|
||||
|
@ -170,6 +174,11 @@ bool ZONE_CONTAINER::Save( FILE* aFile ) const
|
|||
if( ret < 3 )
|
||||
return false;
|
||||
|
||||
ret = fprintf( aFile,
|
||||
"ZSmoothing %d %d\n",
|
||||
cornerSmoothingType, cornerRadius );
|
||||
if( ret < 2 )
|
||||
return false;
|
||||
|
||||
// Save the corner list
|
||||
for( item_pos = 0; item_pos < corners_count; item_pos++ )
|
||||
|
@ -320,6 +329,25 @@ int ZONE_CONTAINER::ReadDescr( LINE_READER* aReader )
|
|||
}
|
||||
/* Set hatch mode later, after reading outlines corners data */
|
||||
}
|
||||
else if( strnicmp( Line, "ZSmoothing", 10 ) == 0 )
|
||||
{
|
||||
int tempSmoothingType;
|
||||
int tempCornerRadius;
|
||||
text = Line + 10;
|
||||
ret = sscanf( text, "%d %d", &tempSmoothingType, &tempCornerRadius );
|
||||
|
||||
if( ret < 2 )
|
||||
return false;
|
||||
|
||||
if( tempSmoothingType >= ZONE_SETTING::SMOOTHING_LAST)
|
||||
return false;
|
||||
|
||||
if( tempSmoothingType < 0 )
|
||||
return false;
|
||||
|
||||
cornerSmoothingType = tempSmoothingType;
|
||||
SetCornerRadius( tempCornerRadius );
|
||||
}
|
||||
else if( strnicmp( Line, "ZOptions", 8 ) == 0 ) // Options info found
|
||||
{
|
||||
int fillmode = 1;
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "gr_basic.h"
|
||||
#include "PolyLine.h"
|
||||
#include "richio.h"
|
||||
#include "class_zone_setting.h"
|
||||
|
||||
/* a small class used when filling areas with segments */
|
||||
class SEGMENT
|
||||
|
@ -61,7 +62,10 @@ public:
|
|||
* ( m_FillMode == 1 )
|
||||
* in this case segments have m_ZoneMinThickness width
|
||||
*/
|
||||
|
||||
private:
|
||||
CPolyLine* smoothedPoly; // Corner-smoothed version of m_Poly
|
||||
int cornerSmoothingType;
|
||||
unsigned int cornerRadius;
|
||||
public:
|
||||
ZONE_CONTAINER( BOARD* parent );
|
||||
~ZONE_CONTAINER();
|
||||
|
@ -366,6 +370,7 @@ public:
|
|||
{
|
||||
return m_Poly->GetHatchStyle();
|
||||
}
|
||||
|
||||
/**
|
||||
* Function IsSame
|
||||
* test is 2 zones are equivalent:
|
||||
|
@ -374,6 +379,35 @@ public:
|
|||
* @param aZoneToCompare = zone to compare with "this"
|
||||
*/
|
||||
bool IsSame( const ZONE_CONTAINER &aZoneToCompare);
|
||||
|
||||
/**
|
||||
* Function GetSmoothedPoly
|
||||
* returns a pointer to the corner-smoothed version of
|
||||
* m_Poly if it exists, otherwise it returns m_Poly.
|
||||
* @return CPolyLine* - pointer to the polygon.
|
||||
*/
|
||||
CPolyLine* GetSmoothedPoly() const
|
||||
{
|
||||
if( smoothedPoly )
|
||||
return smoothedPoly;
|
||||
else
|
||||
return m_Poly;
|
||||
};
|
||||
|
||||
void SetCornerSmoothingType( int aType ) { cornerSmoothingType = aType; };
|
||||
int GetCornerSmoothingType() const { return cornerSmoothingType; };
|
||||
|
||||
void SetCornerRadius( unsigned int aRadius )
|
||||
{
|
||||
if( aRadius > MAX_ZONE_CORNER_RADIUS )
|
||||
cornerRadius = MAX_ZONE_CORNER_RADIUS;
|
||||
else if( aRadius < 0 )
|
||||
cornerRadius = 0;
|
||||
else
|
||||
cornerRadius = aRadius;
|
||||
};
|
||||
|
||||
unsigned int GetCornerRadius() const { return cornerRadius; };
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -37,6 +37,9 @@ ZONE_SETTING::ZONE_SETTING( void )
|
|||
m_ThermalReliefCopperBridgeValue = 200; // tickness of the copper bridge in thermal reliefs
|
||||
|
||||
m_Zone_Pad_Options = THERMAL_PAD; // How pads are covered by copper in zone
|
||||
|
||||
cornerSmoothingType = SMOOTHING_NONE;
|
||||
cornerRadius = 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -57,6 +60,8 @@ void ZONE_SETTING::ImportSetting( const ZONE_CONTAINER& aSource )
|
|||
m_ThermalReliefGapValue = aSource.m_ThermalReliefGapValue;
|
||||
m_ThermalReliefCopperBridgeValue = aSource.m_ThermalReliefCopperBridgeValue;
|
||||
m_Zone_Pad_Options = aSource.m_PadOption;
|
||||
cornerSmoothingType = aSource.GetCornerSmoothingType();
|
||||
cornerRadius = aSource.GetCornerRadius();
|
||||
}
|
||||
|
||||
|
||||
|
@ -79,6 +84,8 @@ void ZONE_SETTING::ExportSetting( ZONE_CONTAINER& aTarget, bool aFullExport )
|
|||
aTarget.m_ThermalReliefGapValue = m_ThermalReliefGapValue;
|
||||
aTarget.m_ThermalReliefCopperBridgeValue = m_ThermalReliefCopperBridgeValue;
|
||||
aTarget.m_PadOption = m_Zone_Pad_Options;
|
||||
aTarget.SetCornerSmoothingType( cornerSmoothingType );
|
||||
aTarget.SetCornerRadius( cornerRadius );
|
||||
if( aFullExport )
|
||||
{
|
||||
aTarget.SetNet( m_NetcodeSelection );
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#ifndef ZONE_SETTING_H
|
||||
#define ZONE_SETTING_H
|
||||
|
||||
#define MAX_ZONE_CORNER_RADIUS 4000
|
||||
|
||||
/*************************************************/
|
||||
/* Class ZONE_SETTING to handle zones parameters */
|
||||
|
@ -12,6 +13,12 @@
|
|||
class ZONE_SETTING
|
||||
{
|
||||
public:
|
||||
enum {
|
||||
SMOOTHING_NONE,
|
||||
SMOOTHING_CHAMFER,
|
||||
SMOOTHING_FILLET,
|
||||
SMOOTHING_LAST
|
||||
};
|
||||
int m_FillMode; // Mode for filling zone : 1 use segments, 0 use polygons
|
||||
int m_ZoneClearance; // Clearance value
|
||||
int m_ZoneMinThickness; // Min thickness value in filled areas
|
||||
|
@ -23,6 +30,9 @@ public:
|
|||
long m_ThermalReliefGapValue; // tickness of the gap in thermal reliefs
|
||||
long m_ThermalReliefCopperBridgeValue; // tickness of the copper bridge in thermal reliefs
|
||||
int m_Zone_Pad_Options; // How pads are covered by copper in zone
|
||||
private:
|
||||
int cornerSmoothingType; // Corner smoothing type
|
||||
unsigned int cornerRadius; // Corner chamfer distance / fillet radius
|
||||
public:
|
||||
ZONE_SETTING( void );
|
||||
|
||||
|
@ -43,6 +53,19 @@ public:
|
|||
* m_NetcodeSelection
|
||||
*/
|
||||
void ExportSetting( ZONE_CONTAINER& aTarget, bool aFullExport = true);
|
||||
|
||||
void SetCornerSmoothingType( int aType) { cornerSmoothingType = aType; };
|
||||
int GetCornerSmoothingType() const { return cornerSmoothingType; };
|
||||
void SetCornerRadius( int aRadius )
|
||||
{
|
||||
if( aRadius > MAX_ZONE_CORNER_RADIUS )
|
||||
cornerRadius = MAX_ZONE_CORNER_RADIUS;
|
||||
else if( aRadius < 0 )
|
||||
cornerRadius = 0;
|
||||
else
|
||||
cornerRadius = aRadius;
|
||||
};
|
||||
unsigned int GetCornerRadius() const { return cornerRadius; };
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "zones.h"
|
||||
|
||||
#include "dialog_copper_zones.h"
|
||||
#include "class_zone_setting.h"
|
||||
|
||||
#define LAYER_BITMAP_SIZE_X 20
|
||||
#define LAYER_BITMAP_SIZE_Y 10
|
||||
|
@ -124,6 +125,13 @@ void dialog_copper_zone::initDialog()
|
|||
m_Zone_Setting->m_ThermalReliefCopperBridgeValue,
|
||||
PCB_INTERNAL_UNIT );
|
||||
|
||||
m_cornerSmoothingChoice->SetSelection( m_Zone_Setting->GetCornerSmoothingType() );
|
||||
|
||||
AddUnitSymbol( *m_cornerSmoothingTitle, g_UserUnit );
|
||||
PutValueInLocalUnits( *m_cornerSmoothingCtrl,
|
||||
m_Zone_Setting->GetCornerRadius(),
|
||||
PCB_INTERNAL_UNIT );
|
||||
|
||||
switch( m_Zone_Setting->m_Zone_HatchingStyle )
|
||||
{
|
||||
case CPolyLine::NO_HATCH:
|
||||
|
@ -186,6 +194,9 @@ void dialog_copper_zone::initDialog()
|
|||
// Build list of nets:
|
||||
m_DoNotShowNetNameFilter->SetValue( netNameDoNotShowFilter );
|
||||
buildAvailableListOfNets();
|
||||
|
||||
wxCommandEvent event;
|
||||
OnCornerSmoothingModeChoice( event );
|
||||
}
|
||||
|
||||
|
||||
|
@ -203,6 +214,35 @@ void dialog_copper_zone::OnClose( wxCloseEvent& event )
|
|||
}
|
||||
|
||||
|
||||
void dialog_copper_zone::OnCornerSmoothingModeChoice( wxCommandEvent& event )
|
||||
{
|
||||
int selection = m_cornerSmoothingChoice->GetSelection();
|
||||
|
||||
switch( selection )
|
||||
{
|
||||
case ZONE_SETTING::SMOOTHING_NONE:
|
||||
m_cornerSmoothingTitle->Enable( false );
|
||||
m_cornerSmoothingCtrl->Enable( false );
|
||||
break;
|
||||
case ZONE_SETTING::SMOOTHING_CHAMFER:
|
||||
m_cornerSmoothingTitle->Enable( true );
|
||||
m_cornerSmoothingCtrl->Enable( true );
|
||||
m_cornerSmoothingTitle->SetLabel( wxT( "Chamfer distance" ) );
|
||||
AddUnitSymbol( *m_cornerSmoothingTitle, g_UserUnit );
|
||||
break;
|
||||
case ZONE_SETTING::SMOOTHING_FILLET:
|
||||
m_cornerSmoothingTitle->Enable( true );
|
||||
m_cornerSmoothingCtrl->Enable( true );
|
||||
m_cornerSmoothingTitle->SetLabel( wxT( "Fillet radius" ) );
|
||||
AddUnitSymbol( *m_cornerSmoothingTitle, g_UserUnit );
|
||||
break;
|
||||
}
|
||||
|
||||
Layout();
|
||||
m_MainBoxSizer->SetSizeHints( this );
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************************************/
|
||||
bool dialog_copper_zone::AcceptOptions( bool aPromptForErrors, bool aUseExportableSetupOnly )
|
||||
/********************************************************************************************/
|
||||
|
@ -282,6 +322,10 @@ bool dialog_copper_zone::AcceptOptions( bool aPromptForErrors, bool aUseExportab
|
|||
return false;
|
||||
}
|
||||
|
||||
m_Zone_Setting->SetCornerSmoothingType( m_cornerSmoothingChoice->GetSelection() );
|
||||
txtvalue = m_cornerSmoothingCtrl->GetValue();
|
||||
m_Zone_Setting->SetCornerRadius( ReturnValueFromString( g_UserUnit, txtvalue, m_Parent->m_InternalUnits ) );
|
||||
|
||||
if( m_OrientEdgesOpt->GetSelection() == 0 )
|
||||
g_Zone_45_Only = FALSE;
|
||||
else
|
||||
|
@ -493,6 +537,7 @@ void dialog_copper_zone::buildAvailableListOfNets()
|
|||
m_ListNetNameSelection->Clear();
|
||||
listNetName.Insert( wxT( "<no net>" ), 0 );
|
||||
m_ListNetNameSelection->InsertItems( listNetName, 0 );
|
||||
m_ListNetNameSelection->SetSelection( 0 );
|
||||
|
||||
// Ensure current select net for the zone is visible:
|
||||
int net_select = m_Zone_Setting->m_NetcodeSelection;
|
||||
|
|
|
@ -38,6 +38,7 @@ private:
|
|||
void OnButtonOkClick( wxCommandEvent& event );
|
||||
void OnButtonCancelClick( wxCommandEvent& event );
|
||||
void OnClose( wxCloseEvent& event );
|
||||
void OnCornerSmoothingModeChoice( wxCommandEvent& event );
|
||||
bool AcceptOptions( bool aPromptForErrors, bool aUseExportableSetupOnly = false );
|
||||
void OnNetSortingOptionSelected( wxCommandEvent& event );
|
||||
void ExportSetupToOtherCopperZones( wxCommandEvent& event );
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version Sep 8 2010)
|
||||
// C++ code generated with wxFormBuilder (version Nov 18 2010)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO "NOT" EDIT THIS FILE!
|
||||
|
@ -15,6 +15,7 @@ BEGIN_EVENT_TABLE( dialog_copper_zone_base, wxDialog )
|
|||
EVT_TEXT_ENTER( ID_TEXTCTRL_NETNAMES_FILTER, dialog_copper_zone_base::_wxFB_OnRunFiltersButtonClick )
|
||||
EVT_TEXT_ENTER( ID_TEXTCTRL_NETNAMES_FILTER, dialog_copper_zone_base::_wxFB_OnRunFiltersButtonClick )
|
||||
EVT_BUTTON( wxID_APPLY_FILTERS, dialog_copper_zone_base::_wxFB_OnRunFiltersButtonClick )
|
||||
EVT_CHOICE( wxID_ANY, dialog_copper_zone_base::_wxFB_OnCornerSmoothingModeChoice )
|
||||
EVT_CHOICE( ID_M_PADINZONEOPT, dialog_copper_zone_base::_wxFB_OnPadsInZoneClick )
|
||||
EVT_BUTTON( wxID_BUTTON_EXPORT, dialog_copper_zone_base::_wxFB_ExportSetupToOtherCopperZones )
|
||||
EVT_BUTTON( wxID_OK, dialog_copper_zone_base::_wxFB_OnButtonOkClick )
|
||||
|
@ -25,8 +26,7 @@ dialog_copper_zone_base::dialog_copper_zone_base( wxWindow* parent, wxWindowID i
|
|||
{
|
||||
this->SetSizeHints( wxDefaultSize, wxDefaultSize );
|
||||
|
||||
wxBoxSizer* m_MainBoxSize;
|
||||
m_MainBoxSize = new wxBoxSizer( wxVERTICAL );
|
||||
m_MainBoxSizer = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
wxBoxSizer* m_OptionsBoxSizer;
|
||||
m_OptionsBoxSizer = new wxBoxSizer( wxHORIZONTAL );
|
||||
|
@ -87,7 +87,7 @@ dialog_copper_zone_base::dialog_copper_zone_base( wxWindow* parent, wxWindowID i
|
|||
|
||||
m_OptionsBoxSizer->Add( m_NetSortOptSizer, 0, wxALL, 5 );
|
||||
|
||||
m_MainBoxSize->Add( m_OptionsBoxSizer, 1, wxALL|wxEXPAND, 5 );
|
||||
m_MainBoxSizer->Add( m_OptionsBoxSizer, 1, wxALL|wxEXPAND, 5 );
|
||||
|
||||
wxStaticBoxSizer* m_ExportableSetupSizer;
|
||||
m_ExportableSetupSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Settings") ), wxHORIZONTAL );
|
||||
|
@ -113,28 +113,20 @@ dialog_copper_zone_base::dialog_copper_zone_base( wxWindow* parent, wxWindowID i
|
|||
|
||||
m_staticText151 = new wxStaticText( this, wxID_ANY, _("Corner smoothing:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticText151->Wrap( -1 );
|
||||
m_staticText151->Enable( false );
|
||||
|
||||
bSizer9->Add( m_staticText151, 0, wxLEFT|wxRIGHT|wxTOP, 5 );
|
||||
|
||||
wxString m_choice7Choices[] = { _("None") };
|
||||
int m_choice7NChoices = sizeof( m_choice7Choices ) / sizeof( wxString );
|
||||
m_choice7 = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choice7NChoices, m_choice7Choices, 0 );
|
||||
m_choice7->SetSelection( 0 );
|
||||
m_choice7->Enable( false );
|
||||
wxString m_cornerSmoothingChoiceChoices[] = { _("None"), _("Chamfer"), _("Fillet") };
|
||||
int m_cornerSmoothingChoiceNChoices = sizeof( m_cornerSmoothingChoiceChoices ) / sizeof( wxString );
|
||||
m_cornerSmoothingChoice = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_cornerSmoothingChoiceNChoices, m_cornerSmoothingChoiceChoices, 0 );
|
||||
m_cornerSmoothingChoice->SetSelection( 0 );
|
||||
bSizer9->Add( m_cornerSmoothingChoice, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 );
|
||||
|
||||
bSizer9->Add( m_choice7, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 );
|
||||
m_cornerSmoothingTitle = new wxStaticText( this, wxID_ANY, _("Chamfer distance (mm):"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_cornerSmoothingTitle->Wrap( -1 );
|
||||
bSizer9->Add( m_cornerSmoothingTitle, 0, wxLEFT|wxRIGHT|wxTOP, 5 );
|
||||
|
||||
m_staticText161 = new wxStaticText( this, wxID_ANY, _("Chamfer distance (mm):"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticText161->Wrap( -1 );
|
||||
m_staticText161->Enable( false );
|
||||
|
||||
bSizer9->Add( m_staticText161, 0, wxLEFT|wxRIGHT|wxTOP, 5 );
|
||||
|
||||
m_textCtrl7 = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_textCtrl7->Enable( false );
|
||||
|
||||
bSizer9->Add( m_textCtrl7, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 );
|
||||
m_cornerSmoothingCtrl = new wxTextCtrl( this, ID_M_CORNERSMOOTHINGCTRL, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
bSizer9->Add( m_cornerSmoothingCtrl, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 );
|
||||
|
||||
m_ExportableSetupSizer->Add( bSizer9, 0, wxEXPAND, 5 );
|
||||
|
||||
|
@ -226,7 +218,7 @@ dialog_copper_zone_base::dialog_copper_zone_base( wxWindow* parent, wxWindowID i
|
|||
|
||||
m_ExportableSetupSizer->Add( bSizer81, 0, wxEXPAND, 5 );
|
||||
|
||||
m_MainBoxSize->Add( m_ExportableSetupSizer, 1, wxALL|wxEXPAND, 5 );
|
||||
m_MainBoxSizer->Add( m_ExportableSetupSizer, 1, wxALL|wxEXPAND, 5 );
|
||||
|
||||
wxBoxSizer* bSizer10;
|
||||
bSizer10 = new wxBoxSizer( wxHORIZONTAL );
|
||||
|
@ -243,9 +235,9 @@ dialog_copper_zone_base::dialog_copper_zone_base( wxWindow* parent, wxWindowID i
|
|||
m_ButtonCancel = new wxButton( this, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
bSizer10->Add( m_ButtonCancel, 0, wxALL|wxEXPAND, 5 );
|
||||
|
||||
m_MainBoxSize->Add( bSizer10, 0, wxALIGN_RIGHT|wxALL, 5 );
|
||||
m_MainBoxSizer->Add( bSizer10, 0, wxALIGN_RIGHT|wxALL, 5 );
|
||||
|
||||
this->SetSizer( m_MainBoxSize );
|
||||
this->SetSizer( m_MainBoxSizer );
|
||||
this->Layout();
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,5 +1,5 @@
|
|||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version Sep 8 2010)
|
||||
// C++ code generated with wxFormBuilder (version Nov 18 2010)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO "NOT" EDIT THIS FILE!
|
||||
|
@ -38,6 +38,7 @@ class dialog_copper_zone_base : public wxDialog
|
|||
void _wxFB_OnClose( wxCloseEvent& event ){ OnClose( event ); }
|
||||
void _wxFB_OnNetSortingOptionSelected( wxCommandEvent& event ){ OnNetSortingOptionSelected( event ); }
|
||||
void _wxFB_OnRunFiltersButtonClick( wxCommandEvent& event ){ OnRunFiltersButtonClick( event ); }
|
||||
void _wxFB_OnCornerSmoothingModeChoice( wxCommandEvent& event ){ OnCornerSmoothingModeChoice( event ); }
|
||||
void _wxFB_OnPadsInZoneClick( wxCommandEvent& event ){ OnPadsInZoneClick( event ); }
|
||||
void _wxFB_ExportSetupToOtherCopperZones( wxCommandEvent& event ){ ExportSetupToOtherCopperZones( event ); }
|
||||
void _wxFB_OnButtonOkClick( wxCommandEvent& event ){ OnButtonOkClick( event ); }
|
||||
|
@ -51,6 +52,7 @@ class dialog_copper_zone_base : public wxDialog
|
|||
ID_M_NETDISPLAYOPTION,
|
||||
ID_TEXTCTRL_NETNAMES_FILTER,
|
||||
wxID_APPLY_FILTERS,
|
||||
ID_M_CORNERSMOOTHINGCTRL,
|
||||
ID_M_PADINZONEOPT,
|
||||
wxID_ANTIPAD_SIZE,
|
||||
wxID_COPPER_BRIDGE_VALUE,
|
||||
|
@ -61,6 +63,7 @@ class dialog_copper_zone_base : public wxDialog
|
|||
wxID_BUTTON_EXPORT,
|
||||
};
|
||||
|
||||
wxBoxSizer* m_MainBoxSizer;
|
||||
wxBoxSizer* m_layerSizer;
|
||||
wxStaticText* m_staticText17;
|
||||
wxStaticText* m_staticText2;
|
||||
|
@ -77,9 +80,9 @@ class dialog_copper_zone_base : public wxDialog
|
|||
wxStaticText* m_MinThicknessValueTitle;
|
||||
wxTextCtrl* m_ZoneMinThicknessCtrl;
|
||||
wxStaticText* m_staticText151;
|
||||
wxChoice* m_choice7;
|
||||
wxStaticText* m_staticText161;
|
||||
wxTextCtrl* m_textCtrl7;
|
||||
wxChoice* m_cornerSmoothingChoice;
|
||||
wxStaticText* m_cornerSmoothingTitle;
|
||||
wxTextCtrl* m_cornerSmoothingCtrl;
|
||||
wxStaticText* m_staticText13;
|
||||
wxChoice* m_PadInZoneOpt;
|
||||
wxStaticText* m_AntipadSizeText;
|
||||
|
@ -102,6 +105,7 @@ class dialog_copper_zone_base : public wxDialog
|
|||
virtual void OnClose( wxCloseEvent& event ) { event.Skip(); }
|
||||
virtual void OnNetSortingOptionSelected( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnRunFiltersButtonClick( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnCornerSmoothingModeChoice( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnPadsInZoneClick( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void ExportSetupToOtherCopperZones( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnButtonOkClick( wxCommandEvent& event ) { event.Skip(); }
|
||||
|
|
|
@ -43,15 +43,35 @@ int ZONE_CONTAINER::BuildFilledPolysListData( BOARD* aPcb )
|
|||
if( GetNumCorners() <= 2 ) // malformed zone. Kbool does not like it ...
|
||||
return 0;
|
||||
|
||||
m_Poly->MakeKboolPoly( -1, -1, NULL, true );
|
||||
// Make a smoothed polygon out of the user-drawn polygon if required
|
||||
if( smoothedPoly ) {
|
||||
delete smoothedPoly;
|
||||
smoothedPoly = NULL;
|
||||
}
|
||||
|
||||
switch( cornerSmoothingType )
|
||||
{
|
||||
case ZONE_SETTING::SMOOTHING_CHAMFER:
|
||||
smoothedPoly = m_Poly->Chamfer( cornerRadius );
|
||||
break;
|
||||
case ZONE_SETTING::SMOOTHING_FILLET:
|
||||
smoothedPoly = m_Poly->Fillet( cornerRadius, m_ArcToSegmentsCount );
|
||||
break;
|
||||
default:
|
||||
smoothedPoly = new CPolyLine;
|
||||
smoothedPoly->Copy( m_Poly );
|
||||
break;
|
||||
}
|
||||
|
||||
smoothedPoly->MakeKboolPoly( -1, -1, NULL, true );
|
||||
int count = 0;
|
||||
while( m_Poly->GetKboolEngine()->StartPolygonGet() )
|
||||
while( smoothedPoly->GetKboolEngine()->StartPolygonGet() )
|
||||
{
|
||||
CPolyPt corner( 0, 0, false );
|
||||
while( m_Poly->GetKboolEngine()->PolygonHasMorePoints() )
|
||||
while( smoothedPoly->GetKboolEngine()->PolygonHasMorePoints() )
|
||||
{
|
||||
corner.x = (int) m_Poly->GetKboolEngine()->GetPolygonXPoint();
|
||||
corner.y = (int) m_Poly->GetKboolEngine()->GetPolygonYPoint();
|
||||
corner.x = (int) smoothedPoly->GetKboolEngine()->GetPolygonXPoint();
|
||||
corner.y = (int) smoothedPoly->GetKboolEngine()->GetPolygonYPoint();
|
||||
corner.end_contour = false;
|
||||
m_FilledPolysList.push_back( corner );
|
||||
count++;
|
||||
|
@ -60,10 +80,10 @@ int ZONE_CONTAINER::BuildFilledPolysListData( BOARD* aPcb )
|
|||
corner.end_contour = true;
|
||||
m_FilledPolysList.pop_back();
|
||||
m_FilledPolysList.push_back( corner );
|
||||
m_Poly->GetKboolEngine()->EndPolygonGet();
|
||||
smoothedPoly->GetKboolEngine()->EndPolygonGet();
|
||||
}
|
||||
|
||||
m_Poly->FreeKboolEngine();
|
||||
smoothedPoly->FreeKboolEngine();
|
||||
|
||||
/* For copper layers, we now must add holes in the Polygon list.
|
||||
* holes are pads and tracks with their clearance area
|
||||
|
|
|
@ -854,6 +854,8 @@ int BOARD::Test_Drc_Areas_Outlines_To_Areas_Outlines( ZONE_CONTAINER* aArea_To_E
|
|||
for( int ia = 0; ia < GetAreaCount(); ia++ )
|
||||
{
|
||||
ZONE_CONTAINER* Area_Ref = GetArea( ia );
|
||||
CPolyLine* refSmoothedPoly = Area_Ref->GetSmoothedPoly();
|
||||
|
||||
if( !Area_Ref->IsOnCopperLayer() )
|
||||
continue;
|
||||
|
||||
|
@ -863,6 +865,7 @@ int BOARD::Test_Drc_Areas_Outlines_To_Areas_Outlines( ZONE_CONTAINER* aArea_To_E
|
|||
for( int ia2 = 0; ia2 < GetAreaCount(); ia2++ )
|
||||
{
|
||||
ZONE_CONTAINER* Area_To_Test = GetArea( ia2 );
|
||||
CPolyLine* testSmoothedPoly = Area_To_Test->GetSmoothedPoly();
|
||||
|
||||
if( Area_Ref == Area_To_Test )
|
||||
continue;
|
||||
|
@ -884,11 +887,11 @@ int BOARD::Test_Drc_Areas_Outlines_To_Areas_Outlines( ZONE_CONTAINER* aArea_To_E
|
|||
zone2zoneClearance = MAX( zone2zoneClearance, Area_To_Test->m_ZoneClearance );
|
||||
|
||||
// test for some corners of Area_Ref inside Area_To_Test
|
||||
for( int ic = 0; ic < Area_Ref->m_Poly->GetNumCorners(); ic++ )
|
||||
for( int ic = 0; ic < refSmoothedPoly->GetNumCorners(); ic++ )
|
||||
{
|
||||
int x = Area_Ref->m_Poly->GetX( ic );
|
||||
int y = Area_Ref->m_Poly->GetY( ic );
|
||||
if( Area_To_Test->m_Poly->TestPointInside( x, y ) )
|
||||
int x = refSmoothedPoly->GetX( ic );
|
||||
int y = refSmoothedPoly->GetY( ic );
|
||||
if( testSmoothedPoly->TestPointInside( x, y ) )
|
||||
{
|
||||
// COPPERAREA_COPPERAREA error: copper area ref corner inside copper area
|
||||
if( aCreate_Markers )
|
||||
|
@ -905,11 +908,11 @@ int BOARD::Test_Drc_Areas_Outlines_To_Areas_Outlines( ZONE_CONTAINER* aArea_To_E
|
|||
}
|
||||
|
||||
// test for some corners of Area_To_Test inside Area_Ref
|
||||
for( int ic2 = 0; ic2 < Area_To_Test->m_Poly->GetNumCorners(); ic2++ )
|
||||
for( int ic2 = 0; ic2 < testSmoothedPoly->GetNumCorners(); ic2++ )
|
||||
{
|
||||
int x = Area_To_Test->m_Poly->GetX( ic2 );
|
||||
int y = Area_To_Test->m_Poly->GetY( ic2 );
|
||||
if( Area_Ref->m_Poly->TestPointInside( x, y ) )
|
||||
int x = testSmoothedPoly->GetX( ic2 );
|
||||
int y = testSmoothedPoly->GetY( ic2 );
|
||||
if( refSmoothedPoly->TestPointInside( x, y ) )
|
||||
{
|
||||
// COPPERAREA_COPPERAREA error: copper area corner inside copper area ref
|
||||
if( aCreate_Markers )
|
||||
|
@ -926,46 +929,46 @@ int BOARD::Test_Drc_Areas_Outlines_To_Areas_Outlines( ZONE_CONTAINER* aArea_To_E
|
|||
}
|
||||
|
||||
// now test spacing between areas
|
||||
for( int icont = 0; icont < Area_Ref->m_Poly->GetNumContours(); icont++ )
|
||||
for( int icont = 0; icont < refSmoothedPoly->GetNumContours(); icont++ )
|
||||
{
|
||||
int ic_start = Area_Ref->m_Poly->GetContourStart( icont );
|
||||
int ic_end = Area_Ref->m_Poly->GetContourEnd( icont );
|
||||
int ic_start = refSmoothedPoly->GetContourStart( icont );
|
||||
int ic_end = refSmoothedPoly->GetContourEnd( icont );
|
||||
for( int ic = ic_start; ic<=ic_end; ic++ )
|
||||
{
|
||||
int ax1 = Area_Ref->m_Poly->GetX( ic );
|
||||
int ay1 = Area_Ref->m_Poly->GetY( ic );
|
||||
int ax1 = refSmoothedPoly->GetX( ic );
|
||||
int ay1 = refSmoothedPoly->GetY( ic );
|
||||
int ax2, ay2;
|
||||
if( ic == ic_end )
|
||||
{
|
||||
ax2 = Area_Ref->m_Poly->GetX( ic_start );
|
||||
ay2 = Area_Ref->m_Poly->GetY( ic_start );
|
||||
ax2 = refSmoothedPoly->GetX( ic_start );
|
||||
ay2 = refSmoothedPoly->GetY( ic_start );
|
||||
}
|
||||
else
|
||||
{
|
||||
ax2 = Area_Ref->m_Poly->GetX( ic + 1 );
|
||||
ay2 = Area_Ref->m_Poly->GetY( ic + 1 );
|
||||
ax2 = refSmoothedPoly->GetX( ic + 1 );
|
||||
ay2 = refSmoothedPoly->GetY( ic + 1 );
|
||||
}
|
||||
int astyle = Area_Ref->m_Poly->GetSideStyle( ic );
|
||||
for( int icont2 = 0; icont2 < Area_To_Test->m_Poly->GetNumContours(); icont2++ )
|
||||
int astyle = refSmoothedPoly->GetSideStyle( ic );
|
||||
for( int icont2 = 0; icont2 < testSmoothedPoly->GetNumContours(); icont2++ )
|
||||
{
|
||||
int ic_start2 = Area_To_Test->m_Poly->GetContourStart( icont2 );
|
||||
int ic_end2 = Area_To_Test->m_Poly->GetContourEnd( icont2 );
|
||||
int ic_start2 = testSmoothedPoly->GetContourStart( icont2 );
|
||||
int ic_end2 = testSmoothedPoly->GetContourEnd( icont2 );
|
||||
for( int ic2 = ic_start2; ic2<=ic_end2; ic2++ )
|
||||
{
|
||||
int bx1 = Area_To_Test->m_Poly->GetX( ic2 );
|
||||
int by1 = Area_To_Test->m_Poly->GetY( ic2 );
|
||||
int bx1 = testSmoothedPoly->GetX( ic2 );
|
||||
int by1 = testSmoothedPoly->GetY( ic2 );
|
||||
int bx2, by2;
|
||||
if( ic2 == ic_end2 )
|
||||
{
|
||||
bx2 = Area_To_Test->m_Poly->GetX( ic_start2 );
|
||||
by2 = Area_To_Test->m_Poly->GetY( ic_start2 );
|
||||
bx2 = testSmoothedPoly->GetX( ic_start2 );
|
||||
by2 = testSmoothedPoly->GetY( ic_start2 );
|
||||
}
|
||||
else
|
||||
{
|
||||
bx2 = Area_To_Test->m_Poly->GetX( ic2 + 1 );
|
||||
by2 = Area_To_Test->m_Poly->GetY( ic2 + 1 );
|
||||
bx2 = testSmoothedPoly->GetX( ic2 + 1 );
|
||||
by2 = testSmoothedPoly->GetY( ic2 + 1 );
|
||||
}
|
||||
int bstyle = Area_To_Test->m_Poly->GetSideStyle( ic2 );
|
||||
int bstyle = testSmoothedPoly->GetSideStyle( ic2 );
|
||||
int x, y;
|
||||
|
||||
int d = GetClearanceBetweenSegments(
|
||||
|
|
|
@ -907,6 +907,215 @@ void CPolyLine::RemoveContour( int icont )
|
|||
}
|
||||
|
||||
|
||||
int CPolyLine::Chamfer( unsigned int aIndex, unsigned int aDistance )
|
||||
{
|
||||
int x1, y1;
|
||||
long xa, ya, xb, yb, nx, ny;
|
||||
|
||||
if( !aDistance )
|
||||
return 0;
|
||||
|
||||
x1 = corner[aIndex].x;
|
||||
y1 = corner[aIndex].y;
|
||||
|
||||
if( aIndex == 0 )
|
||||
{
|
||||
xa = corner[corner.size()-1].x - x1;
|
||||
ya = corner[corner.size()-1].y - y1;
|
||||
}
|
||||
else
|
||||
{
|
||||
xa = corner[aIndex-1].x - x1;
|
||||
ya = corner[aIndex-1].y - y1;
|
||||
}
|
||||
|
||||
if( aIndex == corner.size()-1 )
|
||||
{
|
||||
xb = corner[0].x - x1;
|
||||
yb = corner[0].y - y1;
|
||||
}
|
||||
else
|
||||
{
|
||||
xb = corner[aIndex+1].x - x1;
|
||||
yb = corner[aIndex+1].y - y1;
|
||||
}
|
||||
|
||||
// Move the first vertex into new position
|
||||
nx = (long)aDistance*xa/sqrt( xa*xa + ya*ya );
|
||||
ny = (long)aDistance*ya/sqrt( xa*xa + ya*ya );
|
||||
corner[aIndex].x = x1 + nx;
|
||||
corner[aIndex].y = y1 + ny;
|
||||
|
||||
// Add one new vertex
|
||||
nx = (long)aDistance*xb/sqrt( xb*xb + yb*yb );
|
||||
ny = (long)aDistance*yb/sqrt( xb*xb + yb*yb );
|
||||
InsertCorner( aIndex, x1 + nx, y1 + ny );
|
||||
|
||||
return 1; // Added one vertex
|
||||
}
|
||||
|
||||
|
||||
CPolyLine* CPolyLine::Chamfer( unsigned int aDistance )
|
||||
{
|
||||
CPolyLine* newPoly = new CPolyLine;
|
||||
unsigned int lena, lenb;
|
||||
newPoly->Copy( this );
|
||||
|
||||
for( unsigned int i = 0, index = 0; i < corner.size(); i++, index++ )
|
||||
{
|
||||
if( i == 0 )
|
||||
lena = GetEdgeLength( corner.size()-1 );
|
||||
else
|
||||
lena = GetEdgeLength( i - 1 );
|
||||
lenb = GetEdgeLength( i );
|
||||
|
||||
unsigned int distance = aDistance;
|
||||
|
||||
// Chamfer one half of an edge at most
|
||||
if( 0.5*lena < distance )
|
||||
distance = 0.5*lena;
|
||||
|
||||
if( 0.5*lenb < distance )
|
||||
distance = 0.5*lenb;
|
||||
|
||||
// Chamfer this corner and keep tract of added vertices
|
||||
index += newPoly->Chamfer( index, distance );
|
||||
}
|
||||
|
||||
return newPoly;
|
||||
}
|
||||
|
||||
|
||||
int CPolyLine::Fillet( unsigned int aIndex, unsigned int aRadius,
|
||||
unsigned int aSegments )
|
||||
{
|
||||
int x1, y1; // Current vertex
|
||||
int xa, ya; // Previous vertex
|
||||
int xb, yb; // Next vertex
|
||||
double nx, ny;
|
||||
|
||||
if( !aRadius )
|
||||
return 0;
|
||||
|
||||
x1 = corner[aIndex].x;
|
||||
y1 = corner[aIndex].y;
|
||||
|
||||
if( aIndex == 0 )
|
||||
{
|
||||
xa = corner[corner.size()-1].x - x1;
|
||||
ya = corner[corner.size()-1].y - y1;
|
||||
}
|
||||
else
|
||||
{
|
||||
xa = corner[aIndex-1].x - x1;
|
||||
ya = corner[aIndex-1].y - y1;
|
||||
}
|
||||
|
||||
if( aIndex == corner.size()-1 )
|
||||
{
|
||||
xb = corner[0].x - x1;
|
||||
yb = corner[0].y - y1;
|
||||
}
|
||||
else
|
||||
{
|
||||
xb = corner[aIndex+1].x - x1;
|
||||
yb = corner[aIndex+1].y - y1;
|
||||
}
|
||||
|
||||
double lena = sqrt( xa*xa + ya*ya );
|
||||
double lenb = sqrt( xb*xb + yb*yb );
|
||||
double cosine = ( xa*xb + ya*yb )/( lena*lenb );
|
||||
|
||||
// Calculate fillet arc absolute center point (xc, yx)
|
||||
double k = aRadius / sqrt( .5*( 1-cosine ) );
|
||||
double lenab = sqrt( ( xa/lena + xb/lenb )*( xa/lena + xb/lenb ) +
|
||||
( ya/lena + yb/lenb )*( ya/lena + yb/lenb ) );
|
||||
double xc = x1 + k*( xa/lena + xb/lenb )/lenab;
|
||||
double yc = y1 + k*( ya/lena + yb/lenb )/lenab;
|
||||
|
||||
// Calculate arc start and end vectors
|
||||
k = aRadius / sqrt( 2/( 1+cosine )-1 );
|
||||
double xs = x1 + k*xa/lena - xc;
|
||||
double ys = y1 + k*ya/lena - yc;
|
||||
double xe = x1 + k*xb/lenb - xc;
|
||||
double ye = y1 + k*yb/lenb - yc;
|
||||
|
||||
// Cosine of arc angle
|
||||
double argument = ( xs*xe + ys*ye ) / ( aRadius*aRadius );
|
||||
|
||||
if( argument < -1 ) // Just in case...
|
||||
argument = -1;
|
||||
else if( argument > 1 )
|
||||
argument = 1;
|
||||
|
||||
double arcAngle = acos( argument );
|
||||
|
||||
// Calculate the number of segments
|
||||
double tempSegments = (double)aSegments * ( arcAngle / ( 2*M_PI ) );
|
||||
|
||||
if( tempSegments - (int)tempSegments > 0 )
|
||||
tempSegments++;
|
||||
aSegments = tempSegments;
|
||||
|
||||
double deltaAngle = arcAngle / aSegments;
|
||||
double startAngle = atan2( -ys, xs );
|
||||
|
||||
// Flip arc for inner corners
|
||||
if( xa*yb - ya*xb <= 0 )
|
||||
deltaAngle *= -1;
|
||||
|
||||
// Move first vertex into new position
|
||||
nx = xc + xs + 0.5;
|
||||
ny = yc + ys + 0.5;
|
||||
corner[aIndex].x = (int)nx;
|
||||
corner[aIndex].y = (int)ny;
|
||||
|
||||
// Add new vertices
|
||||
unsigned int nVertices = 0;
|
||||
for( unsigned int j = 0; j < aSegments; j++ )
|
||||
{
|
||||
nx = xc + cos( startAngle + (j+1)*deltaAngle )*aRadius + 0.5;
|
||||
ny = yc - sin( startAngle + (j+1)*deltaAngle )*aRadius + 0.5;
|
||||
InsertCorner( aIndex + nVertices, (int)nx, (int)ny );
|
||||
nVertices++;
|
||||
}
|
||||
|
||||
return nVertices; // Return the number of added vertices
|
||||
}
|
||||
|
||||
|
||||
CPolyLine* CPolyLine::Fillet( unsigned int aRadius, unsigned int aSegments )
|
||||
{
|
||||
CPolyLine* newPoly = new CPolyLine;
|
||||
unsigned int lena, lenb;
|
||||
newPoly->Copy( this );
|
||||
|
||||
for( unsigned int i = 0, index = 0; i < corner.size(); i++, index++ )
|
||||
{
|
||||
if( i == 0 )
|
||||
lena = GetEdgeLength( corner.size()-1 );
|
||||
else
|
||||
lena = GetEdgeLength( i - 1 );
|
||||
lenb = GetEdgeLength( i );
|
||||
|
||||
unsigned int radius = aRadius;
|
||||
double denom = sqrt( 2.0/( 1+GetCosine( i ) )-1 );
|
||||
|
||||
// Limit rounding distance to one half of an edge
|
||||
if( 0.5*lena*denom < radius )
|
||||
radius = 0.5*lena*denom;
|
||||
|
||||
if( 0.5*lenb*denom < radius )
|
||||
radius = 0.5*lenb*denom;
|
||||
|
||||
// Round this corner and keep tract of added vertices
|
||||
index += newPoly->Fillet( index, radius, aSegments );
|
||||
}
|
||||
|
||||
return newPoly;
|
||||
}
|
||||
|
||||
|
||||
/******************************************/
|
||||
void CPolyLine::RemoveAllContours( void )
|
||||
/******************************************/
|
||||
|
@ -996,6 +1205,63 @@ int CPolyLine::GetEndContour( int ic )
|
|||
}
|
||||
|
||||
|
||||
unsigned int CPolyLine::GetEdgeLength( unsigned int aIndex )
|
||||
{
|
||||
long xa, ya, xb, yb;
|
||||
xa = corner[aIndex].x;
|
||||
ya = corner[aIndex].y;
|
||||
|
||||
if( aIndex == corner.size()-1 )
|
||||
{
|
||||
xb = corner[0].x;
|
||||
yb = corner[0].y;
|
||||
}
|
||||
else
|
||||
{
|
||||
xb = corner[aIndex+1].x;
|
||||
yb = corner[aIndex+1].y;
|
||||
}
|
||||
|
||||
return sqrt( (xb-xa)*(xb-xa) + (yb-ya)*(yb-ya) );
|
||||
}
|
||||
|
||||
|
||||
double CPolyLine::GetCosine( unsigned int aIndex )
|
||||
{
|
||||
int x1, y1;
|
||||
long xa, ya, xb, yb;
|
||||
x1 = corner[aIndex].x;
|
||||
y1 = corner[aIndex].y;
|
||||
|
||||
if( aIndex == 0 )
|
||||
{
|
||||
xa = corner[corner.size()-1].x - x1;
|
||||
ya = corner[corner.size()-1].y - y1;
|
||||
}
|
||||
else
|
||||
{
|
||||
xa = corner[aIndex-1].x - x1;
|
||||
ya = corner[aIndex-1].y - y1;
|
||||
}
|
||||
|
||||
if( aIndex == corner.size() - 1 )
|
||||
{
|
||||
xb = corner[0].x - x1;
|
||||
yb = corner[0].y - y1;
|
||||
}
|
||||
else
|
||||
{
|
||||
xb = corner[aIndex+1].x - x1;
|
||||
yb = corner[aIndex+1].y - y1;
|
||||
}
|
||||
|
||||
double lena = sqrt( (double)xa*xa + ya*ya );
|
||||
double lenb = sqrt( (double)xb*xb + yb*yb );
|
||||
|
||||
return ( xa*xb + ya*yb )/( lena*lenb );
|
||||
}
|
||||
|
||||
|
||||
CRect CPolyLine::GetBounds()
|
||||
{
|
||||
CRect r = GetCornerBounds();
|
||||
|
|
|
@ -132,6 +132,43 @@ public:
|
|||
void Close( int style = STRAIGHT, bool bDraw = false );
|
||||
void RemoveContour( int icont );
|
||||
|
||||
/**
|
||||
* Function Chamfer
|
||||
* chamfers a corner.
|
||||
* @param aIndex is the corner index.
|
||||
* @param aDistance is the chamfering distance.
|
||||
* @return int - The number of segments added.
|
||||
*/
|
||||
int Chamfer( unsigned int aIndex, unsigned int aDistance );
|
||||
|
||||
/**
|
||||
* Function Chamfer
|
||||
* returns a chamfered version of a polygon.
|
||||
* @param aDistance is the chamfering distance.
|
||||
* @return CPolyLine* - Pointer to new polygon.
|
||||
*/
|
||||
CPolyLine* Chamfer( unsigned int aDistance );
|
||||
|
||||
/**
|
||||
* Function Fillet
|
||||
* rounds a corner.
|
||||
* @param aIndex is the corner index.
|
||||
* @param aDistance is the fillet radius.
|
||||
* @param aSegments is the number of segments / 360 degrees.
|
||||
* @return int - The number of segments added.
|
||||
*/
|
||||
int Fillet( unsigned int aIndex, unsigned int aRadius,
|
||||
unsigned int aSegments );
|
||||
|
||||
/**
|
||||
* Function Fillet
|
||||
* returns a filleted version of a polygon.
|
||||
* @param aDistance is the fillet radius.
|
||||
* @param aSegments is the number of segments / fillet.
|
||||
* @return CPolyLine* - Pointer to new polygon.
|
||||
*/
|
||||
CPolyLine* Fillet( unsigned int aRadius, unsigned int aSegments );
|
||||
|
||||
void RemoveAllContours( void );
|
||||
|
||||
// drawing functions
|
||||
|
@ -149,9 +186,8 @@ public:
|
|||
bool IsCutoutContour( int icont );
|
||||
void AppendArc( int xi, int yi, int xf, int yf, int xc, int yc, int num );
|
||||
|
||||
|
||||
// access functions
|
||||
int GetLayer() { return m_layer; }
|
||||
int GetLayer() { return m_layer; }
|
||||
int GetNumCorners();
|
||||
int GetNumSides();
|
||||
int GetClosed();
|
||||
|
@ -164,6 +200,22 @@ public:
|
|||
int GetY( int ic );
|
||||
int GetEndContour( int ic );
|
||||
|
||||
/**
|
||||
* Function GetEdgeLength
|
||||
* returns the length of the edge starting at given corner index.
|
||||
* @param aIndex is the corner index.
|
||||
* @return unsigned int - the length of the edge.
|
||||
*/
|
||||
unsigned int GetEdgeLength( unsigned int aIndex );
|
||||
|
||||
/**
|
||||
* Function GetCosine
|
||||
* returns the cosine between the two edge vectors at a corner.
|
||||
* @param aIndex is the corner index.
|
||||
* @return double - the cosine value.
|
||||
*/
|
||||
double GetCosine( unsigned int aIndex );
|
||||
|
||||
int GetUtility( int ic ) { return corner[ic].utility; };
|
||||
void SetUtility( int ic, int utility ) { corner[ic].utility = utility; };
|
||||
int GetSideStyle( int is );
|
||||
|
|
Loading…
Reference in New Issue