zones in pcbnew: some optimizations

This commit is contained in:
charras 2008-10-19 18:18:45 +00:00
parent fff34db7f3
commit 43ee94b7a4
6 changed files with 77 additions and 40 deletions

View File

@ -174,8 +174,8 @@ public:
/**
* Function GetBoundingBox
* returns the bounding box of this Footprint
* Mainly used to redraw the screen area occuped by the footprint
* returns the bounding box of this pad
* Mainly used to redraw the screen area occuped by the pad
*/
EDA_Rect GetBoundingBox();

View File

@ -11,6 +11,8 @@
#include "PolyLine.h"
#include "pcbnew.h"
#include "trigo.h"
#include "zones.h"
#include "autorout.h"
/************************/
@ -21,18 +23,18 @@ ZONE_CONTAINER::ZONE_CONTAINER( BOARD* parent ) :
BOARD_ITEM( parent, TYPEZONE_CONTAINER )
{
m_NetCode = -1; // Net number for fast comparisons
m_NetCode = -1; // Net number for fast comparisons
m_CornerSelection = -1;
m_ZoneClearance = 200; // a reasonnable clerance value
m_GridFillValue = 50; // a reasonnable grid used for filling
m_PadOption = THERMAL_PAD;
utility = 0; // flags used in polygon calculations
utility2 = 0; // flags used in polygon calculations
m_Poly = new CPolyLine(); // Outlines
m_ArcToSegmentsCount = 16; // Use 16 segment to convert a circle to a polygon
m_ZoneClearance = g_DesignSettings.m_ZoneClearence; // a reasonnable clerance value
m_GridFillValue = g_GridRoutingSize; // a reasonnable grid used for filling
m_PadOption = g_Zone_Pad_Options;
utility = 0; // flags used in polygon calculations
utility2 = 0; // flags used in polygon calculations
m_Poly = new CPolyLine(); // Outlines
m_ArcToSegmentsCount = g_Zone_Arc_Approximation; // Use 16 or 32segment to convert a circle to a polygon
m_DrawOptions = 0;
m_ThermalReliefGapValue = 200; // tickness of the gap in thermal reliefs
m_ThermalReliefCopperBridgeValue = 200; // tickness of the copper bridge in thermal reliefs
m_ThermalReliefGapValue = g_ThermalReliefGapValue; // tickness of the gap in thermal reliefs
m_ThermalReliefCopperBridgeValue = g_ThermalReliefCopperBridgeValue; // tickness of the copper bridge in thermal reliefs
}
@ -141,7 +143,7 @@ bool ZONE_CONTAINER::Save( FILE* aFile ) const
return false;
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 )
return false;
@ -274,8 +276,8 @@ int ZONE_CONTAINER::ReadDescr( FILE* aFile, int* aLineNum )
}
if( strnicmp( Line, "ZOptions", 8 ) == 0 ) // Options info found
{
int gridsize = 50;
int arcsegmentcount = 16;
int gridsize = 50;
int arcsegmentcount = 16;
char drawopt = 'F';
text = Line + 8;
ret = sscanf( text, "%d %d %c %d %d", &gridsize, &arcsegmentcount, &drawopt,
@ -587,7 +589,7 @@ void ZONE_CONTAINER::DrawWhileCreateOutline( WinEDA_DrawPanel* panel, wxDC* DC,
// draw the lines
wxPoint start_contour_pos = GetCornerPosition( 0 );
int icmax = GetNumCorners() - 1;
int icmax = GetNumCorners() - 1;
for( int ic = 0; ic <= icmax; ic++ )
{
int xi = GetCornerPosition( ic ).x;
@ -609,8 +611,9 @@ void ZONE_CONTAINER::DrawWhileCreateOutline( WinEDA_DrawPanel* panel, wxDC* DC,
current_gr_mode = GR_XOR;
xf = start_contour_pos.x;
yf = start_contour_pos.y;
// Prepare the next contour for drawing, if exists
if ( ic < icmax )
if( ic < icmax )
start_contour_pos = GetCornerPosition( ic + 1 );
}
GRSetDrawMode( DC, current_gr_mode );

View File

@ -61,18 +61,18 @@ void dialog_copper_zone::OnInitDialog( wxInitDialogEvent& event )
SetFocus(); // Required under wxGTK if we want to demiss the dialog with the ESC key
wxString title = _( "Zone clearance value:" ) + ReturnUnitSymbol( g_UnitMetric );
m_ClearanceValueTitle->SetLabel( title );
wxString msg = _( "Zone clearance value:" ) + ReturnUnitSymbol( g_UnitMetric );
m_ClearanceValueTitle->SetLabel( msg );
title = _( "Grid :" ) + ReturnUnitSymbol( g_UnitMetric );
m_GridCtrl->SetLabel( title );
msg = _( "Grid :" ) + ReturnUnitSymbol( g_UnitMetric );
m_GridCtrl->SetLabel( msg );
if( g_DesignSettings.m_ZoneClearence == 0 )
g_DesignSettings.m_ZoneClearence = g_DesignSettings.m_TrackClearence;
title = ReturnStringFromValue( g_UnitMetric,
msg = ReturnStringFromValue( g_UnitMetric,
g_DesignSettings.m_ZoneClearence,
m_Parent->m_InternalUnits );
m_ZoneClearanceCtrl->SetValue( title );
m_ZoneClearanceCtrl->SetValue( msg );
if( g_Zone_45_Only )
m_OrientEdgesOpt->SetSelection( 1 );
@ -87,7 +87,7 @@ void dialog_copper_zone::OnInitDialog( wxInitDialogEvent& event )
for( unsigned ii = 0; ii < 4; ii++ )
{
wxString msg = ReturnStringFromValue( g_UnitMetric,
msg = ReturnStringFromValue( g_UnitMetric,
GridList[ii],
m_Parent->m_InternalUnits );
m_GridCtrl->SetString( ii, msg );
@ -101,10 +101,10 @@ void dialog_copper_zone::OnInitDialog( wxInitDialogEvent& event )
if( m_Zone_Container )
{
title = ReturnStringFromValue( g_UnitMetric,
msg = ReturnStringFromValue( g_UnitMetric,
m_Zone_Container->m_ZoneClearance,
m_Parent->m_InternalUnits );
m_ZoneClearanceCtrl->SetValue( title );
m_ZoneClearanceCtrl->SetValue( msg );
switch( m_Zone_Container->m_PadOption )
{
@ -193,7 +193,6 @@ void dialog_copper_zone::OnInitDialog( wxInitDialogEvent& event )
int layer_cnt = board->GetCopperLayerCount();
for( int ii = 0; ii < board->GetCopperLayerCount(); ii++ )
{
wxString msg;
int layer_number = COPPER_LAYER_N;
if( layer_cnt <= 1 || ii < layer_cnt - 1 )

View File

@ -28,6 +28,7 @@ enum zone_cmd {
/* variables used in zone dialogs and functions */
/************************************************/
// @todo: make a class like ZONE_GENERAL_SETTING instead of many global variables
eda_global bool g_Zone_45_Only
#ifdef MAIN
= FALSE

View File

@ -68,6 +68,16 @@ void WinEDA_PcbFrame::Add_Similar_Zone( wxDC* DC, ZONE_CONTAINER* zone_container
return;
s_AddCutoutToCurrentZone = false;
s_CurrentZone = zone_container;
/* set zones setup to the current zone */
g_Zone_Hatching = zone_container->m_Poly->GetHatchStyle();
g_Zone_Arc_Approximation = zone_container->m_ArcToSegmentsCount;
g_ThermalReliefGapValue = zone_container->m_ThermalReliefGapValue;
g_ThermalReliefCopperBridgeValue = zone_container->m_ThermalReliefCopperBridgeValue;
g_GridRoutingSize = zone_container->m_GridFillValue;
g_Zone_Pad_Options = zone_container->m_PadOption;
// Use the general event handle to set others params (like toolbar) */
wxCommandEvent evt;
evt.SetId( ID_PCB_ZONES_BUTT );
Process_Special_Functions( evt );
@ -89,6 +99,16 @@ void WinEDA_PcbFrame::Add_Zone_Cutout( wxDC* DC, ZONE_CONTAINER* zone_container
return;
s_AddCutoutToCurrentZone = true;
s_CurrentZone = zone_container;
/* set zones setup to the current zone */
g_Zone_Hatching = zone_container->m_Poly->GetHatchStyle();
g_Zone_Arc_Approximation = zone_container->m_ArcToSegmentsCount;
g_ThermalReliefGapValue = zone_container->m_ThermalReliefGapValue;
g_ThermalReliefCopperBridgeValue = zone_container->m_ThermalReliefCopperBridgeValue;
g_GridRoutingSize = zone_container->m_GridFillValue;
g_Zone_Pad_Options = zone_container->m_PadOption;
// Use the general event handle to set others params (like toolbar) */
wxCommandEvent evt;
evt.SetId( ID_PCB_ZONES_BUTT );
Process_Special_Functions( evt );
@ -909,17 +929,16 @@ int WinEDA_PcbFrame::Fill_Zone( wxDC* DC, ZONE_CONTAINER* zone_container, bool v
wxBusyCursor dummy; // Shows an hourglass cursor (removed by its destructor)
int error_level = 0;
zone_container->m_FilledPolysList.clear();
if( zone_container->m_GridFillValue == 0 )
{
zone_container->m_FilledPolysList.clear();
zone_container->BuildFilledPolysListData( m_Pcb );
if ( DC )
DrawPanel->Refresh();
}
else
{
zone_container->m_FilledPolysList.clear();
zone_container->m_GridFillValue = g_GridRoutingSize;
g_GridRoutingSize = zone_container->m_GridFillValue;
error_level = zone_container->Fill_Zone( this, DC, verbose );
}

View File

@ -91,6 +91,12 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
/* Add holes (i.e. tracks and pads areas as polygons outlines)
* in GroupB in Bool_Engine
*/
/* items ouside the zone bounding box are skipped */
EDA_Rect item_boundingbox;
EDA_Rect zone_boundingbox = GetBoundingBox();
zone_boundingbox.Inflate(m_ZoneClearance, m_ZoneClearance);
/*
* First : Add pads
*/
for( MODULE* module = aPcb->m_Modules; module; module = module->Next() )
@ -102,19 +108,26 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
if( pad->GetNet() != GetNet() )
{
AddPadWithClearancePolygon( booleng, *pad, m_ZoneClearance );
item_boundingbox = pad->GetBoundingBox();
if ( item_boundingbox.Intersects( zone_boundingbox ) )
AddPadWithClearancePolygon( booleng, *pad, m_ZoneClearance );
continue;
}
switch( m_PadOption )
{
case PAD_NOT_IN_ZONE:
AddPadWithClearancePolygon( booleng, *pad, m_ZoneClearance );
item_boundingbox = pad->GetBoundingBox();
if ( item_boundingbox.Intersects( zone_boundingbox ) )
AddPadWithClearancePolygon( booleng, *pad, m_ZoneClearance );
break;
case THERMAL_PAD:
AddThermalReliefPadPolygon( booleng, *pad,
m_ThermalReliefGapValue, m_ThermalReliefCopperBridgeValue );
item_boundingbox = pad->GetBoundingBox();
item_boundingbox.Inflate(m_ThermalReliefGapValue, m_ThermalReliefGapValue);
if ( item_boundingbox.Intersects( zone_boundingbox ) )
AddThermalReliefPadPolygon( booleng, *pad,
m_ThermalReliefGapValue, m_ThermalReliefCopperBridgeValue );
break;
case PAD_IN_ZONE:
@ -133,7 +146,9 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
continue;
if( track->GetNet() == GetNet() )
continue;
AddTrackWithClearancePolygon( booleng, *track, m_ZoneClearance );
item_boundingbox = track->GetBoundingBox();
if ( item_boundingbox.Intersects( zone_boundingbox ) )
AddTrackWithClearancePolygon( booleng, *track, m_ZoneClearance );
}
// Draw graphic items (copper texts) and board edges
@ -501,7 +516,7 @@ void AddThermalReliefPadPolygon( Bool_Engine* aBooleng,
{
if( aBooleng->StartPolygonAdd( GROUP_B ) )
{
for( int ic = 0; ic < corners_buffer.size(); ic++ )
for( unsigned ic = 0; ic < corners_buffer.size(); ic++ )
{
wxPoint cpos = corners_buffer[ic];
RotatePoint( &cpos, angle );
@ -517,11 +532,11 @@ void AddThermalReliefPadPolygon( Bool_Engine* aBooleng,
}
// Create holes, that are the mirrored from the previous holes
for( int i = 0; i < corners_buffer.size(); i++ )
for( unsigned ic = 0; ic < corners_buffer.size(); ic++ )
{
wxPoint swap = corners_buffer[i];
wxPoint swap = corners_buffer[ic];
swap = wxPoint( -swap.x, swap.y );
corners_buffer[i] = swap;
corners_buffer[ic] = swap;
}
// Now add corner 4 and 2 (2 is the corner 4 rotated by 180 deg
@ -530,7 +545,7 @@ void AddThermalReliefPadPolygon( Bool_Engine* aBooleng,
{
if( aBooleng->StartPolygonAdd( GROUP_B ) )
{
for( int ic = 0; ic < corners_buffer.size(); ic++ )
for( unsigned ic = 0; ic < corners_buffer.size(); ic++ )
{
wxPoint cpos = corners_buffer[ic];
RotatePoint( &cpos, angle );