From 43ee94b7a458a616ad8b7a9c2f64c4f30db4ca05 Mon Sep 17 00:00:00 2001 From: charras Date: Sun, 19 Oct 2008 18:18:45 +0000 Subject: [PATCH] zones in pcbnew: some optimizations --- pcbnew/class_pad.h | 4 +-- pcbnew/class_zone.cpp | 33 +++++++++-------- pcbnew/dialog_copper_zones.cpp | 19 +++++----- pcbnew/zones.h | 1 + pcbnew/zones_by_polygon.cpp | 25 +++++++++++-- .../zones_convert_brd_items_to_polygons.cpp | 35 +++++++++++++------ 6 files changed, 77 insertions(+), 40 deletions(-) diff --git a/pcbnew/class_pad.h b/pcbnew/class_pad.h index ff4f10dcc4..ad21c87d7e 100644 --- a/pcbnew/class_pad.h +++ b/pcbnew/class_pad.h @@ -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(); diff --git a/pcbnew/class_zone.cpp b/pcbnew/class_zone.cpp index 7c5fe32e35..0ac2798a5d 100644 --- a/pcbnew/class_zone.cpp +++ b/pcbnew/class_zone.cpp @@ -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 ); diff --git a/pcbnew/dialog_copper_zones.cpp b/pcbnew/dialog_copper_zones.cpp index 20c146bf84..e17ac8c099 100644 --- a/pcbnew/dialog_copper_zones.cpp +++ b/pcbnew/dialog_copper_zones.cpp @@ -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 ) diff --git a/pcbnew/zones.h b/pcbnew/zones.h index e17054713b..22f43495b5 100644 --- a/pcbnew/zones.h +++ b/pcbnew/zones.h @@ -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 diff --git a/pcbnew/zones_by_polygon.cpp b/pcbnew/zones_by_polygon.cpp index 96934e5027..573bac1ffb 100644 --- a/pcbnew/zones_by_polygon.cpp +++ b/pcbnew/zones_by_polygon.cpp @@ -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 ); } diff --git a/pcbnew/zones_convert_brd_items_to_polygons.cpp b/pcbnew/zones_convert_brd_items_to_polygons.cpp index 2a04093ab4..6043985392 100644 --- a/pcbnew/zones_convert_brd_items_to_polygons.cpp +++ b/pcbnew/zones_convert_brd_items_to_polygons.cpp @@ -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 );