Loading CHANGELOG.txt +8 −1 Original line number Diff line number Diff line Loading @@ -5,7 +5,14 @@ Started 2007-June-11 Please add newer entries at the top, list the date and your name with 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 * Replace Kicad file history implementation with wxFileHistory. Loading include/id.h +0 −11 Original line number Diff line number Diff line Loading @@ -48,17 +48,6 @@ enum main_id { ID_LOAD_PROJECT, ID_LOAD_ONE_SHEET, 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_ONE_SHEET, ID_SAVE_ONE_SHEET_AS, Loading pcbnew/pcbframe.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -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_APPEND_FILE, 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_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_FILE_GENCADFORMAT, WinEDA_PcbFrame::ExportToGenCAD ) Loading pcbnew/zones_convert_brd_items_to_polygons.cpp +124 −87 Original line number Diff line number Diff line Loading @@ -295,16 +295,31 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb ) 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. //#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 // 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; for( indexend = 0; indexend < m_FilledPolysList.size(); indexend++ ) { 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; } } Loading @@ -328,25 +343,21 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb ) for( D_PAD* pad = module->m_Pads; pad != NULL; pad = pad->Next() ) { // check if( pad->IsOnLayer( GetLayer() ) && pad->GetNet() == GetNet() && m_PadOption == THERMAL_PAD ) { if( !pad->IsOnLayer( GetLayer() ) ) continue; if( pad->GetNet() != GetNet() ) continue; item_boundingbox = pad->GetBoundingBox(); item_boundingbox.Inflate( m_ThermalReliefGapValue, m_ThermalReliefGapValue ); if( !( item_boundingbox.Intersects( zone_boundingbox ) ) ) continue; // test point int dx = (pad->m_Size.x / 2) + m_ThermalReliefGapValue + 3; int dy = (pad->m_Size.y / 2) + m_ThermalReliefGapValue + 3; // compute north, south, west and east points for zone connection. 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); int dx = ( pad->m_Size.x / 2 ) + m_ThermalReliefGapValue; int dy = ( pad->m_Size.y / 2 ) + m_ThermalReliefGapValue; // This is CIRCLE pad tweak (for circle pads the thermal stubs are at 45 deg) int fAngle = pad->m_Orient; Loading @@ -357,38 +368,65 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb ) 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 for (int i=0; i<4; i++) { for( int i = 0; i<4; i++ ) { // rotate point RotatePoint( &ptTest[i], fAngle ); // translate point ptTest[i] += pad->ReturnShapePos(); if ( TestPointInsidePolygon( m_FilledPolysList, indexstart, indexend, ptTest[i].x, ptTest[i].y ) == false) bool inside = 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 std::vector<wxPoint> corners_buffer; // polygons are rectangles with width of copper bridge value const int iDTRC = m_ThermalReliefCopperBridgeValue / 2; switch (i) { switch( i ) { case 0: 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 ) ); break; case 1: 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 ) ); break; case 2: 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 ) ); break; case 3: corners_buffer.push_back( wxPoint( -dx, -iDTRC ) ); corners_buffer.push_back( wxPoint( -dx, iDTRC ) ); Loading @@ -396,6 +434,7 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb ) corners_buffer.push_back( wxPoint( -iDTRC, -iDTRC ) ); break; } // add computed polygon to group_B if( booleng->StartPolygonAdd( GROUP_B ) ) { Loading @@ -413,7 +452,6 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb ) } } } } /* compute copper areas */ booleng->Do_Operation( BOOL_A_SUB_B ); Loading @@ -423,11 +461,10 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb ) CopyPolygonsFromBoolengineToFilledPolysList( booleng ); delete booleng; #endif // Remove insulated islands: // Remove insulated islands, if any: if( GetNet() > 0 ) Test_For_Copper_Island_And_Remove_Insulated_Islands( aPcb ); #endif } Loading Loading
CHANGELOG.txt +8 −1 Original line number Diff line number Diff line Loading @@ -5,7 +5,14 @@ Started 2007-June-11 Please add newer entries at the top, list the date and your name with 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 * Replace Kicad file history implementation with wxFileHistory. Loading
include/id.h +0 −11 Original line number Diff line number Diff line Loading @@ -48,17 +48,6 @@ enum main_id { ID_LOAD_PROJECT, ID_LOAD_ONE_SHEET, 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_ONE_SHEET, ID_SAVE_ONE_SHEET_AS, Loading
pcbnew/pcbframe.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -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_APPEND_FILE, 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_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_FILE_GENCADFORMAT, WinEDA_PcbFrame::ExportToGenCAD ) Loading
pcbnew/zones_convert_brd_items_to_polygons.cpp +124 −87 Original line number Diff line number Diff line Loading @@ -295,16 +295,31 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb ) 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. //#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 // 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; for( indexend = 0; indexend < m_FilledPolysList.size(); indexend++ ) { 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; } } Loading @@ -328,25 +343,21 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb ) for( D_PAD* pad = module->m_Pads; pad != NULL; pad = pad->Next() ) { // check if( pad->IsOnLayer( GetLayer() ) && pad->GetNet() == GetNet() && m_PadOption == THERMAL_PAD ) { if( !pad->IsOnLayer( GetLayer() ) ) continue; if( pad->GetNet() != GetNet() ) continue; item_boundingbox = pad->GetBoundingBox(); item_boundingbox.Inflate( m_ThermalReliefGapValue, m_ThermalReliefGapValue ); if( !( item_boundingbox.Intersects( zone_boundingbox ) ) ) continue; // test point int dx = (pad->m_Size.x / 2) + m_ThermalReliefGapValue + 3; int dy = (pad->m_Size.y / 2) + m_ThermalReliefGapValue + 3; // compute north, south, west and east points for zone connection. 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); int dx = ( pad->m_Size.x / 2 ) + m_ThermalReliefGapValue; int dy = ( pad->m_Size.y / 2 ) + m_ThermalReliefGapValue; // This is CIRCLE pad tweak (for circle pads the thermal stubs are at 45 deg) int fAngle = pad->m_Orient; Loading @@ -357,38 +368,65 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb ) 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 for (int i=0; i<4; i++) { for( int i = 0; i<4; i++ ) { // rotate point RotatePoint( &ptTest[i], fAngle ); // translate point ptTest[i] += pad->ReturnShapePos(); if ( TestPointInsidePolygon( m_FilledPolysList, indexstart, indexend, ptTest[i].x, ptTest[i].y ) == false) bool inside = 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 std::vector<wxPoint> corners_buffer; // polygons are rectangles with width of copper bridge value const int iDTRC = m_ThermalReliefCopperBridgeValue / 2; switch (i) { switch( i ) { case 0: 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 ) ); break; case 1: 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 ) ); break; case 2: 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 ) ); break; case 3: corners_buffer.push_back( wxPoint( -dx, -iDTRC ) ); corners_buffer.push_back( wxPoint( -dx, iDTRC ) ); Loading @@ -396,6 +434,7 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb ) corners_buffer.push_back( wxPoint( -iDTRC, -iDTRC ) ); break; } // add computed polygon to group_B if( booleng->StartPolygonAdd( GROUP_B ) ) { Loading @@ -413,7 +452,6 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb ) } } } } /* compute copper areas */ booleng->Do_Operation( BOOL_A_SUB_B ); Loading @@ -423,11 +461,10 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb ) CopyPolygonsFromBoolengineToFilledPolysList( booleng ); delete booleng; #endif // Remove insulated islands: // Remove insulated islands, if any: if( GetNet() > 0 ) Test_For_Copper_Island_And_Remove_Insulated_Islands( aPcb ); #endif } Loading