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
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>

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
* @param nb_segm = corner count
* @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
*/
{

View File

@ -149,6 +149,10 @@ bool ZONE_CONTAINER::Save( FILE* aFile ) const
if( ret < 2 )
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,
m_DrawOptions ? 'S' : 'F', m_ThermalReliefGapValue, m_ThermalReliefCopperBridgeValue );
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)
{
@ -522,8 +536,26 @@ void ZONE_CONTAINER::DrawFilledArea( WinEDA_DrawPanel* panel,
GRClosedPoly( &panel->m_ClipBox, DC, corners_count, CornersBuffer,
false, 0, color, color );
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,
true, 0, color, color );
}
corners_count = 0;
ii = 0;
}

View File

@ -26,6 +26,7 @@ public:
CPolyLine* m_Poly; // outlines
int m_CornerSelection; // For corner moving, corner index to drag, or -1 if no selection
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_ArcToSegmentsCount; // number of segments to convert a cirlce to a polygon (uses 16 or 32)
int m_PadOption; //

View File

@ -26,6 +26,7 @@ ZONE_SETTING::ZONE_SETTING( void )
{
m_GridFillValue = 250; // Grid value for filling zone by segments, 0 to used polygons to fill
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_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
@ -47,6 +48,7 @@ void ZONE_SETTING::ImportSetting( const ZONE_CONTAINER& aSource )
{
m_GridFillValue = aSource.m_GridFillValue;
m_ZoneClearance = aSource.m_ZoneClearance;
m_ZoneMinThickness = aSource.m_ZoneMinThickness;
m_NetcodeSelection = aSource.GetNet();
m_CurrentZone_Layer = aSource.GetLayer();
m_Zone_HatchingStyle = aSource.GetHatchStyle();
@ -68,9 +70,10 @@ void ZONE_SETTING::ExportSetting( ZONE_CONTAINER& aTarget )
{
aTarget.m_GridFillValue = m_GridFillValue;
aTarget.m_ZoneClearance = m_ZoneClearance;
aTarget.SetNet(m_NetcodeSelection);
aTarget.SetLayer(m_CurrentZone_Layer);
aTarget.m_Poly->SetHatch(m_Zone_HatchingStyle);
aTarget.m_ZoneMinThickness = m_ZoneMinThickness;
aTarget.SetNet( m_NetcodeSelection );
aTarget.SetLayer( m_CurrentZone_Layer );
aTarget.m_Poly->SetHatch( m_Zone_HatchingStyle );
aTarget.m_ArcToSegmentsCount = m_ArcToSegmentsCount;
aTarget.m_DrawOptions = m_FilledAreasShowMode;
aTarget.m_ThermalReliefGapValue = m_ThermalReliefGapValue;

View File

@ -19,6 +19,7 @@ class ZONE_SETTING
public:
int m_GridFillValue; // Grid value for filling zone by segments, 0 to used polygons to fill
int m_ZoneClearance; // Clearance value
int m_ZoneMinThickness; // Min thickness value in filled areas
int m_NetcodeSelection; // Net code selection for the current zone
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

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
wxString msg = _( "Zone clearance value:" ) + ReturnUnitSymbol( g_UnitMetric );
m_ClearanceValueTitle->SetLabel( msg );
wxString msg;
msg = _( "Grid :" ) + ReturnUnitSymbol( g_UnitMetric );
msg = m_GridCtrl->GetLabel() + ReturnUnitSymbol( g_UnitMetric );
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 )
m_OrientEdgesOpt->SetSelection( 1 );
@ -98,11 +92,18 @@ void dialog_copper_zone::OnInitDialog( wxInitDialogEvent& event )
m_GridCtrl->SetSelection( selection );
AddUnitSymbol( *m_ClearanceValueTitle, g_UnitMetric );
msg = ReturnStringFromValue( g_UnitMetric,
m_Zone_Setting->m_ZoneClearance,
m_Parent->m_InternalUnits );
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 )
{
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();
m_Zone_Setting->m_ZoneClearance =
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 )
g_Zone_45_Only = FALSE;
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!)") };
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->SetSelection( 4 );
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( 1 );
m_FillOptionsBox->Add( m_GridCtrl, 0, wxALL|wxEXPAND, 5 );
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_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_OthersOptionsSizer->Add( m_ClearanceValueTitle, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
m_ZoneClearanceCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
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_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_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_RightBoxSizer->Add( m_NetSortOptSizer, 1, wxEXPAND, 5 );

View File

@ -130,14 +130,14 @@
<property name="font"></property>
<property name="hidden">0</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="maximum_size"></property>
<property name="minimum_size"></property>
<property name="name">m_GridCtrl</property>
<property name="permission">protected</property>
<property name="pos"></property>
<property name="selection">4</property>
<property name="selection">1</property>
<property name="size"></property>
<property name="style">wxRA_SPECIFY_COLS</property>
<property name="subclass"></property>
@ -733,7 +733,7 @@
<property name="font"></property>
<property name="hidden">0</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="minimum_size"></property>
<property name="name">m_ClearanceValueTitle</property>
@ -827,6 +827,112 @@
<event name="OnUpdateUI"></event>
</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>
@ -1160,7 +1266,7 @@
<property name="size"></property>
<property name="style"></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="window_extra_style"></property>
<property name="window_name"></property>

View File

@ -73,6 +73,8 @@ class dialog_copper_zone_base : public wxDialog
wxCheckBox* m_ShowFilledAreasInSketchOpt;
wxStaticText* m_ClearanceValueTitle;
wxTextCtrl* m_ZoneClearanceCtrl;
wxStaticText* m_MinThicknessValueTitle;
wxTextCtrl* m_ZoneMinThicknessCtrl;
wxButton* m_ExportSetupButton;
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,
int rayon,int width);
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,
const wxString & Text, int t_orient,
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 */
void PlotGERBERLine(wxPoint start, wxPoint end, 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,
int penwidth, int orient);
/* 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;
}
PlotPolygon( format_plot, TRUE, PtEdge->m_PolyCount, ptr_base );
PlotFilledPolygon( format_plot, PtEdge->m_PolyCount, ptr_base );
free( ptr_base );
break;
}
@ -748,7 +748,9 @@ void PlotFilledAreas( ZONE_CONTAINER * aZone, int aFormat )
corners_count++;
if( corner->end_contour )
{ // 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;
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 */
{
switch( format_plot )
{
case PLOT_FORMAT_GERBER:
PlotPolygon_GERBER( nbpoints, coord, Filled );
PlotFilledPolygon_GERBER( nbpoints, coord );
break;
case PLOT_FORMAT_HPGL:
PlotPolyHPGL( nbpoints, coord, Filled );
PlotPolyHPGL( nbpoints, coord, true );
break;
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;
}
}

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 );
}
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;
@ -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 )
/*******************************************************/

