Commit 0d3fc601 authored by charras's avatar charras

Found why remove unused thermal stubs fails sometimes.Solved

parent 9f8e1d9d
...@@ -5,7 +5,14 @@ Started 2007-June-11 ...@@ -5,7 +5,14 @@ Started 2007-June-11
Please add newer entries at the top, list the date and your name with Please add newer entries at the top, list the date and your name with
email address. email address.
2009-Jan-11 UPDATE Wayne Stambaugh <stambaughw@verizon.net> 2009-Jan-17 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr>
================================================================================
++pcbnew:
Found why remove unused thermal stubs fails sometimes:
Only the first filled area in a zone was tested.
Solved.
2009-Jan-18 UPDATE Wayne Stambaugh <stambaughw@verizon.net>
================================================================================ ================================================================================
++All ++All
* Replace Kicad file history implementation with wxFileHistory. * Replace Kicad file history implementation with wxFileHistory.
......
...@@ -48,17 +48,6 @@ enum main_id { ...@@ -48,17 +48,6 @@ enum main_id {
ID_LOAD_PROJECT, ID_LOAD_PROJECT,
ID_LOAD_ONE_SHEET, ID_LOAD_ONE_SHEET,
ID_NEW_PROJECT, ID_NEW_PROJECT,
ID_LOAD_FILE_1,
ID_LOAD_FILE_2,
ID_LOAD_FILE_3,
ID_LOAD_FILE_4,
ID_LOAD_FILE_5,
ID_LOAD_FILE_6,
ID_LOAD_FILE_7,
ID_LOAD_FILE_8,
ID_LOAD_FILE_9,
ID_LOAD_FILE_10,
ID_SAVE_PROJECT, ID_SAVE_PROJECT,
ID_SAVE_ONE_SHEET, ID_SAVE_ONE_SHEET,
ID_SAVE_ONE_SHEET_AS, ID_SAVE_ONE_SHEET_AS,
......
...@@ -48,9 +48,9 @@ BEGIN_EVENT_TABLE( WinEDA_PcbFrame, WinEDA_BasePcbFrame ) ...@@ -48,9 +48,9 @@ BEGIN_EVENT_TABLE( WinEDA_PcbFrame, WinEDA_BasePcbFrame )
EVT_MENU( ID_MENU_SAVE_BOARD, WinEDA_PcbFrame::Files_io ) EVT_MENU( ID_MENU_SAVE_BOARD, WinEDA_PcbFrame::Files_io )
EVT_MENU( ID_MENU_APPEND_FILE, WinEDA_PcbFrame::Files_io ) EVT_MENU( ID_MENU_APPEND_FILE, WinEDA_PcbFrame::Files_io )
EVT_MENU( ID_MENU_SAVE_BOARD_AS, WinEDA_PcbFrame::Files_io ) EVT_MENU( ID_MENU_SAVE_BOARD_AS, WinEDA_PcbFrame::Files_io )
EVT_MENU_RANGE( wxID_FILE1, wxID_FILE9, WinEDA_PcbFrame::OnFileHistory )
EVT_MENU( ID_GEN_PLOT, WinEDA_PcbFrame::ToPlotter ) EVT_MENU( ID_GEN_PLOT, WinEDA_PcbFrame::ToPlotter )
EVT_MENU_RANGE( ID_LOAD_FILE_1, ID_LOAD_FILE_10,
WinEDA_PcbFrame::Files_io )
EVT_MENU( ID_GEN_EXPORT_SPECCTRA, WinEDA_PcbFrame::ExportToSpecctra ) EVT_MENU( ID_GEN_EXPORT_SPECCTRA, WinEDA_PcbFrame::ExportToSpecctra )
EVT_MENU( ID_GEN_EXPORT_FILE_GENCADFORMAT, WinEDA_PcbFrame::ExportToGenCAD ) EVT_MENU( ID_GEN_EXPORT_FILE_GENCADFORMAT, WinEDA_PcbFrame::ExportToGenCAD )
......
...@@ -95,7 +95,7 @@ double s_Correction; /* mult coeff used to enlarge rounded and oval pads (an ...@@ -95,7 +95,7 @@ double s_Correction; /* mult coeff used to enlarge rounded and oval pads (an
* 11 - Remove new insulated copper islands * 11 - Remove new insulated copper islands
*/ */
/* Important note: /* Important note:
* One can add thermal areas in the step 6, with others items to substract. * One can add thermal areas in the step 6, with others items to substract.
* It is faster. * It is faster.
* But : * But :
...@@ -188,7 +188,7 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb ) ...@@ -188,7 +188,7 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
continue; continue;
} }
if ( (m_PadOption == PAD_NOT_IN_ZONE) || (GetNet() == 0) ) if( (m_PadOption == PAD_NOT_IN_ZONE) || (GetNet() == 0) )
{ {
item_boundingbox = pad->GetBoundingBox(); item_boundingbox = pad->GetBoundingBox();
if( item_boundingbox.Intersects( zone_boundingbox ) ) if( item_boundingbox.Intersects( zone_boundingbox ) )
...@@ -280,7 +280,7 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb ) ...@@ -280,7 +280,7 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
} }
} }
if ( have_poly_to_substract ) if( have_poly_to_substract )
{ {
/* Add the main corrected polygon (i.e. the filled area using only one outline) /* Add the main corrected polygon (i.e. the filled area using only one outline)
* in GroupA in Bool_Engine * in GroupA in Bool_Engine
...@@ -295,16 +295,31 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb ) ...@@ -295,16 +295,31 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
delete booleng; delete booleng;
} }
// Remove insulated islands:
if( GetNet() > 0 )
Test_For_Copper_Island_And_Remove_Insulated_Islands( aPcb );
if( m_PadOption != THERMAL_PAD )
return;
// Now we remove all unused thermal stubs. // Now we remove all unused thermal stubs.
//#define REMOVE_UNUSED_THERMAL_STUBS // Can be commented to skip unused thermal stubs calculations #define REMOVE_UNUSED_THERMAL_STUBS // Can be commented to skip unused thermal stubs calculations
#ifdef REMOVE_UNUSED_THERMAL_STUBS #ifdef REMOVE_UNUSED_THERMAL_STUBS
// first compute endindex for TestPointInsidePolygon
/* First, Create the list of filled areas begin and end indexes.
* Because a zone creates more than one filled sub area,
* we must handle all start and end points of all sub areas
* for TestPointInsidePolygon, to search if a point is in a filled area in zone
*/
std::vector <int> filled_areas_begin_end_index_list;
unsigned int indexstart = 0, indexend; unsigned int indexstart = 0, indexend;
for( indexend = 0; indexend < m_FilledPolysList.size(); indexend++ ) for( indexend = 0; indexend < m_FilledPolysList.size(); indexend++ )
{ {
if( m_FilledPolysList[indexend].end_contour ) // end of a filled sub-area found if( m_FilledPolysList[indexend].end_contour ) // end of a filled sub-area found
{ {
break; filled_areas_begin_end_index_list.push_back( indexstart );
filled_areas_begin_end_index_list.push_back( indexend );
indexstart = indexend + 1;
} }
} }
...@@ -328,67 +343,90 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb ) ...@@ -328,67 +343,90 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
for( D_PAD* pad = module->m_Pads; pad != NULL; pad = pad->Next() ) for( D_PAD* pad = module->m_Pads; pad != NULL; pad = pad->Next() )
{ {
// check // check
if( pad->IsOnLayer( GetLayer() ) if( !pad->IsOnLayer( GetLayer() ) )
&& pad->GetNet() == GetNet() continue;
&& m_PadOption == THERMAL_PAD ) if( pad->GetNet() != GetNet() )
{ continue;
item_boundingbox = pad->GetBoundingBox(); item_boundingbox = pad->GetBoundingBox();
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 ) ) )
continue; continue;
// test point // test point
int dx = (pad->m_Size.x / 2) + m_ThermalReliefGapValue + 3; int dx =
int dy = (pad->m_Size.y / 2) + m_ThermalReliefGapValue + 3; ( pad->m_Size.x / 2 ) + m_ThermalReliefGapValue;
int dy =
// compute north, south, west and east points for zone connection. ( pad->m_Size.y / 2 ) + m_ThermalReliefGapValue;
wxPoint ptTest[4];
ptTest[0] = wxPoint(0, dy+m_ZoneMinThickness/2);
ptTest[1] = wxPoint(0, -(dy+m_ZoneMinThickness/2));
ptTest[2] = wxPoint( dx+m_ZoneMinThickness/2, 0);
ptTest[3] = wxPoint(-(dx+m_ZoneMinThickness/2), 0);
// This is CIRCLE pad tweak (for circle pads the thermal stubs are at 45 deg) // This is CIRCLE pad tweak (for circle pads the thermal stubs are at 45 deg)
int fAngle = pad->m_Orient; int fAngle = pad->m_Orient;
if ( pad->m_PadShape == PAD_CIRCLE) if( pad->m_PadShape == PAD_CIRCLE )
{ {
dx = (int) (dx * s_Correction); dx = (int) ( dx * s_Correction );
dy = dx; dy = dx;
fAngle = 450; fAngle = 450;
} }
// compute north, south, west and east points for zone connection.
// Add a small value to ensure point is inside zone, not on an edge
wxPoint ptTest[4];
ptTest[0] = wxPoint( 0, 3 + dy + m_ZoneMinThickness / 2 );
ptTest[1] = wxPoint( 0, -(3 + dy + m_ZoneMinThickness / 2) );
ptTest[2] = wxPoint( 3 + dx + m_ZoneMinThickness / 2, 0 );
ptTest[3] = wxPoint( -(3 + dx + m_ZoneMinThickness / 2), 0 );
// Test all sides // Test all sides
for (int i=0; i<4; i++) { for( int i = 0; i<4; i++ )
{
// rotate point // rotate point
RotatePoint( &ptTest[i], fAngle ); RotatePoint( &ptTest[i], fAngle );
// translate point // translate point
ptTest[i] += pad->ReturnShapePos(); ptTest[i] += pad->ReturnShapePos();
if ( TestPointInsidePolygon( m_FilledPolysList, indexstart, bool inside = false;
indexend, ptTest[i].x, ptTest[i].y ) == false) for( unsigned idx = 0;
idx < filled_areas_begin_end_index_list.size() && inside == false;
idx += 2 )
{
indexstart = filled_areas_begin_end_index_list[idx];
indexend = filled_areas_begin_end_index_list[idx + 1];
inside = TestPointInsidePolygon( m_FilledPolysList, indexstart,
indexend, ptTest[i].x, ptTest[i].y );
}
if( inside == false )
{ {
// polygon buffer // polygon buffer
std::vector<wxPoint> corners_buffer; std::vector<wxPoint> corners_buffer;
// polygons are rectangles with width of copper bridge value // polygons are rectangles with width of copper bridge value
const int iDTRC = m_ThermalReliefCopperBridgeValue / 2; const int iDTRC = m_ThermalReliefCopperBridgeValue / 2;
switch (i) {
switch( i )
{
case 0: case 0:
corners_buffer.push_back( wxPoint( -iDTRC, dy) ); corners_buffer.push_back( wxPoint( -iDTRC, dy ) );
corners_buffer.push_back( wxPoint( +iDTRC, dy) ); corners_buffer.push_back( wxPoint( +iDTRC, dy ) );
corners_buffer.push_back( wxPoint( +iDTRC, iDTRC ) ); corners_buffer.push_back( wxPoint( +iDTRC, iDTRC ) );
corners_buffer.push_back( wxPoint( -iDTRC, iDTRC ) ); corners_buffer.push_back( wxPoint( -iDTRC, iDTRC ) );
break; break;
case 1: case 1:
corners_buffer.push_back( wxPoint( -iDTRC, -dy ) ); corners_buffer.push_back( wxPoint( -iDTRC, -dy ) );
corners_buffer.push_back( wxPoint( +iDTRC, -dy ) ); corners_buffer.push_back( wxPoint( +iDTRC, -dy ) );
corners_buffer.push_back( wxPoint( +iDTRC, -iDTRC ) ); corners_buffer.push_back( wxPoint( +iDTRC, -iDTRC ) );
corners_buffer.push_back( wxPoint( -iDTRC, -iDTRC ) ); corners_buffer.push_back( wxPoint( -iDTRC, -iDTRC ) );
break; break;
case 2: case 2:
corners_buffer.push_back( wxPoint( dx, -iDTRC ) ); corners_buffer.push_back( wxPoint( dx, -iDTRC ) );
corners_buffer.push_back( wxPoint( dx, iDTRC ) ); corners_buffer.push_back( wxPoint( dx, iDTRC ) );
corners_buffer.push_back( wxPoint( +iDTRC, iDTRC ) ); corners_buffer.push_back( wxPoint( +iDTRC, iDTRC ) );
corners_buffer.push_back( wxPoint( +iDTRC, -iDTRC ) ); corners_buffer.push_back( wxPoint( +iDTRC, -iDTRC ) );
break; break;
case 3: case 3:
corners_buffer.push_back( wxPoint( -dx, -iDTRC ) ); corners_buffer.push_back( wxPoint( -dx, -iDTRC ) );
corners_buffer.push_back( wxPoint( -dx, iDTRC ) ); corners_buffer.push_back( wxPoint( -dx, iDTRC ) );
...@@ -396,6 +434,7 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb ) ...@@ -396,6 +434,7 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
corners_buffer.push_back( wxPoint( -iDTRC, -iDTRC ) ); corners_buffer.push_back( wxPoint( -iDTRC, -iDTRC ) );
break; break;
} }
// add computed polygon to group_B // add computed polygon to group_B
if( booleng->StartPolygonAdd( GROUP_B ) ) if( booleng->StartPolygonAdd( GROUP_B ) )
{ {
...@@ -413,7 +452,6 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb ) ...@@ -413,7 +452,6 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
} }
} }
} }
}
/* compute copper areas */ /* compute copper areas */
booleng->Do_Operation( BOOL_A_SUB_B ); booleng->Do_Operation( BOOL_A_SUB_B );
...@@ -423,11 +461,10 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb ) ...@@ -423,11 +461,10 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
CopyPolygonsFromBoolengineToFilledPolysList( booleng ); CopyPolygonsFromBoolengineToFilledPolysList( booleng );
delete booleng; delete booleng;
#endif // Remove insulated islands, if any:
// Remove insulated islands:
if( GetNet() > 0 ) if( GetNet() > 0 )
Test_For_Copper_Island_And_Remove_Insulated_Islands( aPcb ); Test_For_Copper_Island_And_Remove_Insulated_Islands( aPcb );
#endif
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment