Zones now have a min thickness filled area parameter

This commit is contained in:
charras 2008-11-22 20:50:30 +00:00
parent 346914c9e3
commit 1c6ff86768
15 changed files with 340 additions and 59 deletions

View File

@ -9,6 +9,11 @@ email address.
================================================================================ ================================================================================
++pcbnew ++pcbnew
Some cleanup in dialog pad edition. Some cleanup in dialog pad edition.
Added:
Zones now have a min thickness filled area parameter
that ensure a minimun width for filled copper areas
(areas below this min thickness are removed)
Shapes also are better
2008-Nov-19 UPDATE Jerry Jacobs <jerkejacobs@gmail.com> 2008-Nov-19 UPDATE Jerry Jacobs <jerkejacobs@gmail.com>

View File

@ -184,7 +184,7 @@ void PlotPolyPS( int nb_segm, int* coord, bool fill, int width )
/* Draw a polygon ( a filled polygon if fill == 1 ) in POSTSCRIPT format /* Draw a polygon ( a filled polygon if fill == 1 ) in POSTSCRIPT format
* @param nb_segm = corner count * @param nb_segm = corner count
* @param coord = corner list (a corner uses 2 int = X coordinate followed by Y coordinate * @param coord = corner list (a corner uses 2 int = X coordinate followed by Y coordinate
* @param fill :if == 0 : filled polygon * @param fill :if true : filled polygon
* @param width = line width * @param width = line width
*/ */
{ {

View File

@ -149,6 +149,10 @@ bool ZONE_CONTAINER::Save( FILE* aFile ) const
if( ret < 2 ) if( ret < 2 )
return false; return false;
ret = fprintf( aFile, "ZMinThickness %d\n", m_ZoneMinThickness );
if( ret < 1 )
return false;
ret = fprintf( aFile, "ZOptions %d %d %c %d %d\n", m_GridFillValue, m_ArcToSegmentsCount, ret = fprintf( aFile, "ZOptions %d %d %c %d %d\n", m_GridFillValue, m_ArcToSegmentsCount,
m_DrawOptions ? 'S' : 'F', m_ThermalReliefGapValue, m_ThermalReliefCopperBridgeValue ); m_DrawOptions ? 'S' : 'F', m_ThermalReliefGapValue, m_ThermalReliefCopperBridgeValue );
if( ret < 3 ) if( ret < 3 )
@ -332,6 +336,16 @@ int ZONE_CONTAINER::ReadDescr( FILE* aFile, int* aLineNum )
} }
} }
if( strnicmp( Line, "ZMinThickness", 13 ) == 0 ) // Min Thickness info found
{
int thickness;
text = Line + 13;
ret = sscanf( text, "%d", &thickness );
if( ret < 1 )
error = true;
else
m_ZoneMinThickness = thickness;
}
if( strnicmp( Line, "$POLYSCORNERS", 13 ) == 0 ) // Read the PolysList (polygons used for fill areas in the zone) if( strnicmp( Line, "$POLYSCORNERS", 13 ) == 0 ) // Read the PolysList (polygons used for fill areas in the zone)
{ {
@ -522,8 +536,26 @@ void ZONE_CONTAINER::DrawFilledArea( WinEDA_DrawPanel* panel,
GRClosedPoly( &panel->m_ClipBox, DC, corners_count, CornersBuffer, GRClosedPoly( &panel->m_ClipBox, DC, corners_count, CornersBuffer,
false, 0, color, color ); false, 0, color, color );
else else
{
// Draw outlines:
if ( m_ZoneMinThickness > 1 )
{
int ilim = corners_count * 2;
for ( int is = 0, ie = ilim-2; is < ilim; ie = is, is+=2 )
{
int x0 = CornersBuffer[is];
int y0 = CornersBuffer[is+1];
int x1 = CornersBuffer[ie];
int y1 = CornersBuffer[ie+1];
GRFillCSegm( &panel->m_ClipBox, DC,
x0, y0, x1 , y1,
m_ZoneMinThickness, color );
}
}
// Draw areas:
GRPoly( &panel->m_ClipBox, DC, corners_count, CornersBuffer, GRPoly( &panel->m_ClipBox, DC, corners_count, CornersBuffer,
true, 0, color, color ); true, 0, color, color );
}
corners_count = 0; corners_count = 0;
ii = 0; ii = 0;
} }

View File

@ -26,6 +26,7 @@ public:
CPolyLine* m_Poly; // outlines CPolyLine* m_Poly; // outlines
int m_CornerSelection; // For corner moving, corner index to drag, or -1 if no selection int m_CornerSelection; // For corner moving, corner index to drag, or -1 if no selection
int m_ZoneClearance; // clearance value int m_ZoneClearance; // clearance value
int m_ZoneMinThickness; // Min thickness value in filled areas
int m_GridFillValue; // Grid used for filling, 0 = use polygonal areas to fill int m_GridFillValue; // Grid used for filling, 0 = use polygonal areas to fill
int m_ArcToSegmentsCount; // number of segments to convert a cirlce to a polygon (uses 16 or 32) int m_ArcToSegmentsCount; // number of segments to convert a cirlce to a polygon (uses 16 or 32)
int m_PadOption; // int m_PadOption; //

View File

@ -25,7 +25,8 @@
ZONE_SETTING::ZONE_SETTING( void ) ZONE_SETTING::ZONE_SETTING( void )
{ {
m_GridFillValue = 250; // Grid value for filling zone by segments, 0 to used polygons to fill m_GridFillValue = 250; // Grid value for filling zone by segments, 0 to used polygons to fill
m_ZoneClearance = 200; // Clearance value m_ZoneClearance = 200; // Clearance value
m_ZoneMinThickness = 0; // Min thickness value in filled areas
m_NetcodeSelection = 0; // Net code selection for the current zone m_NetcodeSelection = 0; // Net code selection for the current zone
m_CurrentZone_Layer = 0; // Layer used to create the current zone m_CurrentZone_Layer = 0; // Layer used to create the current zone
m_Zone_HatchingStyle = CPolyLine::DIAGONAL_EDGE; // Option to show the zone area (outlines only, short hatches or full hatches m_Zone_HatchingStyle = CPolyLine::DIAGONAL_EDGE; // Option to show the zone area (outlines only, short hatches or full hatches
@ -47,6 +48,7 @@ void ZONE_SETTING::ImportSetting( const ZONE_CONTAINER& aSource )
{ {
m_GridFillValue = aSource.m_GridFillValue; m_GridFillValue = aSource.m_GridFillValue;
m_ZoneClearance = aSource.m_ZoneClearance; m_ZoneClearance = aSource.m_ZoneClearance;
m_ZoneMinThickness = aSource.m_ZoneMinThickness;
m_NetcodeSelection = aSource.GetNet(); m_NetcodeSelection = aSource.GetNet();
m_CurrentZone_Layer = aSource.GetLayer(); m_CurrentZone_Layer = aSource.GetLayer();
m_Zone_HatchingStyle = aSource.GetHatchStyle(); m_Zone_HatchingStyle = aSource.GetHatchStyle();
@ -66,13 +68,14 @@ void ZONE_SETTING::ImportSetting( const ZONE_CONTAINER& aSource )
*/ */
void ZONE_SETTING::ExportSetting( ZONE_CONTAINER& aTarget ) void ZONE_SETTING::ExportSetting( ZONE_CONTAINER& aTarget )
{ {
aTarget.m_GridFillValue = m_GridFillValue; aTarget.m_GridFillValue = m_GridFillValue;
aTarget.m_ZoneClearance = m_ZoneClearance; aTarget.m_ZoneClearance = m_ZoneClearance;
aTarget.SetNet(m_NetcodeSelection); aTarget.m_ZoneMinThickness = m_ZoneMinThickness;
aTarget.SetLayer(m_CurrentZone_Layer); aTarget.SetNet( m_NetcodeSelection );
aTarget.m_Poly->SetHatch(m_Zone_HatchingStyle); aTarget.SetLayer( m_CurrentZone_Layer );
aTarget.m_ArcToSegmentsCount = m_ArcToSegmentsCount; aTarget.m_Poly->SetHatch( m_Zone_HatchingStyle );
aTarget.m_DrawOptions = m_FilledAreasShowMode; aTarget.m_ArcToSegmentsCount = m_ArcToSegmentsCount;
aTarget.m_DrawOptions = m_FilledAreasShowMode;
aTarget.m_ThermalReliefGapValue = m_ThermalReliefGapValue; aTarget.m_ThermalReliefGapValue = m_ThermalReliefGapValue;
aTarget.m_ThermalReliefCopperBridgeValue = m_ThermalReliefCopperBridgeValue; aTarget.m_ThermalReliefCopperBridgeValue = m_ThermalReliefCopperBridgeValue;
aTarget.m_PadOption = m_Zone_Pad_Options; aTarget.m_PadOption = m_Zone_Pad_Options;

View File

@ -17,17 +17,18 @@
class ZONE_SETTING class ZONE_SETTING
{ {
public: public:
int m_GridFillValue; // Grid value for filling zone by segments, 0 to used polygons to fill int m_GridFillValue; // Grid value for filling zone by segments, 0 to used polygons to fill
int m_ZoneClearance; // Clearance value int m_ZoneClearance; // Clearance value
int m_NetcodeSelection; // Net code selection for the current zone int m_ZoneMinThickness; // Min thickness value in filled areas
int m_CurrentZone_Layer; // Layer used to create the current zone int m_NetcodeSelection; // Net code selection for the current zone
int m_Zone_HatchingStyle; // Option to show the zone area (outlines only, short hatches or full hatches int m_CurrentZone_Layer; // Layer used to create the current zone
int m_Zone_HatchingStyle; // Option to show the zone area (outlines only, short hatches or full hatches
int m_ArcToSegmentsCount; /* Option to select number of segments to approximate a circle int m_ArcToSegmentsCount; /* Option to select number of segments to approximate a circle
* 16 or 32 segments */ * 16 or 32 segments */
int m_FilledAreasShowMode; // Used to select draw options for filled areas in a zone (currently normal =0, sketch = 1) int m_FilledAreasShowMode; // Used to select draw options for filled areas in a zone (currently normal =0, sketch = 1)
long m_ThermalReliefGapValue; // tickness of the gap in thermal reliefs long m_ThermalReliefGapValue; // tickness of the gap in thermal reliefs
long m_ThermalReliefCopperBridgeValue; // tickness of the copper bridge 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 int m_Zone_Pad_Options; // How pads are covered by copper in zone
public: public:
ZONE_SETTING( void ); ZONE_SETTING( void );

View File

@ -64,17 +64,11 @@ void dialog_copper_zone::OnInitDialog( wxInitDialogEvent& event )
SetFocus(); // Required under wxGTK if we want to demiss the dialog with the ESC key SetFocus(); // Required under wxGTK if we want to demiss the dialog with the ESC key
wxString msg = _( "Zone clearance value:" ) + ReturnUnitSymbol( g_UnitMetric ); wxString msg;
m_ClearanceValueTitle->SetLabel( msg );
msg = _( "Grid :" ) + ReturnUnitSymbol( g_UnitMetric ); msg = m_GridCtrl->GetLabel() + ReturnUnitSymbol( g_UnitMetric );
m_GridCtrl->SetLabel( msg ); m_GridCtrl->SetLabel( msg );
msg = ReturnStringFromValue( g_UnitMetric,
m_Zone_Setting->m_ZoneClearance,
m_Parent->m_InternalUnits );
m_ZoneClearanceCtrl->SetValue( msg );
if( g_Zone_45_Only ) if( g_Zone_45_Only )
m_OrientEdgesOpt->SetSelection( 1 ); m_OrientEdgesOpt->SetSelection( 1 );
@ -98,11 +92,18 @@ void dialog_copper_zone::OnInitDialog( wxInitDialogEvent& event )
m_GridCtrl->SetSelection( selection ); m_GridCtrl->SetSelection( selection );
AddUnitSymbol( *m_ClearanceValueTitle, g_UnitMetric );
msg = ReturnStringFromValue( g_UnitMetric, msg = ReturnStringFromValue( g_UnitMetric,
m_Zone_Setting->m_ZoneClearance, m_Zone_Setting->m_ZoneClearance,
m_Parent->m_InternalUnits ); m_Parent->m_InternalUnits );
m_ZoneClearanceCtrl->SetValue( msg ); m_ZoneClearanceCtrl->SetValue( msg );
AddUnitSymbol( *m_MinThicknessValueTitle, g_UnitMetric );
msg = ReturnStringFromValue( g_UnitMetric,
m_Zone_Setting->m_ZoneMinThickness,
m_Parent->m_InternalUnits );
m_ZoneMinThicknessCtrl->SetValue( msg );
switch( m_Zone_Setting->m_Zone_Pad_Options ) switch( m_Zone_Setting->m_Zone_Pad_Options )
{ {
case PAD_NOT_IN_ZONE: // Pads are not covered case PAD_NOT_IN_ZONE: // Pads are not covered
@ -324,6 +325,11 @@ bool dialog_copper_zone::AcceptOptions( bool aPromptForErrors, bool aUseExportab
wxString txtvalue = m_ZoneClearanceCtrl->GetValue(); wxString txtvalue = m_ZoneClearanceCtrl->GetValue();
m_Zone_Setting->m_ZoneClearance = m_Zone_Setting->m_ZoneClearance =
ReturnValueFromString( g_UnitMetric, txtvalue, m_Parent->m_InternalUnits ); ReturnValueFromString( g_UnitMetric, txtvalue, m_Parent->m_InternalUnits );
txtvalue = m_ZoneMinThicknessCtrl->GetValue();
m_Zone_Setting->m_ZoneMinThickness =
ReturnValueFromString( g_UnitMetric, txtvalue, m_Parent->m_InternalUnits );
if( m_OrientEdgesOpt->GetSelection() == 0 ) if( m_OrientEdgesOpt->GetSelection() == 0 )
g_Zone_45_Only = FALSE; g_Zone_45_Only = FALSE;
else else

View File

@ -39,8 +39,8 @@ dialog_copper_zone_base::dialog_copper_zone_base( wxWindow* parent, wxWindowID i
wxString m_GridCtrlChoices[] = { _("0.00000"), _("0.00000"), _("0.00000"), _("0.00000"), _("No grid (For tests only!)") }; wxString m_GridCtrlChoices[] = { _("0.00000"), _("0.00000"), _("0.00000"), _("0.00000"), _("No grid (For tests only!)") };
int m_GridCtrlNChoices = sizeof( m_GridCtrlChoices ) / sizeof( wxString ); int m_GridCtrlNChoices = sizeof( m_GridCtrlChoices ) / sizeof( wxString );
m_GridCtrl = new wxRadioBox( this, ID_RADIOBOX_GRID_SELECTION, _("Grid Size for Filling:"), wxDefaultPosition, wxDefaultSize, m_GridCtrlNChoices, m_GridCtrlChoices, 1, wxRA_SPECIFY_COLS ); m_GridCtrl = new wxRadioBox( this, ID_RADIOBOX_GRID_SELECTION, _("Grid Size for Filling"), wxDefaultPosition, wxDefaultSize, m_GridCtrlNChoices, m_GridCtrlChoices, 1, wxRA_SPECIFY_COLS );
m_GridCtrl->SetSelection( 4 ); m_GridCtrl->SetSelection( 1 );
m_FillOptionsBox->Add( m_GridCtrl, 0, wxALL|wxEXPAND, 5 ); m_FillOptionsBox->Add( m_GridCtrl, 0, wxALL|wxEXPAND, 5 );
wxString m_PadInZoneOptChoices[] = { _("Include pads"), _("Thermal relief"), _("Exclude pads") }; wxString m_PadInZoneOptChoices[] = { _("Include pads"), _("Thermal relief"), _("Exclude pads") };
@ -119,13 +119,22 @@ dialog_copper_zone_base::dialog_copper_zone_base( wxWindow* parent, wxWindowID i
m_OthersOptionsSizer->Add( m_ShowFilledAreasInSketchOpt, 0, wxALL, 5 ); m_OthersOptionsSizer->Add( m_ShowFilledAreasInSketchOpt, 0, wxALL, 5 );
m_ClearanceValueTitle = new wxStaticText( this, wxID_ANY, _("Zone clearance value (mm):"), wxDefaultPosition, wxDefaultSize, 0 ); m_ClearanceValueTitle = new wxStaticText( this, wxID_ANY, _("Zone clearance value"), wxDefaultPosition, wxDefaultSize, 0 );
m_ClearanceValueTitle->Wrap( -1 ); m_ClearanceValueTitle->Wrap( -1 );
m_OthersOptionsSizer->Add( m_ClearanceValueTitle, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); m_OthersOptionsSizer->Add( m_ClearanceValueTitle, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
m_ZoneClearanceCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); m_ZoneClearanceCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
m_OthersOptionsSizer->Add( m_ZoneClearanceCtrl, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); m_OthersOptionsSizer->Add( m_ZoneClearanceCtrl, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
m_MinThicknessValueTitle = new wxStaticText( this, wxID_ANY, _("Zone min thickness value"), wxDefaultPosition, wxDefaultSize, 0 );
m_MinThicknessValueTitle->Wrap( -1 );
m_OthersOptionsSizer->Add( m_MinThicknessValueTitle, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
m_ZoneMinThicknessCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
m_ZoneMinThicknessCtrl->SetToolTip( _("Value of minimun thickness of filled areas") );
m_OthersOptionsSizer->Add( m_ZoneMinThicknessCtrl, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
m_OutilinesBoxOpt->Add( m_OthersOptionsSizer, 1, wxEXPAND, 5 ); m_OutilinesBoxOpt->Add( m_OthersOptionsSizer, 1, wxEXPAND, 5 );
m_MiddleBoxSizer->Add( m_OutilinesBoxOpt, 1, wxEXPAND, 5 ); m_MiddleBoxSizer->Add( m_OutilinesBoxOpt, 1, wxEXPAND, 5 );
@ -173,6 +182,8 @@ dialog_copper_zone_base::dialog_copper_zone_base( wxWindow* parent, wxWindowID i
m_NetSortOptSizer->Add( m_staticText5, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); m_NetSortOptSizer->Add( m_staticText5, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
m_NetNameFilter = new wxTextCtrl( this, ID_TEXTCTRL_NETNAMES_FILTER, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); m_NetNameFilter = new wxTextCtrl( this, ID_TEXTCTRL_NETNAMES_FILTER, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
m_NetNameFilter->SetToolTip( _("Pattern in advanced mode, to filter net names in list\nNet names matching this pattern are not displayed") );
m_NetSortOptSizer->Add( m_NetNameFilter, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); m_NetSortOptSizer->Add( m_NetNameFilter, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
m_RightBoxSizer->Add( m_NetSortOptSizer, 1, wxEXPAND, 5 ); m_RightBoxSizer->Add( m_NetSortOptSizer, 1, wxEXPAND, 5 );

View File

@ -130,14 +130,14 @@
<property name="font"></property> <property name="font"></property>
<property name="hidden">0</property> <property name="hidden">0</property>
<property name="id"> ID_RADIOBOX_GRID_SELECTION</property> <property name="id"> ID_RADIOBOX_GRID_SELECTION</property>
<property name="label">Grid Size for Filling:</property> <property name="label">Grid Size for Filling</property>
<property name="majorDimension">1</property> <property name="majorDimension">1</property>
<property name="maximum_size"></property> <property name="maximum_size"></property>
<property name="minimum_size"></property> <property name="minimum_size"></property>
<property name="name">m_GridCtrl</property> <property name="name">m_GridCtrl</property>
<property name="permission">protected</property> <property name="permission">protected</property>
<property name="pos"></property> <property name="pos"></property>
<property name="selection">4</property> <property name="selection">1</property>
<property name="size"></property> <property name="size"></property>
<property name="style">wxRA_SPECIFY_COLS</property> <property name="style">wxRA_SPECIFY_COLS</property>
<property name="subclass"></property> <property name="subclass"></property>
@ -733,7 +733,7 @@
<property name="font"></property> <property name="font"></property>
<property name="hidden">0</property> <property name="hidden">0</property>
<property name="id">wxID_ANY</property> <property name="id">wxID_ANY</property>
<property name="label">Zone clearance value (mm):</property> <property name="label">Zone clearance value</property>
<property name="maximum_size"></property> <property name="maximum_size"></property>
<property name="minimum_size"></property> <property name="minimum_size"></property>
<property name="name">m_ClearanceValueTitle</property> <property name="name">m_ClearanceValueTitle</property>
@ -827,6 +827,112 @@
<event name="OnUpdateUI"></event> <event name="OnUpdateUI"></event>
</object> </object>
</object> </object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
<property name="proportion">0</property>
<object class="wxStaticText" expanded="1">
<property name="bg"></property>
<property name="context_help"></property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="font"></property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Zone min thickness value</property>
<property name="maximum_size"></property>
<property name="minimum_size"></property>
<property name="name">m_MinThicknessValueTitle</property>
<property name="permission">protected</property>
<property name="pos"></property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass"></property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<property name="wrap">-1</property>
<event name="OnChar"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
<property name="proportion">0</property>
<object class="wxTextCtrl" expanded="1">
<property name="bg"></property>
<property name="context_help"></property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="font"></property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="maximum_size"></property>
<property name="maxlength">0</property>
<property name="minimum_size"></property>
<property name="name">m_ZoneMinThicknessCtrl</property>
<property name="permission">protected</property>
<property name="pos"></property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass"></property>
<property name="tooltip">Value of minimun thickness of filled areas</property>
<property name="value"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnChar"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnText"></event>
<event name="OnTextEnter"></event>
<event name="OnTextMaxLen"></event>
<event name="OnTextURL"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
</object> </object>
</object> </object>
</object> </object>
@ -1160,7 +1266,7 @@
<property name="size"></property> <property name="size"></property>
<property name="style"></property> <property name="style"></property>
<property name="subclass"></property> <property name="subclass"></property>
<property name="tooltip"></property> <property name="tooltip">Pattern in advanced mode, to filter net names in list&#x0A;Net names matching this pattern are not displayed</property>
<property name="value"></property> <property name="value"></property>
<property name="window_extra_style"></property> <property name="window_extra_style"></property>
<property name="window_name"></property> <property name="window_name"></property>

View File

@ -73,6 +73,8 @@ class dialog_copper_zone_base : public wxDialog
wxCheckBox* m_ShowFilledAreasInSketchOpt; wxCheckBox* m_ShowFilledAreasInSketchOpt;
wxStaticText* m_ClearanceValueTitle; wxStaticText* m_ClearanceValueTitle;
wxTextCtrl* m_ZoneClearanceCtrl; wxTextCtrl* m_ZoneClearanceCtrl;
wxStaticText* m_MinThicknessValueTitle;
wxTextCtrl* m_ZoneMinThicknessCtrl;
wxButton* m_ExportSetupButton; wxButton* m_ExportSetupButton;
wxButton* m_OkButton; wxButton* m_OkButton;

View File

@ -146,7 +146,8 @@ void PlotTextePcb( TEXTE_PCB * pt_texte,int format_plot,int masque_layer);
void PlotArc(int format_plot, wxPoint centre, int start_angle,int end_angle, void PlotArc(int format_plot, wxPoint centre, int start_angle,int end_angle,
int rayon,int width); int rayon,int width);
void PlotCircle(int format_plot,int width, wxPoint centre, int rayon); void PlotCircle(int format_plot,int width, wxPoint centre, int rayon);
void PlotPolygon(int format_plot, bool filled, int nbpoints, int * coord); void PlotFilledPolygon(int format_plot, int nbpoints, int * coord);
void PlotPolygon(int format_plot, int nbpoints, int * coord, int width);
void Plot_1_texte( int format_plot, void Plot_1_texte( int format_plot,
const wxString & Text, int t_orient, const wxString & Text, int t_orient,
int width, int ox,int oy,int size_h,int size_v, int width, int ox,int oy,int size_h,int size_v,
@ -166,7 +167,8 @@ void PlotFilledAreas( ZONE_CONTAINER * aZone, int aFormat);
/* PLOTGERB.CPP */ /* PLOTGERB.CPP */
void PlotGERBERLine(wxPoint start, wxPoint end, int width); void PlotGERBERLine(wxPoint start, wxPoint end, int width);
void PlotCircle_GERBER( wxPoint centre, int rayon, int width); void PlotCircle_GERBER( wxPoint centre, int rayon, int width);
void PlotPolygon_GERBER(int nb_segm, int * coord, bool fill); void PlotFilledPolygon_GERBER(int nb_segm, int * coord);
void PlotPolygon_GERBER(int nb_segm, int * coord, int width);
void trace_1_contour_GERBER(wxPoint pos, wxSize size, wxSize delta, void trace_1_contour_GERBER(wxPoint pos, wxSize size, wxSize delta,
int penwidth, int orient); int penwidth, int orient);
/* Trace 1 contour rectangulaire ou trapezoidal d'orientation quelconque /* Trace 1 contour rectangulaire ou trapezoidal d'orientation quelconque

View File

@ -550,7 +550,7 @@ void Plot_1_EdgeModule( int format_plot, EDGE_MODULE* PtEdge )
*ptr++ = y; *ptr++ = y;
} }
PlotPolygon( format_plot, TRUE, PtEdge->m_PolyCount, ptr_base ); PlotFilledPolygon( format_plot, PtEdge->m_PolyCount, ptr_base );
free( ptr_base ); free( ptr_base );
break; break;
} }
@ -748,7 +748,9 @@ void PlotFilledAreas( ZONE_CONTAINER * aZone, int aFormat )
corners_count++; corners_count++;
if( corner->end_contour ) if( corner->end_contour )
{ // Plot the current filled area { // Plot the current filled area
PlotPolygon( aFormat, true, corners_count, CornersBuffer ); PlotFilledPolygon( aFormat, corners_count, CornersBuffer );
if ( aZone->m_ZoneMinThickness > 0 )
PlotPolygon( aFormat, corners_count, CornersBuffer, aZone->m_ZoneMinThickness );
corners_count = 0; corners_count = 0;
ii = 0; ii = 0;
} }
@ -848,22 +850,43 @@ void PlotCircle( int format_plot, int thickness, wxPoint centre, int radius )
/**********************************************************************/ /**********************************************************************/
void PlotPolygon( int format_plot, bool Filled, int nbpoints, int* coord ) void PlotFilledPolygon( int format_plot, int nbpoints, int* coord )
/**********************************************************************/ /**********************************************************************/
/* plot a polygon */ /* plot a polygon */
{ {
switch( format_plot ) switch( format_plot )
{ {
case PLOT_FORMAT_GERBER: case PLOT_FORMAT_GERBER:
PlotPolygon_GERBER( nbpoints, coord, Filled ); PlotFilledPolygon_GERBER( nbpoints, coord );
break; break;
case PLOT_FORMAT_HPGL: case PLOT_FORMAT_HPGL:
PlotPolyHPGL( nbpoints, coord, Filled ); PlotPolyHPGL( nbpoints, coord, true );
break; break;
case PLOT_FORMAT_POST: case PLOT_FORMAT_POST:
PlotPolyPS( nbpoints, coord, Filled ); PlotPolyPS( nbpoints, coord, true );
break;
}
}
/**********************************************************************/
void PlotPolygon( int format_plot, int nbpoints, int* coord, int width )
/**********************************************************************/
/* plot a polygon */
{
switch( format_plot )
{
case PLOT_FORMAT_GERBER:
PlotPolygon_GERBER( nbpoints, coord, width );
break;
case PLOT_FORMAT_HPGL:
PlotPolyHPGL( nbpoints, coord, false, width );
break;
case PLOT_FORMAT_POST:
PlotPolyPS( nbpoints, coord, false, width );
break; break;
} }
} }

View File

@ -632,7 +632,7 @@ void trace_1_pad_TRAPEZE_GERBER( wxPoint pos, wxSize size, wxSize delta,
PlotGERBERLine( polygon[3], polygon[0], plotLine_width ); PlotGERBERLine( polygon[3], polygon[0], plotLine_width );
} }
else else
PlotPolygon_GERBER( 4, coord, TRUE ); PlotFilledPolygon_GERBER( 4, coord );
} }
@ -701,7 +701,7 @@ void PlotCircle_GERBER( wxPoint centre, int rayon, int epaisseur )
/***************************************************************/ /***************************************************************/
void PlotPolygon_GERBER( int nb_segm, int* coord, bool fill ) void PlotFilledPolygon_GERBER( int nb_segm, int* coord )
/***************************************************************/ /***************************************************************/
{ {
int ii; int ii;
@ -730,6 +730,30 @@ void PlotPolygon_GERBER( int nb_segm, int* coord, bool fill )
} }
/***************************************************************/
void PlotPolygon_GERBER( int nb_segm, int* coord, int width )
/***************************************************************/
{
wxPoint start, end, startpoint;
startpoint.x = *coord++;
startpoint.y = *coord++;
start = startpoint;
for( int ii = 0; ii < nb_segm-1; ii++ )
{
end.x = *coord;
coord++;
end.y = *coord;
coord++;
PlotGERBERLine(start, end, width );
start = end;
}
if ( startpoint != end ) // Close poly
PlotGERBERLine(end, startpoint, width );
}
/*******************************************************/ /*******************************************************/
D_CODE* get_D_code( int dx, int dy, int type, int drill ) D_CODE* get_D_code( int dx, int dy, int type, int drill )
/*******************************************************/ /*******************************************************/

View File

@ -52,10 +52,11 @@ double s_Correction; /* mult coeff used to enlarge rounded and oval pads (an
*/ */
/** function AddClearanceAreasPolygonsToPolysList /** function AddClearanceAreasPolygonsToPolysList
* Supports a min thickness area constraint.
* Add non copper areas polygons (pads and tracks with clearence) * Add non copper areas polygons (pads and tracks with clearence)
* to a filled copper area * to the filled copper area found
* used in BuildFilledPolysListData when calculating filled areas in a zone * in BuildFilledPolysListData after calculating filled areas in a zone
* Non copper areas are pads and track and their clearance area * Non filled copper areas are pads and track and their clearance areas
* The filled copper area must be computed just before. * The filled copper area must be computed just before.
* BuildFilledPolysListData() call this function just after creating the * BuildFilledPolysListData() call this function just after creating the
* filled copper area polygon (without clearence areas * filled copper area polygon (without clearence areas
@ -64,10 +65,17 @@ double s_Correction; /* mult coeff used to enlarge rounded and oval pads (an
* this means the created polygons have no holes (hole are linked to outer outline by double overlapped segments * this means the created polygons have no holes (hole are linked to outer outline by double overlapped segments
* and are therefore compatible with draw functions (DC draw polygons and Gerber or PS outputs) * and are therefore compatible with draw functions (DC draw polygons and Gerber or PS outputs)
* 2 - Add the main outline (zone outline) in group A * 2 - Add the main outline (zone outline) in group A
* 3 - Add all non filled areas (pads, tracks) in group B * 3 - Creates a correction using BOOL_CORRECTION operation to inflate the resulting area
* 4 - calculates the polygon A - B * with m_ZoneMinThickness/2 value.
* 5 - put resulting list of polygons (filled areas) in m_FilledPolysList * The result is areas with a margin of m_ZoneMinThickness/2
* 6 - Remove insulated copper islands * When drawing outline with segments having a thickness of m_ZoneMinThickness, the outlines wilm
* match exactly the initial outlines
* 4 - recreates the same Bool_Engine, with no correction
* 3 - Add the main outline (zone outline) in group A
* 4 - Add all non filled areas (pads, tracks) in group B with a clearance of m_Clearance + m_ZoneMinThickness/2
* 5 - calculates the polygon A - B
* 6 - put resulting list of polygons (filled areas) in m_FilledPolysList
* 7 - Remove insulated copper islands
*/ */
void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb ) void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
{ {
@ -87,16 +95,19 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
/* Uses a kbool engine to add holes in the m_FilledPolysList polygon. /* Uses a kbool engine to add holes in the m_FilledPolysList polygon.
* Because this function is called just after creating the m_FilledPolysList, * Because this function is called just after creating the m_FilledPolysList,
* only one polygon is in list. * only one polygon is in list.
* (initial holes in zonesare linked into outer contours by double overlapping segments). * (initial holes in zones are linked into outer contours by double overlapping segments).
* after adding holes, many polygons could be exist in this list. * because after adding holes, many polygons could be exist in this list.
*/ */
Bool_Engine* booleng = new Bool_Engine(); Bool_Engine* booleng = new Bool_Engine();
ArmBoolEng( booleng, true ); ArmBoolEng( booleng, true );
/* Add the main polygon (i.e. the filled area using only one outline) /* First, Add the main polygon (i.e. the filled area using only one outline)
* in GroupA in Bool_Engine * in GroupA in Bool_Engine to do a BOOL_CORRECTION operation
* to reserve a m_ZoneMinThickness/2 margind around the outlines and holes
* the margind will be filled when redraw outilnes with segments having a whidth set to
* m_ZoneMinThickness
* so m_ZoneMinThickness is the min thickness of the filled zones areas
*/ */
unsigned corners_count = m_FilledPolysList.size(); unsigned corners_count = m_FilledPolysList.size();
unsigned ic = 0; unsigned ic = 0;
@ -112,9 +123,59 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
booleng->EndPolygonAdd(); booleng->EndPolygonAdd();
} }
booleng->SetCorrectionFactor( (double) -m_ZoneMinThickness/2 );
booleng->Do_Operation( BOOL_CORRECTION );
/* No copy the new outline in m_FilledPolysList */
m_FilledPolysList.clear();
while( booleng->StartPolygonGet() )
{
CPolyPt corner( 0, 0, false );
while( booleng->PolygonHasMorePoints() )
{
corner.x = (int) booleng->GetPolygonXPoint();
corner.y = (int) booleng->GetPolygonYPoint();
corner.end_contour = false;
m_FilledPolysList.push_back( corner );
}
corner.end_contour = true;
m_FilledPolysList.pop_back();
m_FilledPolysList.push_back( corner );
booleng->EndPolygonGet();
}
delete booleng;
/* Second, Add the main (corrected) polygon (i.e. the filled area using only one outline)
* in GroupA in Bool_Engine to do a BOOL_A_SUB_B operation
* All areas to remove will be put in GroupB in Bool_Engine
*/
booleng = new Bool_Engine();
ArmBoolEng( booleng, true );
/* Add the main corrected polygon (i.e. the filled area using only one outline)
* in GroupA in Bool_Engine
*/
corners_count = m_FilledPolysList.size();
ic = 0;
if( booleng->StartPolygonAdd( GROUP_A ) )
{
for( ; ic < corners_count; ic++ )
{
CPolyPt* corner = &m_FilledPolysList[ic];
booleng->AddPoint( corner->x, corner->y );
if( corner->end_contour )
break;
}
booleng->EndPolygonAdd();
}
// Calculates the clearance value that meet DRC requirements // Calculates the clearance value that meet DRC requirements
int clearance = max( m_ZoneClearance, g_DesignSettings.m_TrackClearence ); int clearance = max( m_ZoneClearance, g_DesignSettings.m_TrackClearence );
clearance += m_ZoneMinThickness/2;
/* Add holes (i.e. tracks and pads areas as polygons outlines) /* Add holes (i.e. tracks and pads areas as polygons outlines)
* in GroupB in Bool_Engine * in GroupB in Bool_Engine
@ -155,7 +216,8 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
item_boundingbox.Inflate( m_ThermalReliefGapValue, m_ThermalReliefGapValue ); item_boundingbox.Inflate( m_ThermalReliefGapValue, m_ThermalReliefGapValue );
if( item_boundingbox.Intersects( zone_boundingbox ) ) if( item_boundingbox.Intersects( zone_boundingbox ) )
AddThermalReliefPadPolygon( booleng, *pad, AddThermalReliefPadPolygon( booleng, *pad,
m_ThermalReliefGapValue, m_ThermalReliefCopperBridgeValue ); m_ThermalReliefGapValue/* + (m_ZoneMinThickness/2)*/,
m_ThermalReliefCopperBridgeValue /*- m_ZoneMinThickness*/ );
break; break;
case PAD_IN_ZONE: case PAD_IN_ZONE:
@ -401,6 +463,9 @@ void AddThermalReliefPadPolygon( Bool_Engine* aBooleng,
int delta = 3600 / s_CircleToSegmentsCount; // rot angle in 0.1 degree int delta = 3600 / s_CircleToSegmentsCount; // rot angle in 0.1 degree
if ( aCopperThickness < 0 )
aCopperThickness = 0;
copper_tickness.x = min( dx, aCopperThickness ); copper_tickness.x = min( dx, aCopperThickness );
copper_tickness.y = min( dy, aCopperThickness ); copper_tickness.y = min( dy, aCopperThickness );

View File

@ -541,7 +541,7 @@ void ArmBoolEng( Bool_Engine* aBooleng, bool aConvertHoles )
double DGRID = 1.0; // round coordinate X or Y value in calculations to this (initial value = 1000.0 in kbool example) double DGRID = 1.0; // round coordinate X or Y value in calculations to this (initial value = 1000.0 in kbool example)
// Note: in kicad, coordinates are already integer so DGRID can be set to 1 // Note: in kicad, coordinates are already integer so DGRID can be set to 1
double MARGE = 0.1; // snap with in this range points to lines in the intersection routines double MARGE = 0.001; // snap with in this range points to lines in the intersection routines
// should always be > DGRID a MARGE >= 10*DGRID is ok // should always be > DGRID a MARGE >= 10*DGRID is ok
// this is also used to remove small segments and to decide when // this is also used to remove small segments and to decide when
// two segments are in line. ( initial value = 0.001 ) // two segments are in line. ( initial value = 0.001 )
@ -559,7 +559,7 @@ void ArmBoolEng( Bool_Engine* aBooleng, bool aConvertHoles )
Another scaling with Grid is applied on top of it to create space in the integer number for Another scaling with Grid is applied on top of it to create space in the integer number for
even smaller numbers. even smaller numbers.
*/ */
int GRID = 100; // initial value = 10000 in kbool example int GRID = 10000; // initial value = 10000 in kbool example
aBooleng->SetMarge( MARGE ); aBooleng->SetMarge( MARGE );
aBooleng->SetGrid( GRID ); aBooleng->SetGrid( GRID );