diff --git a/common/trigo.cpp b/common/trigo.cpp index ab1078db17..2fc4b7ffc3 100644 --- a/common/trigo.cpp +++ b/common/trigo.cpp @@ -249,8 +249,10 @@ void RotatePoint( int* pX, int* pY, int angle ) else { double fangle = DEG2RAD( (double) angle / 10.0 ); - double fpx = (*pY * sin( fangle ) ) + (*pX * cos( fangle ) ); - double fpy = (*pY * cos( fangle ) ) - (*pX * sin( fangle ) ); + double sinus = sin( fangle ); + double cosinus = cos( fangle ); + double fpx = (*pY * sinus ) + (*pX * cosinus ); + double fpy = (*pY * cosinus ) - (*pX * sinus ); *pX = wxRound( fpx ); *pY = wxRound( fpy ); } @@ -345,9 +347,11 @@ void RotatePoint( double* pX, double* pY, int angle ) else { double fangle = DEG2RAD( (double) angle / 10.0 ); + double sinus = sin( fangle ); + double cosinus = cos( fangle ); - double fpx = (*pY * sin( fangle ) ) + (*pX * cos( fangle ) ); - double fpy = (*pY * cos( fangle ) ) - (*pX * sin( fangle ) ); + double fpx = (*pY * sinus ) + (*pX * cosinus ); + double fpy = (*pY * cosinus ) - (*pX * sinus ); *pX = fpx; *pY = fpy; } diff --git a/include/wxBasePcbFrame.h b/include/wxBasePcbFrame.h index e1d29a619d..99bedde38f 100644 --- a/include/wxBasePcbFrame.h +++ b/include/wxBasePcbFrame.h @@ -441,15 +441,14 @@ public: * according to its net code. and when nets are changed (when a new netlist is read) * tracks are sorted before using this function. *

- * @param aDC = current Device Context */ - void TestConnections( wxDC* aDC ); + void TestConnections(); /** * Function TestNetConnection * tests the connections relative to \a aNetCode. Track segments are assumed to be * sorted by net codes. - * @param aDC Cyrrent Device Context + * @param aDC Current Device Context * @param aNetCode The net code to test */ void TestNetConnection( wxDC* aDC, int aNetCode ); @@ -458,10 +457,6 @@ public: * Function RecalculateAllTracksNetcode * search connections between tracks and pads and propagate pad net codes to the track * segments. - *

- * This is a 2 pass computation. First we search a connection between a track segment - * and a pad. If the connection is found, the segment netcode is set to the pad netcode. - *