View File

@ -52,10 +52,11 @@ double s_Correction; /* mult coeff used to enlarge rounded and oval pads (an
*/
/** function AddClearanceAreasPolygonsToPolysList
* Supports a min thickness area constraint.
* Add non copper areas polygons (pads and tracks with clearence)
* to a filled copper area
* used in BuildFilledPolysListData when calculating filled areas in a zone
* Non copper areas are pads and track and their clearance area
* to the filled copper area found
* in BuildFilledPolysListData after calculating filled areas in a zone
* Non filled copper areas are pads and track and their clearance areas
* The filled copper area must be computed just before.
* BuildFilledPolysListData() call this function just after creating the
* 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
* 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
* 3 - Add all non filled areas (pads, tracks) in group B
* 4 - calculates the polygon A - B
* 5 - put resulting list of polygons (filled areas) in m_FilledPolysList
* 6 - Remove insulated copper islands
* 3 - Creates a correction using BOOL_CORRECTION operation to inflate the resulting area
* with m_ZoneMinThickness/2 value.
* The result is areas with a margin of m_ZoneMinThickness/2
* 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 )
{
@ -87,16 +95,19 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
/* Uses a kbool engine to add holes in the m_FilledPolysList polygon.
* Because this function is called just after creating the m_FilledPolysList,
* only one polygon is in list.
* (initial holes in zonesare linked into outer contours by double overlapping segments).
* after adding holes, many polygons could be exist in this list.
* (initial holes in zones are linked into outer contours by double overlapping segments).
* because after adding holes, many polygons could be exist in this list.
*/
Bool_Engine* booleng = new Bool_Engine();
ArmBoolEng( booleng, true );
/* Add the main polygon (i.e. the filled area using only one outline)
* in GroupA in Bool_Engine
/* First, Add the main polygon (i.e. the filled area using only one outline)
* 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 ic = 0;
@ -112,9 +123,59 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
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
int clearance = max( m_ZoneClearance, g_DesignSettings.m_TrackClearence );
clearance += m_ZoneMinThickness/2;
/* Add holes (i.e. tracks and pads areas as polygons outlines)
* in GroupB in Bool_Engine
@ -155,7 +216,8 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
item_boundingbox.Inflate( m_ThermalReliefGapValue, m_ThermalReliefGapValue );
if( item_boundingbox.Intersects( zone_boundingbox ) )
AddThermalReliefPadPolygon( booleng, *pad,
m_ThermalReliefGapValue, m_ThermalReliefCopperBridgeValue );
m_ThermalReliefGapValue/* + (m_ZoneMinThickness/2)*/,
m_ThermalReliefCopperBridgeValue /*- m_ZoneMinThickness*/ );
break;
case PAD_IN_ZONE:
@ -401,6 +463,9 @@ void AddThermalReliefPadPolygon( Bool_Engine* aBooleng,
int delta = 3600 / s_CircleToSegmentsCount; // rot angle in 0.1 degree
if ( aCopperThickness < 0 )
aCopperThickness = 0;
copper_tickness.x = min( dx, 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)
// 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
// this is also used to remove small segments and to decide when
// 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
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->SetGrid( GRID );