*/ void RecalculateAllTracksNetcode(); diff --git a/include/wxPcbStruct.h b/include/wxPcbStruct.h index 985811c5ca..c4d1f8c73a 100644 --- a/include/wxPcbStruct.h +++ b/include/wxPcbStruct.h @@ -1138,20 +1138,20 @@ public: * The zone outline is a frontier, and can be complex (with holes) * The filling starts from starting points like pads, tracks. * If exists the old filling is removed - * @param zone_container = zone to fill - * @param verbose = true to show error messages + * @param aZone = zone to fill * @return error level (0 = no error) */ - int Fill_Zone( ZONE_CONTAINER* zone_container, bool verbose = true ); + int Fill_Zone( ZONE_CONTAINER* aZone ); /** * Function Fill_All_Zones * Fill all zones on the board * The old fillings are removed - * @param verbose = true to show error messages - * @return error level (0 = no error) + * @param aActiveWindow = the current active window, if a progress bar is shown + * = NULL to do not display a progress bar + * @param aVerbose = true to show error messages */ - int Fill_All_Zones( bool verbose = true ); + int Fill_All_Zones( wxWindow * aActiveWindow, bool aVerbose = true ); /** diff --git a/pcbnew/connect.cpp b/pcbnew/connect.cpp index f0caf6d7d0..5d671a2282 100644 --- a/pcbnew/connect.cpp +++ b/pcbnew/connect.cpp @@ -511,7 +511,7 @@ void CONNECTIONS::Propagate_SubNets() } } -void PCB_BASE_FRAME::TestConnections( wxDC* aDC ) +void PCB_BASE_FRAME::TestConnections() { // Clear the cluster identifier for all pads for( unsigned i = 0; i< m_Pcb->GetPadsCount(); ++i ) diff --git a/pcbnew/drc.cpp b/pcbnew/drc.cpp index 53f932a3cd..3a56becf37 100644 --- a/pcbnew/drc.cpp +++ b/pcbnew/drc.cpp @@ -230,7 +230,7 @@ void DRC::RunTests( wxTextCtrl* aMessages ) aMessages->AppendText( _( "Track clearances...\n" ) ); wxSafeYield(); } - testTracks(); + testTracks( true ); // Before testing segments and unconnected, refill all zones: // this is a good caution, because filled areas can be outdated. @@ -240,17 +240,16 @@ void DRC::RunTests( wxTextCtrl* aMessages ) wxSafeYield(); } - m_mainWindow->Fill_All_Zones( false ); - wxSafeYield(); + m_mainWindow->Fill_All_Zones( aMessages->GetParent(), false ); - // test zone clearances to other zones, pads, tracks, and vias - if( aMessages && m_doZonesTest ) + // test zone clearances to other zones + if( aMessages ) { aMessages->AppendText( _( "Test zones...\n" ) ); wxSafeYield(); } - testZones( m_doZonesTest ); + testZones(); // find and gather unconnected pads. if( m_doUnconnectedTest ) @@ -457,10 +456,44 @@ void DRC::testPad2Pad() } -void DRC::testTracks() +#include +/* Function testTracks + * performs the DRC on all tracks. + * because this test can take a while, a progrsse bar can be displayed + * (Note: it is shown only if there are many tracks + */ +void DRC::testTracks( bool aShowProgressBar ) { - for( TRACK* segm = m_pcb->m_Track; segm && segm->Next(); segm = segm->Next() ) + wxProgressDialog * progressDialog = NULL; + const int delta = 500; // This is the number of tests between 2 calls to the + // progress bar + int count = 0; + for( TRACK* segm = m_pcb->m_Track; segm && segm->Next(); segm = segm->Next() ) + count++; + + int deltamax = count/delta; + if( aShowProgressBar && deltamax > 3 ) { + progressDialog = new wxProgressDialog( _( "Track clearances" ), wxEmptyString, + deltamax, m_mainWindow, + wxPD_AUTO_HIDE | wxPD_CAN_ABORT ); + progressDialog->Update( 0, wxEmptyString ); + } + + int ii = 0; + count = 0; + for( TRACK* segm = m_pcb->m_Track; segm && segm->Next(); segm = segm->Next() ) + { + if ( ii++ > delta ) + { + ii = 0; + count++; + if( progressDialog ) + { + if( !progressDialog->Update( count, wxEmptyString ) ) + break; // Aborted by user + } + } if( !doTrackDrc( segm, segm->Next(), true ) ) { wxASSERT( m_currentMarker ); @@ -468,6 +501,8 @@ void DRC::testTracks() m_currentMarker = 0; } } + if( progressDialog ) + progressDialog->Destroy(); } @@ -484,13 +519,13 @@ void DRC::testUnconnected() for( unsigned ii = 0; ii < m_pcb->GetRatsnestsCount(); ++ii ) { - RATSNEST_ITEM* rat = &m_pcb->m_FullRatsnest[ii]; + RATSNEST_ITEM& rat = m_pcb->m_FullRatsnest[ii]; - if( (rat->m_Status & CH_ACTIF) == 0 ) + if( (rat.m_Status & CH_ACTIF) == 0 ) continue; - D_PAD* padStart = rat->m_PadStart; - D_PAD* padEnd = rat->m_PadEnd; + D_PAD* padStart = rat.m_PadStart; + D_PAD* padEnd = rat.m_PadEnd; DRC_ITEM* uncItem = new DRC_ITEM( DRCE_UNCONNECTED_PADS, padStart->GetSelectMenuText(), @@ -502,7 +537,7 @@ void DRC::testUnconnected() } -void DRC::testZones( bool adoTestFillSegments ) +void DRC::testZones() { // Test copper areas for valid netcodes // if a netcode is < 0 the netname was not found when reading a netlist @@ -526,35 +561,6 @@ void DRC::testZones( bool adoTestFillSegments ) // Test copper areas outlines, and create markers when needed m_pcb->Test_Drc_Areas_Outlines_To_Areas_Outlines( NULL, true ); - - TRACK* zoneSeg; - - if( !adoTestFillSegments ) - return; - - // m_pcb->m_Zone is fully obsolete. Keep this test for compatibility - // with old designs. Will be removed on day - for( zoneSeg = m_pcb->m_Zone; zoneSeg && zoneSeg->Next(); zoneSeg = zoneSeg->Next() ) - { - // Test zoneSeg with other zone segments and with all pads - if( !doTrackDrc( zoneSeg, zoneSeg->Next(), true ) ) - { - wxASSERT( m_currentMarker ); - m_pcb->Add( m_currentMarker ); - m_currentMarker = 0; - } - - // Pads already tested: disable pad test - - bool rc = doTrackDrc( zoneSeg, m_pcb->m_Track, false ); - - if( !rc ) - { - wxASSERT( m_currentMarker ); - m_pcb->Add( m_currentMarker ); - m_currentMarker = 0; - } - } } diff --git a/pcbnew/drc_clearance_test_functions.cpp b/pcbnew/drc_clearance_test_functions.cpp index c58baf7be5..63358f1436 100644 --- a/pcbnew/drc_clearance_test_functions.cpp +++ b/pcbnew/drc_clearance_test_functions.cpp @@ -338,12 +338,10 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) // At this point the reference segment is the X axis // Test the reference segment with other track segments - for( track = aStart; track; track = track->Next() ) + wxPoint segStartPoint; + wxPoint segEndPoint; + for( track = aStart; track; track = track->Next() ) { - // coord des extremites du segment teste dans le repere modifie - wxPoint segStartPoint; - wxPoint segEndPoint; - // No problem if segments have the same net code: if( net_code_ref == track->GetNet() ) continue; @@ -401,10 +399,8 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) */ segStartPoint = track->m_Start - origin; segEndPoint = track->m_End - origin; - RotatePoint( &segStartPoint, m_segmAngle ); RotatePoint( &segEndPoint, m_segmAngle ); - if( track->Type() == PCB_VIA_T ) { if( checkMarginToCircle( segStartPoint, w_dist, m_segmLength ) ) diff --git a/pcbnew/drc_stuff.h b/pcbnew/drc_stuff.h index 2ed4b1ff56..c91874c8e1 100644 --- a/pcbnew/drc_stuff.h +++ b/pcbnew/drc_stuff.h @@ -263,13 +263,20 @@ private: */ bool testNetClasses(); - void testTracks(); + /** + * Function testTracks + * performs the DRC on all tracks. + * because this test can take a while, a progrsse bar can be displayed + * @param aShowProgressBar = true to show a progrsse bar + * (Note: it is shown only if there are many tracks + */ + void testTracks( bool aShowProgressBar ); void testPad2Pad(); void testUnconnected(); - void testZones( bool adoTestFillSegments ); + void testZones(); //---------------------------------------------- diff --git a/pcbnew/edit.cpp b/pcbnew/edit.cpp index 3414cce31f..e359b11ec1 100644 --- a/pcbnew/edit.cpp +++ b/pcbnew/edit.cpp @@ -529,7 +529,8 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) case ID_POPUP_PCB_FILL_ALL_ZONES: DrawPanel->MoveCursorToCrossHair(); - Fill_All_Zones(); + Fill_All_Zones( this ); + DrawPanel->Refresh(); GetBoard()->DisplayInfo( this ); break; @@ -557,7 +558,7 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) } SetCurItem( NULL ); // CurItem might be deleted by this command, clear the pointer - TestConnections( NULL ); + TestConnections(); TestForActiveLinksInRatsnest( 0 ); // Recalculate the active ratsnest, i.e. the unconnected links OnModify(); GetBoard()->DisplayInfo( this ); diff --git a/pcbnew/ratsnest.cpp b/pcbnew/ratsnest.cpp index 27b42054be..553adbf741 100644 --- a/pcbnew/ratsnest.cpp +++ b/pcbnew/ratsnest.cpp @@ -159,7 +159,7 @@ void PCB_BASE_FRAME::Compile_Ratsnest( wxDC* aDC, bool aDisplayStatus ) Build_Board_Ratsnest(); /* Compute the pad connections due to the existing tracks (physical connections) */ - TestConnections( aDC ); + TestConnections(); /* Compute the active ratsnest, i.e. the unconnected links */ @@ -294,22 +294,19 @@ void PCB_BASE_FRAME::DrawGeneralRatsnest( wxDC* aDC, int aNetcode ) /** * Function used by TestForActiveLinksInRatsnest - * Function testing the ratsnest between 2 blocks ( same net ) + * Function testing the ratsnest between 2 blocks ( of the same net ) * The search is made between pads in block 1 and the others blocks - * The block n ( n > 1 ) is merged with block 1 by the smallest ratsnest - * The analysis uses the general ratsnest list. - * The function activate the smallest ratsnest between block 1 and the block n - * (activate a logical connexion) + * The block n ( n > 1 ) is merged with block 1 and linked by the smallest ratsnest + * between block 1 and the block n (activate the logical connection) * @param aRatsnestBuffer = the buffer to store NETINFO_ITEM* items * @param aNetinfo = the current NETINFO_ITEM for the current net - * output: - * .state member of the ratsnest - * @return blocks not connected count + * output: .state member, bit CH_ACTIF of the ratsnest item + * @return last subratsnest id in use */ -static int tst_rats_block_to_block( NETINFO_ITEM* aNetinfo, +static int tst_links_between_blocks( NETINFO_ITEM* aNetinfo, vector& aRatsnestBuffer ) { - int current_num_block, min_block; + int subratsnest_id, min_id; RATSNEST_ITEM* link, * best_link; /* Search a link from a block to an other block */ @@ -340,35 +337,35 @@ static int tst_rats_block_to_block( NETINFO_ITEM* aNetinfo, * we must set its status to ACTIVE and merge the 2 blocks */ best_link->m_Status |= CH_ACTIF; - current_num_block = best_link->m_PadStart->GetSubRatsnest(); - min_block = best_link->m_PadEnd->GetSubRatsnest(); + subratsnest_id = best_link->m_PadStart->GetSubRatsnest(); + min_id = best_link->m_PadEnd->GetSubRatsnest(); - if( min_block > current_num_block ) - EXCHG( min_block, current_num_block ); + if( min_id > subratsnest_id ) + EXCHG( min_id, subratsnest_id ); // Merge the 2 blocks in one sub ratsnest: for( unsigned ii = 0; ii < aNetinfo->m_ListPad.size(); ii++ ) { - if( aNetinfo->m_ListPad[ii]->GetSubRatsnest() == current_num_block ) + if( aNetinfo->m_ListPad[ii]->GetSubRatsnest() == subratsnest_id ) { - aNetinfo->m_ListPad[ii]->SetSubRatsnest( min_block ); + aNetinfo->m_ListPad[ii]->SetSubRatsnest( min_id ); } } - return current_num_block; + return subratsnest_id; } /** * Function used by TestForActiveLinksInRatsnest_general * The general ratsnest list must exists because this function explores this ratsnest - * Activates (i.e. set the CH_ACTIF flag) the ratsnest links between 2 pads when needed - * The function links 1 pad not already connected to an other pad (SubRatsnest = 0) - * and active the correspondint link + * Activates (i.e. set the CH_ACTIF flag) the ratsnest links between 2 pads when + * at least one pad not already connected (SubRatsnest = 0) + * and actives the corresponding link * * @param aFirstItem = starting address for the ratsnest list * @param aLastItem = ending address for the ratsnest list - * @param aCurrSubRatsnestId = last block number (computed from the track + * @param aCurrSubRatsnestId = last sub ratsnest id in use (computed from the track * analysis) * * output: @@ -377,7 +374,7 @@ static int tst_rats_block_to_block( NETINFO_ITEM* aNetinfo, * * @return new block number */ -static int tst_rats_pad_to_pad( int aCurrSubRatsnestId, +static void tst_links_between_pads( int & aCurrSubRatsnestId, RATSNEST_ITEM* aFirstItem, RATSNEST_ITEM* aLastItem ) { @@ -411,8 +408,6 @@ static int tst_rats_pad_to_pad( int aCurrSubRatsnestId, item->m_Status |= CH_ACTIF; } } - - return aCurrSubRatsnestId; } /* function TestForActiveLinksInRatsnest @@ -461,13 +456,13 @@ void PCB_BASE_FRAME::TestForActiveLinksInRatsnest( int aNetCode ) continue; // Create subratsnests id from subnets created by existing tracks: - int num_block = 0; + int subratsnest = 0; for( unsigned ip = 0; ip < net->m_ListPad.size(); ip++ ) { pad = net->m_ListPad[ip]; int subnet = pad->GetSubNet(); pad->SetSubRatsnest( subnet ); - num_block = MAX( num_block, subnet ); + subratsnest = MAX( subratsnest, subnet ); } for( unsigned ii = net->m_RatsnestStartIdx; ii < net->m_RatsnestEndIdx; ii++ ) @@ -475,16 +470,16 @@ void PCB_BASE_FRAME::TestForActiveLinksInRatsnest( int aNetCode ) m_Pcb->m_FullRatsnest[ii].m_Status &= ~CH_ACTIF; } - // First pass - activate links for not connected pads pads + // First pass - activate links for not connected pads rats = &m_Pcb->m_FullRatsnest[0]; - int icnt = tst_rats_pad_to_pad( num_block, - rats + net->m_RatsnestStartIdx, - rats + net->m_RatsnestEndIdx ); + tst_links_between_pads( subratsnest, + rats + net->m_RatsnestStartIdx, + rats + net->m_RatsnestEndIdx ); // Second pass activate links between blocks (Iteration) - while( icnt > 1 ) + while( subratsnest > 1 ) { - icnt = tst_rats_block_to_block( net, m_Pcb->m_FullRatsnest ); + subratsnest = tst_links_between_blocks( net, m_Pcb->m_FullRatsnest ); } } @@ -751,16 +746,12 @@ void PCB_BASE_FRAME::TraceModuleRatsNest( wxDC* DC ) /* - * Construction of the list mode display for quick calculation - * in real time the net of a pad in the paths of a track starting - * on the pad. - * - * Parameters: - * Pad_ref (if null: 0 has put the number of ratsnest) - * Ox, oy = coord of extremity of the track record - * Init (flag) - * = 0: update of the ratsnest. - * <> 0: Creating a list + * PCB_BASE_FRAME::BuildAirWiresTargetsList and + * PCB_BASE_FRAME::TraceAirWiresToTargets + * are 2 function to show the near connecting points when + * a new track is created, by displaying g_MaxLinksShowed airwires + * between the on grid mouse cursor and these connecting points + * during the creation of a track */ /* Buffer to store pads coordinates when creating a track. diff --git a/pcbnew/zones_by_polygon_fill_functions.cpp b/pcbnew/zones_by_polygon_fill_functions.cpp index 3505f70f5c..55957c62bb 100644 --- a/pcbnew/zones_by_polygon_fill_functions.cpp +++ b/pcbnew/zones_by_polygon_fill_functions.cpp @@ -89,26 +89,18 @@ void PCB_EDIT_FRAME::Delete_OldZone_Fill( SEGZONE* aZone, long aTimestamp ) * The zone outline is a frontier, and can be complex (with holes) * The filling starts from starting points like pads, tracks. * If exists, the old filling is removed - * @param zone_container = zone to fill - * @param verbose = true to show error messages + * @param aZone = zone to fill * @return error level (0 = no error) */ -int PCB_EDIT_FRAME::Fill_Zone( ZONE_CONTAINER* zone_container, bool verbose ) +int PCB_EDIT_FRAME::Fill_Zone( ZONE_CONTAINER* aZone ) { wxString msg; ClearMsgPanel(); - if( GetBoard()->ComputeBoundingBox() == false ) - { - if( verbose ) - wxMessageBox( wxT( "Board is empty!" ) ); - return -1; - } - // Shows the net - g_Zone_Default_Setting.m_NetcodeSelection = zone_container->GetNet(); - msg = zone_container->GetNetName(); + g_Zone_Default_Setting.m_NetcodeSelection = aZone->GetNet(); + msg = aZone->GetNetName(); if( msg.IsEmpty() ) msg = wxT( "No net" ); @@ -117,9 +109,9 @@ int PCB_EDIT_FRAME::Fill_Zone( ZONE_CONTAINER* zone_container, bool verbose ) wxBusyCursor dummy; // Shows an hourglass cursor (removed by its destructor) - zone_container->m_FilledPolysList.clear(); - zone_container->UnFill(); - zone_container->BuildFilledPolysListData( GetBoard() ); + aZone->m_FilledPolysList.clear(); + aZone->UnFill(); + aZone->BuildFilledPolysListData( GetBoard() ); OnModify(); @@ -127,29 +119,34 @@ int PCB_EDIT_FRAME::Fill_Zone( ZONE_CONTAINER* zone_container, bool verbose ) } -/** +/* * Function Fill_All_Zones * Fill all zones on the board * The old fillings are removed - * @param verbose = true to show error messages - * @return error level (0 = no error) + * aActiveWindow = the current active window, if a progress bar is shown + * = NULL to do not display a progress bar + * aVerbose = true to show error messages + * return error level (0 = no error) */ -int PCB_EDIT_FRAME::Fill_All_Zones( bool verbose ) +int PCB_EDIT_FRAME::Fill_All_Zones( wxWindow * aActiveWindow, bool aVerbose ) { int errorLevel = 0; int areaCount = GetBoard()->GetAreaCount(); wxBusyCursor dummyCursor; wxString msg; #define FORMAT_STRING _( "Filling zone %d out of %d (net %s)..." ) + wxProgressDialog * progressDialog = NULL; // Create a message with a long net name, and build a wxProgressDialog // with a correct size to show this long net name msg.Printf( FORMAT_STRING, 000, areaCount, wxT("XXXXXXXXXXXXXXXXX" ) ); - wxProgressDialog progressDialog( _( "Fill All Zones" ), msg, - areaCount+2, this, - wxPD_AUTO_HIDE | wxPD_APP_MODAL | wxPD_CAN_ABORT ); + if( aActiveWindow ) + progressDialog = new wxProgressDialog( _( "Fill All Zones" ), msg, + areaCount+2, aActiveWindow, + wxPD_AUTO_HIDE | wxPD_CAN_ABORT ); // Display the actual message - progressDialog.Update( 0, _( "Starting zone fill..." ) ); + if( progressDialog ) + progressDialog->Update( 0, _( "Starting zone fill..." ) ); // Remove segment zones GetBoard()->m_Zone.DeleteAll(); @@ -161,21 +158,25 @@ int PCB_EDIT_FRAME::Fill_All_Zones( bool verbose ) ZONE_CONTAINER* zoneContainer = GetBoard()->GetArea( ii ); msg.Printf( FORMAT_STRING, ii+1, areaCount, GetChars( zoneContainer->GetNetName() ) ); - if( !progressDialog.Update( ii+1, msg ) ) - break; + if( progressDialog ) + { + if( !progressDialog->Update( ii+1, msg ) ) + break; // Aborted by user + } - errorLevel = Fill_Zone( zoneContainer, verbose ); + errorLevel = Fill_Zone( zoneContainer ); - if( errorLevel && !verbose ) + if( errorLevel && !aVerbose ) break; } - progressDialog.Update( ii+2, _( "Updating ratsnest..." ) ); - TestConnections( NULL ); + if( progressDialog ) + progressDialog->Update( ii+2, _( "Updating ratsnest..." ) ); + TestConnections(); // Recalculate the active ratsnest, i.e. the unconnected links TestForActiveLinksInRatsnest( 0 ); - DrawPanel->Refresh( true ); - + if( progressDialog ) + progressDialog->Destroy(); return errorLevel; }