diff --git a/pcbnew/drc.cpp b/pcbnew/drc.cpp index 96e240faac..f3f1bd63ea 100644 --- a/pcbnew/drc.cpp +++ b/pcbnew/drc.cpp @@ -1252,1583 +1252,3 @@ bool DRC::checkLine( int x1, int y1, int x2, int y2 ) return true; } - - -#if 0 - -//----< new stuff above this line, old stuff below >------------------------ - - -/* saving drc options */ -static bool s_Pad2PadTestOpt = true; -static bool s_UnconnectedTestOpt = true; -static bool s_ZonesTestOpt = false; -static bool s_CreateRptFileOpt = false; -static FILE* s_RptFile = NULL; -static wxString s_RptFilename; - -static int ErrorsDRC_Count; -static MARKER* current_marqueur; /* Pour gestion des marqueurs sur pcb */ - -static bool AbortDrc, DrcInProgress = FALSE; -static int spot_cX, spot_cY; /* position d'elements a tester */ -static int finx, finy; // coord relatives de l'extremite du segm de reference -static int segm_angle; // angle d'inclinaison du segment de reference en 0,1 degre -static int segm_long; // longueur du segment de reference -static int xcliplo, ycliplo, xcliphi, ycliphi; /* coord de la surface de securite du segment a comparer */ - - -/************************************************************************/ -int WinEDA_PcbFrame::Test_DRC( wxDC* DC, bool TestPad2Pad, bool TestZone ) -/************************************************************************/ - -/* Test DRC : - * Run a drc control for each pad and track segment - * Put a marker on pad or track end which have a drc problem - */ -{ - int ii, jj, old_net; - int flag_err_Drc; - TRACK* pt_segm; - D_PAD* pad; - MARQUEUR* Marqueur; - EDA_BaseStruct* PtStruct; - wxString Line; - -#define PRINT_NB_PAD_POS 42 -#define PRINT_PAD_ERR_POS 48 -#define PRINT_TST_POS 20 -#define PRINT_NB_SEGM_POS 26 -#define PRINT_TRACK_ERR_POS 32 -#define PRINT_NB_ZONESEGM_POS 60 -#define PRINT_ZONE_ERR_POS 70 - - DrcInProgress = TRUE; - ErrorsDRC_Count = 0; - Compile_Ratsnest( DC, TRUE ); - - MsgPanel->EraseMsgBox(); - - m_CurrentScreen->SetRefreshReq(); - - /* Delete previous markers */ - Erase_Marqueurs(); - - if( TestPad2Pad ) /* First test: Test DRC between pads (no track)*/ - { - Line.Printf( wxT( "%d" ), m_Pcb->m_NbPads ); - Affiche_1_Parametre( this, PRINT_NB_PAD_POS, wxT( "NbPad" ), Line, RED ); - Affiche_1_Parametre( this, PRINT_PAD_ERR_POS, wxT( "Pad Err" ), wxT( "0" ), LIGHTRED ); - - if( DrcFrame ) - DrcFrame->m_logWindow->AppendText( _( "Tst Pad to Pad\n" ) ); - - LISTE_PAD* pad_list_start = CreateSortedPadListByXCoord( m_Pcb ); - LISTE_PAD* pad_list_limit = &pad_list_start[m_Pcb->m_NbPads]; - int max_size = 0; - LISTE_PAD* pad_list; - - /* Compute the max size of the pads ( used to stop the test) */ - for( pad_list = pad_list_start; pad_list < pad_list_limit; pad_list++ ) - { - pad = *pad_list; - if( pad->m_Rayon > max_size ) - max_size = pad->m_Rayon; - } - - /* Test the pads */ - for( pad_list = pad_list_start; pad_list < pad_list_limit; pad_list++ ) - { - pad = *pad_list; - if( Test_Pad_to_Pads_Drc( this, DC, pad, pad_list, pad_list_limit, max_size, - TRUE ) == BAD_DRC ) - { - Marqueur = current_marqueur; - current_marqueur = NULL; - if( Marqueur == NULL ) - { - DisplayError( this, wxT( "Test_Drc(): internal err" ) ); - return ErrorsDRC_Count; - } - Line.Printf( wxT( "%d" ), ErrorsDRC_Count ); - Affiche_1_Parametre( this, PRINT_PAD_ERR_POS, wxEmptyString, Line, LIGHTRED ); - Marqueur->Pnext = m_Pcb->m_Drawings; - Marqueur->Pback = m_Pcb; - - PtStruct = m_Pcb->m_Drawings; - if( PtStruct ) - PtStruct->Pback = Marqueur; - m_Pcb->m_Drawings = Marqueur; - } - } - - free( pad_list_start ); - } - - /* Test track segments */ - Line.Printf( wxT( "%d" ), m_Pcb->m_NbSegmTrack ); - Affiche_1_Parametre( this, PRINT_NB_SEGM_POS, _( "SegmNb" ), Line, RED ); - Affiche_1_Parametre( this, PRINT_TRACK_ERR_POS, _( "Track Err" ), wxT( "0" ), LIGHTRED ); - pt_segm = m_Pcb->m_Track; - - if( DrcFrame ) - DrcFrame->m_logWindow->AppendText( _( "Tst Tracks\n" ) ); - - for( ii = 0, old_net = -1, jj = 0; - pt_segm != NULL; - pt_segm = (TRACK*) pt_segm->Pnext, ii++, jj-- ) - { - if( pt_segm->Pnext == NULL ) - break; - - if( jj == 0 ) - { - jj = 10; - wxYield(); - if( AbortDrc ) - { - AbortDrc = FALSE; break; - } - /* Print stats */ - Line.Printf( wxT( "%d" ), ii ); - Affiche_1_Parametre( this, PRINT_TST_POS, wxT( "Test" ), Line, CYAN ); - } - - if( old_net != pt_segm->GetNet() ) - { - wxString msg; - jj = 1; - EQUIPOT* equipot = m_Pcb->FindNet( pt_segm->GetNet() ); - if( equipot ) - msg = equipot->m_Netname + wxT( " " ); - else - msg = wxT( "" ); - Affiche_1_Parametre( this, 0, _( "Netname" ), msg, YELLOW ); - old_net = pt_segm->GetNet(); - } - - g_HightLigth_NetCode = pt_segm->GetNet(); - flag_err_Drc = Drc( this, DC, pt_segm, (TRACK*) pt_segm->Pnext, 1 ); - if( flag_err_Drc == BAD_DRC ) - { - Marqueur = current_marqueur; - current_marqueur = NULL; - if( Marqueur == NULL ) - { - DisplayError( this, wxT( "Test_Drc(): internal err" ) ); - return ErrorsDRC_Count; - } - Marqueur->Pnext = m_Pcb->m_Drawings; - Marqueur->Pback = m_Pcb; - - PtStruct = m_Pcb->m_Drawings; - if( PtStruct ) - PtStruct->Pback = Marqueur; - m_Pcb->m_Drawings = Marqueur; - - GRSetDrawMode( DC, GR_OR ); - pt_segm->Draw( DrawPanel, DC, RED ^ LIGHTRED ); - Line.Printf( wxT( "%d" ), ErrorsDRC_Count ); - Affiche_1_Parametre( this, PRINT_TRACK_ERR_POS, wxEmptyString, Line, LIGHTRED ); - } - } - - /* Test zone segments */ - if( TestZone ) - { - m_Pcb->m_NbSegmZone = 0; - for( pt_segm = (TRACK*) m_Pcb->m_Zone; pt_segm != NULL; pt_segm = (TRACK*) pt_segm->Pnext ) - m_Pcb->m_NbSegmZone++; - - Line.Printf( wxT( "%d" ), m_Pcb->m_NbSegmZone ); - Affiche_1_Parametre( this, PRINT_NB_ZONESEGM_POS, _( "SegmNb" ), Line, RED ); - Affiche_1_Parametre( this, PRINT_ZONE_ERR_POS, _( "Zone Err" ), wxT( "0" ), LIGHTRED ); - - if( DrcFrame ) - DrcFrame->m_logWindow->AppendText( _( "Tst Zones\n" ) ); - - pt_segm = (TRACK*) m_Pcb->m_Zone; - - for( ii = 0, old_net = -1, jj = 0; - pt_segm != NULL; - pt_segm = (TRACK*) pt_segm->Pnext, ii++, jj-- ) - { - if( pt_segm->Pnext == NULL ) - break; - - if( jj == 0 ) - { - jj = 100; - wxYield(); - if( AbortDrc ) - { - AbortDrc = FALSE; - break; - } - /* Print stats */ - Line.Printf( wxT( "%d" ), ii ); - Affiche_1_Parametre( this, PRINT_TST_POS, wxT( "Test" ), Line, CYAN ); - } - - if( old_net != pt_segm->GetNet() ) - { - jj = 1; - wxString msg; - EQUIPOT* equipot = m_Pcb->FindNet( pt_segm->GetNet() ); - - if( equipot ) - msg = equipot->m_Netname + wxT( " " ); - else - msg = wxT( "" ); - - Affiche_1_Parametre( this, 0, _( "Netname" ), msg, YELLOW ); - old_net = pt_segm->GetNet(); - } - g_HightLigth_NetCode = pt_segm->GetNet(); - - /* Test drc with other zone segments, and pads */ - flag_err_Drc = Drc( this, DC, pt_segm, (TRACK*) pt_segm->Pnext, 1 ); - if( flag_err_Drc == BAD_DRC ) - { - Marqueur = current_marqueur; - current_marqueur = NULL; - if( Marqueur == NULL ) - { - DisplayError( this, wxT( "Test_Drc(): internal err" ) ); - return ErrorsDRC_Count; - } - Marqueur->Pnext = m_Pcb->m_Drawings; - Marqueur->Pback = m_Pcb; - - PtStruct = m_Pcb->m_Drawings; - if( PtStruct ) - PtStruct->Pback = Marqueur; - m_Pcb->m_Drawings = Marqueur; - - GRSetDrawMode( DC, GR_OR ); - pt_segm->Draw( DrawPanel, DC, RED ^ LIGHTRED ); - Line.Printf( wxT( "%d" ), ErrorsDRC_Count ); - Affiche_1_Parametre( this, PRINT_ZONE_ERR_POS, wxEmptyString, Line, LIGHTRED ); - } - - /* Test drc with track segments */ - int tmp = m_Pcb->m_NbPads; - m_Pcb->m_NbPads = 0; // Pads already tested: disable pad test - flag_err_Drc = Drc( this, DC, pt_segm, m_Pcb->m_Track, 1 ); - - m_Pcb->m_NbPads = tmp; - - if( flag_err_Drc == BAD_DRC ) - { - Marqueur = current_marqueur; - current_marqueur = NULL; - if( Marqueur == NULL ) - { - DisplayError( this, wxT( "Test_Drc(): internal err" ) ); - return ErrorsDRC_Count; - } - Marqueur->Pnext = m_Pcb->m_Drawings; - Marqueur->Pback = m_Pcb; - - PtStruct = m_Pcb->m_Drawings; - if( PtStruct ) - PtStruct->Pback = Marqueur; - - m_Pcb->m_Drawings = Marqueur; - - GRSetDrawMode( DC, GR_OR ); - pt_segm->Draw( DrawPanel, DC, RED ^ LIGHTRED ); - Line.Printf( wxT( "%d" ), ErrorsDRC_Count ); - Affiche_1_Parametre( this, PRINT_ZONE_ERR_POS, wxEmptyString, Line, LIGHTRED ); - } - } - } - - AbortDrc = FALSE; - DrcInProgress = FALSE; - return ErrorsDRC_Count; -} - - -/***************************************************************/ -void DrcDialog::ListUnconnectedPads( wxCommandEvent& event ) -/***************************************************************/ -{ - if( (m_Parent->m_Pcb->m_Status_Pcb & LISTE_CHEVELU_OK) == 0 ) - { - m_Parent->Compile_Ratsnest( m_DC, TRUE ); - } - if( m_Parent->m_Pcb->m_Ratsnest == NULL ) - return; - - CHEVELU* Ratsnest = m_Parent->m_Pcb->m_Ratsnest; - int draw_mode = GR_SURBRILL | GR_OR; - WinEDA_DrawPanel* panel = m_Parent->DrawPanel; - int ii; - wxString msg; - double convert = 0.0001; - - msg = _( "Look for active routes\n" ); -// m_logWindow->AppendText( msg ); - if( s_RptFile ) - fprintf( s_RptFile, "%s", CONV_TO_UTF8( msg ) ); - - m_UnconnectedCount = 0; - for( ii = m_Parent->m_Pcb->GetNumRatsnests(); ii > 0; Ratsnest++, ii-- ) - { - if( (Ratsnest->status & CH_ACTIF) == 0 ) - continue; - - m_UnconnectedCount++; - if( m_UnconnectedCount == 1 ) - { -// m_logWindow->AppendText( _( "Unconnected found:\n" ) ); - } - - D_PAD* pad = Ratsnest->pad_start; - pad->Draw( panel, m_DC, wxPoint( 0, 0 ), draw_mode ); - - wxString pad_name = pad->ReturnStringPadName(); - wxString module_name = ( (MODULE*) (pad->m_Parent) )->m_Reference->m_Text; - - msg.Printf( _( "%d > Pad %s (%s) @ %.4f,%.4f and " ), m_UnconnectedCount, - pad_name.GetData(), module_name.GetData(), - pad->m_Pos.x * convert, pad->m_Pos.y * convert ); - -// m_logWindow->AppendText( msg ); - if( s_RptFile ) - fprintf( s_RptFile, "%s", CONV_TO_UTF8( msg ) ); - - pad = Ratsnest->pad_end; - pad->Draw( panel, m_DC, wxPoint( 0, 0 ), draw_mode ); - - pad_name = pad->ReturnStringPadName(); - module_name = ( (MODULE*) (pad->m_Parent) )->m_Reference->m_Text; - - msg.Printf( _( "Pad %s (%s) @ %.4f,%.4f\n" ), - pad_name.GetData(), module_name.GetData(), - pad->m_Pos.x * convert, pad->m_Pos.y * convert ); - -// m_logWindow->AppendText( msg ); - if( s_RptFile ) - fprintf( s_RptFile, "%s", CONV_TO_UTF8( msg ) ); - } - - if( m_UnconnectedCount ) - msg.Printf( _( "Active routes: %d\n" ), m_UnconnectedCount ); - else - msg = _( "OK! (No active routes)\n" ); - -// m_logWindow->AppendText( msg ); - if( s_RptFile ) - fprintf( s_RptFile, "%s", CONV_TO_UTF8( msg ) ); -} - - -/****************************************************/ -void DrcDialog::TestDrc( wxCommandEvent& event ) -/****************************************************/ -{ - int errors; - wxString msg; - - if( !DrcInProgress ) - { - if( m_CreateRptCtrl->IsChecked() ) // Create a file rpt - { - s_RptFilename = m_RptFilenameCtrl->GetValue(); - - if( s_RptFilename.IsEmpty() ) - OnButtonBrowseRptFileClick( event ); - - if( !s_RptFilename.IsEmpty() ) - s_RptFile = wxFopen( s_RptFilename, wxT( "w" ) ); - else - s_RptFile = NULL; - } - - if( s_RptFile ) - { - fprintf( s_RptFile, "Drc report for %s\n", - CONV_TO_UTF8( m_Parent->m_CurrentScreen->m_FileName ) ); - char line[256]; - fprintf( s_RptFile, "Created on %s\n", DateAndTime( line ) ); - } - - s_Pad2PadTestOpt = m_Pad2PadTestCtrl->IsChecked(); - s_UnconnectedTestOpt = m_UnconnectedTestCtrl->IsChecked(); - - s_ZonesTestOpt = m_ZonesTestCtrl->IsChecked(); - - AbortDrc = FALSE; - m_logWindow->Clear(); - g_DesignSettings.m_TrackClearence = - ReturnValueFromTextCtrl( *m_SetClearance, m_Parent->m_InternalUnits ); - - /* Test DRC errors (clearance errors, bad connections .. */ - errors = m_Parent->Test_DRC( m_DC, m_Pad2PadTestCtrl->IsChecked( - ), m_ZonesTestCtrl->IsChecked() ); - - /* Search for active routes (unconnected pads) */ - if( m_UnconnectedTestCtrl->IsChecked() ) - ListUnconnectedPads( event ); - else - m_UnconnectedCount = 0; - - if( errors ) - msg.Printf( _( "** End Drc: %d errors **\n" ), errors ); - else if( m_UnconnectedCount == 0 ) - msg = _( "** End Drc: No Error **\n" ); - - m_logWindow->AppendText( msg ); - - if( s_RptFile ) - fprintf( s_RptFile, "%s", CONV_TO_UTF8( msg ) ); - - if( s_RptFile ) - { - msg.Printf( _( "Report file <%s> created\n" ), s_RptFilename.GetData() ); - m_logWindow->AppendText( msg ); - fclose( s_RptFile ); - s_RptFile = NULL; - } - } - else - wxBell(); -} - - -/*********************************************************/ -void DrcDialog::DelDRCMarkers( wxCommandEvent& event ) -/*********************************************************/ -{ - m_Parent->Erase_Marqueurs(); - m_Parent->DrawPanel->ReDraw( m_DC, TRUE ); -} - - -/***********************************************************************/ -int Drc( WinEDA_BasePcbFrame* frame, wxDC* DC, - TRACK* pt_segment, TRACK* StartBuffer, int show_err ) -/***********************************************************************/ - -/** - * Test the current segment: - * @param pt_segment = current segment to test - * @param StartBuffer = track buffer to test (usually m_Pcb->m_Track) - * @param show_err (flag) si 0 pas d'affichage d'erreur sur ecran - * @return : BAD_DRC (1) if DRC error or OK_DRC (0) if OK - */ -{ - int ii; - TRACK* pttrack; - int x0, y0, xf, yf; // coord des extremites du segment teste dans le repere modifie - int dx, dy; // utilise pour calcul des dim x et dim y des segments - int w_dist; - int MaskLayer; - int net_code_ref; - int org_X, org_Y; // Origine sur le PCB des axes du repere centre sur - // l'origine du segment de reference - wxPoint shape_pos; - - org_X = pt_segment->m_Start.x; - org_Y = pt_segment->m_Start.y; - - finx = dx = pt_segment->m_End.x - org_X; - finy = dy = pt_segment->m_End.y - org_Y; - - MaskLayer = pt_segment->ReturnMaskLayer(); - net_code_ref = pt_segment->GetNet(); - - segm_angle = 0; - /* for a non horizontal or vertical segment Compute the segment angle - in 0,1 degrees and its lenght */ - if( dx || dy ) - { - /* Compute the segment angle in 0,1 degrees */ - segm_angle = ArcTangente( dy, dx ); - - /* Compute the segment lenght: we build an equivalent rotated segment, - this segment is horizontal, therefore dx = lenght */ - RotatePoint( &dx, &dy, segm_angle ); /* dx = lenght, dy = 0 */ - } - - segm_long = dx; - - /******************************************/ - /* Phase 1 : test DRC track to pads :*/ - /******************************************/ - - /* Compute the min distance to pads : */ - w_dist = (unsigned) (pt_segment->m_Width >> 1 ); - for( ii = 0; ii < frame->m_Pcb->m_NbPads; ii++ ) - { - D_PAD* pt_pad = frame->m_Pcb->m_Pads[ii]; - - /* No problem if pads are on an other layer, - * But if a drill hole exists (a pad on a single layer can have a hole!) - * we must test the hole - */ - if( (pt_pad->m_Masque_Layer & MaskLayer ) == 0 ) - { - /* We must test the pad hole. In order to use the function "TestClearanceSegmToPad", - * a pseudo pad is used, with a shape and a size like the hole */ - if( pt_pad->m_Drill.x == 0 ) - continue; - - D_PAD pseudo_pad( (MODULE*) NULL ); - - pseudo_pad.m_Size = pt_pad->m_Drill; - pseudo_pad.m_Pos = pt_pad->m_Pos; - pseudo_pad.m_PadShape = pt_pad->m_DrillShape; - pseudo_pad.m_Orient = pt_pad->m_Orient; - pseudo_pad.ComputeRayon(); - spot_cX = pseudo_pad.m_Pos.x - org_X; - spot_cY = pseudo_pad.m_Pos.y - org_Y; - if( TestClearanceSegmToPad( &pseudo_pad, w_dist, - g_DesignSettings.m_TrackClearence ) != OK_DRC ) - { - ErrorsDRC_Count++; - if( show_err ) - Affiche_Erreur_DRC( frame->DrawPanel, DC, - frame->m_Pcb, pt_segment, pt_pad, 0 ); - return BAD_DRC; - } - continue; - } - - /* The pad must be in a net (i.e pt_pad->GetNet() != 0 ) - * but no problem if the pad netcode is the current netcode (same net) */ - if( pt_pad->GetNet() && // the pad must be connected - net_code_ref == pt_pad->GetNet() ) // the pad net is the same as current net -> Ok - continue; - - /* Test DRC pour les pads */ - shape_pos = pt_pad->ReturnShapePos(); - spot_cX = shape_pos.x - org_X; - spot_cY = shape_pos.y - org_Y; - if( TestClearanceSegmToPad( pt_pad, w_dist, g_DesignSettings.m_TrackClearence ) == OK_DRC ) - continue; - - /* Drc error found! */ - else - { - ErrorsDRC_Count++; - if( show_err ) - Affiche_Erreur_DRC( frame->DrawPanel, DC, - frame->m_Pcb, pt_segment, pt_pad, 1 ); - return BAD_DRC; - } - } - - /**********************************************/ - /* Phase 2: test DRC with other track segments */ - /**********************************************/ - - /* At this point the reference segment is the X axis */ - - /* Test the reference segment with other track segments */ - pttrack = StartBuffer; - for( ; pttrack != NULL; pttrack = (TRACK*) pttrack->Pnext ) - { - //No problem if segments have the meme net code: - if( net_code_ref == pttrack->GetNet() ) - continue; - - // No problem if segment are on different layers : - if( ( MaskLayer & pttrack->ReturnMaskLayer() ) == 0 ) - continue; - - /* calcul de la Distance mini = Isol+ rayon ou demi largeur seg ref - + rayon ou demi largeur seg a comparer */ - w_dist = pt_segment->m_Width >> 1; - w_dist += pttrack->m_Width >> 1; - w_dist += g_DesignSettings.m_TrackClearence; - - /* If the reference segment is a via, we test it here */ - if( pt_segment->Type() == TYPEVIA ) - { - int orgx, orgy; // origine du repere d'axe X = segment a comparer - int angle = 0; // angle du segment a tester; - orgx = pttrack->m_Start.x; orgy = pttrack->m_Start.y; - dx = pttrack->m_End.x - orgx; dy = pttrack->m_End.y - orgy; - x0 = pt_segment->m_Start.x - orgx; y0 = pt_segment->m_Start.y - orgy; - - if( pttrack->Type() == TYPEVIA ) /* Tst distance entre 2 vias */ - { - if( (int) hypot( (float) x0, (float) y0 ) < w_dist ) - { - ErrorsDRC_Count++; - if( show_err ) - Affiche_Erreur_DRC( frame->DrawPanel, - DC, - frame->m_Pcb, - pt_segment, - pttrack, - 21 ); - return BAD_DRC; - } - } - else /* Tst drc via / segment */ - { - /* Compute l'angle */ - angle = ArcTangente( dy, dx ); - - /* Compute new coordinates ( the segment become horizontal) */ - RotatePoint( &dx, &dy, angle ); - RotatePoint( &x0, &y0, angle ); - - if( TestMarginToCircle( x0, y0, w_dist, dx ) == BAD_DRC ) - { - ErrorsDRC_Count++; - if( show_err ) - Affiche_Erreur_DRC( frame->DrawPanel, - DC, - frame->m_Pcb, - pt_segment, - pttrack, - 20 ); - return BAD_DRC; - } - } - continue; - } - - /* We compute x0,y0, xf,yf = starting and ending point coordinates for the segment to test - * in the new axis : the new X axis is the reference segment - * We must translate and rotate the segment to test - */ - x0 = pttrack->m_Start.x - org_X; - y0 = pttrack->m_Start.y - org_Y; - - xf = pttrack->m_End.x - org_X; - yf = pttrack->m_End.y - org_Y; - - RotatePoint( &x0, &y0, segm_angle ); - RotatePoint( &xf, &yf, segm_angle ); - - if( pttrack->Type() == TYPEVIA ) - { - if( TestMarginToCircle( x0, y0, w_dist, segm_long ) == OK_DRC ) - continue; - ErrorsDRC_Count++; - if( show_err ) - Affiche_Erreur_DRC( frame->DrawPanel, DC, frame->m_Pcb, pt_segment, pttrack, 21 ); - return BAD_DRC; - } - - - /* We have changed axis: - * the reference segment is Horizontal. - * 3 cases : the segment to test can be parallel, perpendicular or have an other direction - */ - if( y0 == yf ) // parallel segments - { - if( abs( y0 ) >= w_dist ) - continue; - - if( x0 > xf ) - EXCHG( x0, xf ); /* pour que x0 <= xf */ - - if( x0 > (-w_dist) && x0 < (segm_long + w_dist) ) /* possible error drc */ - { - /* Fine test : we consider the rounded shape of the ends */ - if( x0 >= 0 && x0 <= segm_long ) - { - ErrorsDRC_Count++; - if( show_err ) - Affiche_Erreur_DRC( frame->DrawPanel, - DC, - frame->m_Pcb, - pt_segment, - pttrack, - 2 ); - return BAD_DRC; - } - if( TestMarginToCircle( x0, y0, w_dist, segm_long ) == BAD_DRC ) - { - ErrorsDRC_Count++; - if( show_err ) - Affiche_Erreur_DRC( frame->DrawPanel, - DC, - frame->m_Pcb, - pt_segment, - pttrack, - 2 ); - return BAD_DRC; - } - } - if( xf > (-w_dist) && xf < (segm_long + w_dist) ) - { - /* Fine test : we consider the rounded shape of the ends */ - if( xf >= 0 && xf <= segm_long ) - { - ErrorsDRC_Count++; - if( show_err ) - Affiche_Erreur_DRC( frame->DrawPanel, - DC, - frame->m_Pcb, - pt_segment, - pttrack, - 3 ); - return BAD_DRC; - } - if( TestMarginToCircle( xf, yf, w_dist, segm_long ) == BAD_DRC ) - { - ErrorsDRC_Count++; - if( show_err ) - Affiche_Erreur_DRC( frame->DrawPanel, - DC, - frame->m_Pcb, - pt_segment, - pttrack, - 3 ); - return BAD_DRC; - } - } - - if( x0 <=0 && xf >= 0 ) - { - ErrorsDRC_Count++; - if( show_err ) - Affiche_Erreur_DRC( frame->DrawPanel, DC, frame->m_Pcb, pt_segment, pttrack, 4 ); - return BAD_DRC; - } - } - else if( x0 == xf ) // perpendicular segments - { - if( ( x0 <= (-w_dist) ) || ( x0 >= (segm_long + w_dist) ) ) - continue; - - /* Test is segments are crossing */ - if( y0 > yf ) - EXCHG( y0, yf ); - if( (y0 < 0) && (yf > 0) ) - { - ErrorsDRC_Count++; - if( show_err ) - Affiche_Erreur_DRC( frame->DrawPanel, DC, frame->m_Pcb, pt_segment, pttrack, 6 ); - return BAD_DRC; - } - - /* At this point the drc error is due to an end near a reference segm end */ - if( TestMarginToCircle( x0, y0, w_dist, segm_long ) == BAD_DRC ) - { - ErrorsDRC_Count++; - if( show_err ) - Affiche_Erreur_DRC( frame->DrawPanel, DC, frame->m_Pcb, pt_segment, pttrack, 7 ); - return BAD_DRC; - } - if( TestMarginToCircle( xf, yf, w_dist, segm_long ) == BAD_DRC ) - { - ErrorsDRC_Count++; - if( show_err ) - Affiche_Erreur_DRC( frame->DrawPanel, DC, frame->m_Pcb, pt_segment, pttrack, 8 ); - return BAD_DRC; - } - } - else // segments quelconques entre eux */ - { - int bflag = OK_DRC; - /* calcul de la "surface de securite du segment de reference */ - /* First rought 'and fast) test : the track segment is like a rectangle */ - - xcliplo = ycliplo = -w_dist; - xcliphi = segm_long + w_dist; ycliphi = w_dist; - - bflag = Tst_Ligne( x0, y0, xf, yf ); - if( bflag == BAD_DRC ) /* A fine test is needed because a serment is not exactly a rectangle - it has rounded ends */ - { - /* 2eme passe : the track has rounded ends. - * we must a fine test for each rounded end and the rectangular zone */ - - xcliplo = 0; xcliphi = segm_long; - bflag = Tst_Ligne( x0, y0, xf, yf ); - - if( bflag == BAD_DRC ) - { - ErrorsDRC_Count++; - if( show_err ) - Affiche_Erreur_DRC( frame->DrawPanel, - DC, - frame->m_Pcb, - pt_segment, - pttrack, - 9 ); - return BAD_DRC; - } - else // The drc error is due to the starting or the ending point of the reference segment - { - // Test the starting and the ending point - int angle, rx0, ry0, rxf, ryf; - x0 = pttrack->m_Start.x; - y0 = pttrack->m_Start.y; - - xf = pttrack->m_End.x; - yf = pttrack->m_End.y; - - dx = xf - x0; - dy = yf - y0; - - /* Compute the segment orientation (angle) en 0,1 degre */ - angle = ArcTangente( dy, dx ); - - /* Compute the segment lenght: dx = longueur */ - RotatePoint( &dx, &dy, angle ); - - /* Comute the reference segment coordinates relatives to a - * X axis = current tested segment */ - rx0 = pt_segment->m_Start.x - x0; - ry0 = pt_segment->m_Start.y - y0; - rxf = pt_segment->m_End.x - x0; - ryf = pt_segment->m_End.y - y0; - - RotatePoint( &rx0, &ry0, angle ); - RotatePoint( &rxf, &ryf, angle ); - if( TestMarginToCircle( rx0, ry0, w_dist, dx ) == BAD_DRC ) - { - ErrorsDRC_Count++; - if( show_err ) - Affiche_Erreur_DRC( frame->DrawPanel, - DC, - frame->m_Pcb, - pt_segment, - pttrack, - 10 ); - return BAD_DRC; - } - if( TestMarginToCircle( rxf, ryf, w_dist, dx ) == BAD_DRC ) - { - ErrorsDRC_Count++; - if( show_err ) - Affiche_Erreur_DRC( frame->DrawPanel, - DC, - frame->m_Pcb, - pt_segment, - pttrack, - 11 ); - return BAD_DRC; - } - } - } - } - } - - return OK_DRC; -} - - -/*****************************************************************************/ -static bool Test_Pad_to_Pads_Drc( WinEDA_BasePcbFrame* frame, - wxDC* DC, - D_PAD* pad_ref, - LISTE_PAD* start_buffer, - LISTE_PAD* end_buffer, - int max_size, - bool show_err ) -/*****************************************************************************/ - -/** Test the drc between pad_ref and other pads. - * the pad list must be sorted by x coordinate - * @param frame = current active frame - * @param DC = current DC - * @param pad_ref = pad to test - * @param end_buffer = upper limit of the pad list. - * @param max_size = size of the biggest pad (used to stop the test when the X distance is > max_size) - * @param show_err if true, display a marker and amessage. - */ -{ - int MaskLayer; - D_PAD* pad; - LISTE_PAD* pad_list = start_buffer; - - MaskLayer = pad_ref->m_Masque_Layer & ALL_CU_LAYERS; - int x_limite = max_size + g_DesignSettings.m_TrackClearence + - pad_ref->m_Rayon + pad_ref->m_Pos.x; - - for( ; pad_list < end_buffer; pad_list++ ) - { - pad = *pad_list; - if( pad == pad_ref ) - continue; - - /* We can stop the test when pad->m_Pos.x > x_limite - * because the list is sorted by X values */ - if( pad->m_Pos.x > x_limite ) - break; - - /* No probleme if pads are on different copper layers */ - if( (pad->m_Masque_Layer & MaskLayer ) == 0 ) - continue; - - /* The pad must be in a net (i.e pt_pad->GetNet() != 0 ), - * But no problem if pads have the same netcode (same net)*/ - if( pad->GetNet() && (pad_ref->GetNet() == pad->GetNet()) ) - continue; - - /* No problem if pads are from the same footprint - * and have the same pad number ( equivalent pads ) */ - if( (pad->m_Parent == pad_ref->m_Parent) && (pad->m_NumPadName == pad_ref->m_NumPadName) ) - continue; - - if( Pad_to_Pad_Isol( pad_ref, pad, g_DesignSettings.m_TrackClearence ) == OK_DRC ) - continue; - - else /* here we have a drc error! */ - { - ErrorsDRC_Count++; - if( show_err ) - Affiche_Erreur_DRC( frame->DrawPanel, DC, frame->m_Pcb, pad_ref, pad ); - return BAD_DRC; - } - } - - return OK_DRC; -} - - -/**************************************************************************************/ -static int Pad_to_Pad_Isol( D_PAD* pad_ref, D_PAD* pad, const int dist_min ) -/***************************************************************************************/ - -/* Return OK_DRC si clearance between pad_ref and pad is >= dist_min - * or BAD_DRC if not */ -{ - wxPoint rel_pos; - int dist, diag; - wxPoint shape_pos; - int pad_angle; - - rel_pos = pad->ReturnShapePos(); - shape_pos = pad_ref->ReturnShapePos(); - - // rel_pos is pad position relative to the pad_ref position - rel_pos.x -= shape_pos.x; - rel_pos.y -= shape_pos.y; - dist = (int) hypot( (double) rel_pos.x, (double) rel_pos.y ); - - diag = OK_DRC; - - /* tst rapide: si les cercles exinscrits sont distants de dist_min au moins, - * il n'y a pas de risque: */ - if( (dist - pad_ref->m_Rayon - pad->m_Rayon) >= dist_min ) - return OK_DRC; - - /* Ici les pads sont proches et les cercles exinxcrits sont trop proches - * Selon les formes relatives il peut y avoir ou non erreur */ - - bool swap_pads = false; - if( (pad_ref->m_PadShape != PAD_CIRCLE) && (pad->m_PadShape == PAD_CIRCLE) ) - swap_pads = true; - else if( (pad_ref->m_PadShape != PAD_OVAL) && (pad->m_PadShape == PAD_OVAL) ) - swap_pads = true; - - if( swap_pads ) - { - EXCHG( pad_ref, pad ); - rel_pos.x = -rel_pos.x; - rel_pos.y = -rel_pos.y; - } - - switch( pad_ref->m_PadShape ) - { - case PAD_CIRCLE: // pad_ref is like a track segment with a null lenght - segm_long = 0; - segm_angle = 0; - finx = finy = 0; - spot_cX = rel_pos.x; - spot_cY = rel_pos.y; - diag = TestClearanceSegmToPad( pad, pad_ref->m_Rayon, dist_min ); - break; - - case PAD_RECT: - RotatePoint( &rel_pos.x, &rel_pos.y, pad_ref->m_Orient ); - pad_angle = pad_ref->m_Orient + pad->m_Orient; // pad_angle = pad orient relative to the pad_ref orient - NORMALIZE_ANGLE_POS( pad_angle ); - if( pad->m_PadShape == PAD_RECT ) - { - wxSize size = pad->m_Size; - if( (pad_angle == 0) || (pad_angle == 900) || (pad_angle == 1800) || - (pad_angle == 2700) ) - { - if( (pad_angle == 900) || (pad_angle == 2700) ) - { - EXCHG( size.x, size.y ); - } - - // Test DRC: - diag = BAD_DRC; - - rel_pos.x = ABS( rel_pos.x ); - rel_pos.y = ABS( rel_pos.y ); - - if( ( rel_pos.x - ( (size.x + pad_ref->m_Size.x) / 2 ) ) >= dist_min ) - diag = OK_DRC; - - if( ( rel_pos.y - ( (size.y + pad_ref->m_Size.y) / 2 ) ) >= dist_min ) - diag = OK_DRC; - } - else // Any other orient - { - /* TODO : any orient ... */ - } - } - break; - - case PAD_OVAL: /* an oval pad is like a track segment */ - { - /* Create and test a track segment with same dimensions */ - int segm_width; - segm_angle = pad_ref->m_Orient; // Segment orient. - if( pad_ref->m_Size.y < pad_ref->m_Size.x ) /* We suppose the pad is an horizontal oval */ - { - segm_width = pad_ref->m_Size.y; - segm_long = pad_ref->m_Size.x - pad_ref->m_Size.y; - } - else // it was a vertical oval, change to a rotated horizontal one - { - segm_width = pad_ref->m_Size.x; - segm_long = pad_ref->m_Size.y - pad_ref->m_Size.x; - segm_angle += 900; - } - /* the start point must be 0,0 and currently rel_pos is relative the center of pad coordinate */ - int sx = -segm_long / 2, sy = 0; // Start point coordinate of the horizontal equivalent segment - RotatePoint( &sx, &sy, segm_angle ); // True start point coordinate of the equivalent segment - spot_cX = rel_pos.x + sx; - spot_cY = rel_pos.y + sy; // pad position / segment origin - finx = -sx; - finy = -sy; // end of segment coordinate - diag = TestClearanceSegmToPad( pad, segm_width / 2, dist_min ); - break; - } - - default: - /* TODO...*/ - break; - } - - return diag; -} - - -/***************************************************************************/ -static int TestClearanceSegmToPad( const D_PAD* pad_to_test, int w_segm, int dist_min ) -/****************************************************************************/ - -/* - * Routine adaptee de la "distance()" (LOCATE.CPP) - * teste la distance du pad au segment de droite en cours - * - * retourne: - * 0 si distance >= dist_min - * 1 si distance < dist_min - * Parametres d'appel: - * pad_to_test = pointeur sur le pad a tester - * w_segm = demi largeur du segment a tester - * dist_min = marge a respecter - * - * en variables globales - * segm_long = longueur du segment en test - * segm_angle = angle d'inclinaison du segment; - * finx, finy = coord fin du segment / origine - * spot_cX, spot_cY = position du pad / origine du segment - */ -{ - int p_dimx, p_dimy; /* demi - dimensions X et Y du pad a controler */ - int bflag; - int orient; - int x0, y0, xf, yf; - int seuil; - int deltay; - - seuil = w_segm + dist_min; - p_dimx = pad_to_test->m_Size.x >> 1; - p_dimy = pad_to_test->m_Size.y >> 1; - - if( pad_to_test->m_PadShape == PAD_CIRCLE ) - { - /* calcul des coord centre du pad dans le repere axe X confondu - * avec le segment en tst */ - RotatePoint( &spot_cX, &spot_cY, segm_angle ); - return TestMarginToCircle( spot_cX, spot_cY, seuil + p_dimx, segm_long ); - } - else - { - /* calcul de la "surface de securite" du pad de reference */ - xcliplo = spot_cX - seuil - p_dimx; - ycliplo = spot_cY - seuil - p_dimy; - xcliphi = spot_cX + seuil + p_dimx; - ycliphi = spot_cY + seuil + p_dimy; - - x0 = y0 = 0; - - xf = finx; - yf = finy; - - orient = pad_to_test->m_Orient; - - RotatePoint( &x0, &y0, spot_cX, spot_cY, -orient ); - RotatePoint( &xf, &yf, spot_cX, spot_cY, -orient ); - - bflag = Tst_Ligne( x0, y0, xf, yf ); - - if( bflag == OK_DRC ) - return OK_DRC; - - /* Erreur DRC : analyse fine de la forme de la pastille */ - - switch( pad_to_test->m_PadShape ) - { - default: - return BAD_DRC; - - case PAD_OVAL: - /* test de la pastille ovale ramenee au type ovale vertical */ - if( p_dimx > p_dimy ) - { - EXCHG( p_dimx, p_dimy ); orient += 900; - if( orient >= 3600 ) - orient -= 3600; - } - deltay = p_dimy - p_dimx; - - /* ici: p_dimx = rayon, - * delta = dist centre cercles a centre pad */ - - /* Test du rectangle separant les 2 demi cercles */ - xcliplo = spot_cX - seuil - p_dimx; - ycliplo = spot_cY - w_segm - deltay; - xcliphi = spot_cX + seuil + p_dimx; - ycliphi = spot_cY + w_segm + deltay; - - bflag = Tst_Ligne( x0, y0, xf, yf ); - if( bflag == BAD_DRC ) - return BAD_DRC; - - /* test des 2 cercles */ - x0 = spot_cX; /* x0,y0 = centre du cercle superieur du pad ovale */ - y0 = spot_cY + deltay; - RotatePoint( &x0, &y0, spot_cX, spot_cY, orient ); - RotatePoint( &x0, &y0, segm_angle ); - - bflag = TestMarginToCircle( x0, y0, p_dimx + seuil, segm_long ); - if( bflag == BAD_DRC ) - return BAD_DRC; - - x0 = spot_cX; /* x0,y0 = centre du cercle inferieur du pad ovale */ - y0 = spot_cY - deltay; - RotatePoint( &x0, &y0, spot_cX, spot_cY, orient ); - RotatePoint( &x0, &y0, segm_angle ); - - bflag = TestMarginToCircle( x0, y0, p_dimx + seuil, segm_long ); - if( bflag == BAD_DRC ) - return BAD_DRC; - break; - - case PAD_RECT: /* 2 rectangle + 4 1/4 cercles a tester */ - /* Test du rectangle dimx + seuil, dimy */ - xcliplo = spot_cX - p_dimx - seuil; - ycliplo = spot_cY - p_dimy; - xcliphi = spot_cX + p_dimx + seuil; - ycliphi = spot_cY + p_dimy; - - bflag = Tst_Ligne( x0, y0, xf, yf ); - if( bflag == BAD_DRC ) - { - return BAD_DRC; - } - - /* Test du rectangle dimx , dimy + seuil */ - xcliplo = spot_cX - p_dimx; - ycliplo = spot_cY - p_dimy - seuil; - xcliphi = spot_cX + p_dimx; - ycliphi = spot_cY + p_dimy + seuil; - - bflag = Tst_Ligne( x0, y0, xf, yf ); - if( bflag == BAD_DRC ) - { - return BAD_DRC; - } - - /* test des 4 cercles ( surface d'solation autour des sommets */ - /* test du coin sup. gauche du pad */ - x0 = spot_cX - p_dimx; - y0 = spot_cY - p_dimy; - RotatePoint( &x0, &y0, spot_cX, spot_cY, orient ); - RotatePoint( &x0, &y0, segm_angle ); - bflag = TestMarginToCircle( x0, y0, seuil, segm_long ); - if( bflag == BAD_DRC ) - { - return BAD_DRC; - } - - /* test du coin sup. droit du pad */ - x0 = spot_cX + p_dimx; - y0 = spot_cY - p_dimy; - RotatePoint( &x0, &y0, spot_cX, spot_cY, orient ); - RotatePoint( &x0, &y0, segm_angle ); - bflag = TestMarginToCircle( x0, y0, seuil, segm_long ); - if( bflag == BAD_DRC ) - { - return BAD_DRC; - } - - /* test du coin inf. gauche du pad */ - x0 = spot_cX - p_dimx; - y0 = spot_cY + p_dimy; - RotatePoint( &x0, &y0, spot_cX, spot_cY, orient ); - RotatePoint( &x0, &y0, segm_angle ); - bflag = TestMarginToCircle( x0, y0, seuil, segm_long ); - if( bflag == BAD_DRC ) - { - return BAD_DRC; - } - - /* test du coin inf. droit du pad */ - x0 = spot_cX + p_dimx; - y0 = spot_cY + p_dimy; - RotatePoint( &x0, &y0, spot_cX, spot_cY, orient ); - RotatePoint( &x0, &y0, segm_angle ); - bflag = TestMarginToCircle( x0, y0, seuil, segm_long ); - if( bflag == BAD_DRC ) - { - return BAD_DRC; - } - - break; - } - } - return OK_DRC; -} - - -/*******************************************************************/ -static int TestMarginToCircle( int cx, int cy, int rayon, int longueur ) -/*******************************************************************/ - -/* - * Routine analogue a TestClearanceSegmToPad. - * Calcul de la distance d'un cercle (via ronde, extremite de piste) - * au segment de droite en cours de controle (segment de reference dans - * son repere ) - * parametres: - * cx, cy: centre du cercle (surface ronde) a tester, dans le repere - * segment de reference - * rayon = rayon du cercle - * longueur = longueur du segment dans son repere (i.e. coord de fin) - * retourne: - * OK_DRC si distance >= rayon - * BAD_DRC si distance < rayon - */ -{ - if( abs( cy ) > rayon ) - return OK_DRC; - - if( (cx >= -rayon ) && ( cx <= (longueur + rayon) ) ) - { - if( (cx >= 0) && (cx <= longueur) ) - return BAD_DRC; - if( cx > longueur ) - cx -= longueur; - if( hypot( (double) cx, (double) cy ) < rayon ) - return BAD_DRC; - } - - return OK_DRC; -} - - -/******************************************************************************/ -static void Affiche_Erreur_DRC( WinEDA_DrawPanel* panel, wxDC* DC, BOARD* Pcb, - TRACK* pt_ref, BOARD_ITEM* pt_item, int errnumber ) -/******************************************************************************/ - -/* affiche les erreurs de DRC : - * Message d'erreur - + - * Marqueur - * number = numero d'identification - */ -{ - wxPoint erc_pos; - TRACK* pt_segm; - wxString msg; - wxString tracktype, netname1, netname2; - EQUIPOT* equipot = Pcb->FindNet( pt_ref->GetNet() ); - - if( equipot ) - netname1 = equipot->m_Netname; - else - netname1 = wxT( "" ); - - netname2 = wxT( "" ); - - if( pt_ref->Type() == TYPEVIA ) - tracktype = wxT( "Via" ); - - else if( pt_ref->Type() == TYPEZONE ) - tracktype = wxT( "Zone" ); - - else - tracktype = wxT( "Track" ); - - if( pt_item->Type() == TYPEPAD ) - { - D_PAD* pad = (D_PAD*) pt_item; - equipot = Pcb->FindNet( pad->GetNet() ); - if( equipot ) - netname2 = equipot->m_Netname; - - erc_pos = pad->m_Pos; - wxString pad_name = pad->ReturnStringPadName(); - - wxString module_name = ( (MODULE*) (pad->m_Parent) )->m_Reference->m_Text; - - msg.Printf( _( "%d Drc Err %d %s (net %s) and PAD %s (%s) net %s @ %d,%d\n" ), - ErrorsDRC_Count, errnumber, tracktype.GetData(), - netname1.GetData(), - pad_name.GetData(), module_name.GetData(), - netname2.GetData(), - erc_pos.x, erc_pos.y ); - } - - else /* erreur sur segment de piste */ - { - pt_segm = (TRACK*) pt_item; - equipot = Pcb->FindNet( pt_segm->GetNet() ); - if( equipot ) - netname2 = equipot->m_Netname; - erc_pos = pt_segm->m_Start; - if( pt_segm->Type() == TYPEVIA ) - { - msg.Printf( _( "%d Err type %d: %s (net %s) and VIA (net %s) @ %d,%d\n" ), - ErrorsDRC_Count, errnumber, tracktype.GetData(), - netname1.GetData(), netname2.GetData(), - erc_pos.x, erc_pos.y ); - } - else - { - wxPoint erc_pos_f = pt_segm->m_End; - if( hypot( (double) (erc_pos_f.x - pt_ref->m_End.x), - (double) (erc_pos_f.y - pt_ref->m_End.y) ) - < hypot( (double) (erc_pos.x - pt_ref->m_End.x), - (double) (erc_pos.y - pt_ref->m_End.y) ) ) - { - EXCHG( erc_pos_f.x, erc_pos.x ); - EXCHG( erc_pos_f.y, erc_pos.y ); - } - msg.Printf( _( "%d Err type %d: %s (net %s) and track (net %s) @ %d,%d\n" ), - ErrorsDRC_Count, errnumber, tracktype.GetData(), - netname1.GetData(), netname2.GetData(), - erc_pos.x, erc_pos.y ); - } - } - - if( DrcFrame ) - { -// DrcFrame->m_logWindow->AppendText( msg ); - } - else - panel->m_Parent->Affiche_Message( msg ); - - if( s_RptFile ) - fprintf( s_RptFile, "%s", CONV_TO_UTF8( msg ) ); - - if( current_marqueur == NULL ) - current_marqueur = new MARKER( Pcb ); - - current_marqueur->m_Pos = wxPoint( erc_pos.x, erc_pos.y ); - current_marqueur->m_Color = WHITE; - current_marqueur->SetMessage( msg ); - current_marqueur->Draw( panel, DC, GR_OR ); -} - - -/******************************************************************************/ -static void Affiche_Erreur_DRC( WinEDA_DrawPanel* panel, wxDC* DC, BOARD* Pcb, - D_PAD* pad1, D_PAD* pad2 ) -/******************************************************************************/ - -/* affiche les erreurs de DRC : - * Message d'erreur - + - * Marqueur - * number = numero d'identification - */ -{ - wxString msg; - - wxString pad_name1 = pad1->ReturnStringPadName(); - wxString module_name1 = ( (MODULE*) (pad1->m_Parent) )->m_Reference->m_Text; - wxString pad_name2 = pad2->ReturnStringPadName(); - wxString module_name2 = ( (MODULE*) (pad2->m_Parent) )->m_Reference->m_Text; - wxString netname1, netname2; - - EQUIPOT* equipot = Pcb->FindNet( pad1->GetNet() ); - - if( equipot ) - netname1 = equipot->m_Netname; - else - netname1 = wxT( "" ); - - equipot = Pcb->FindNet( pad2->GetNet() ); - if( equipot ) - netname2 = equipot->m_Netname; - else - netname2 = wxT( "" ); - - msg.Printf( _( "%d Drc Err: PAD %s (%s) net %s @ %d,%d and PAD %s (%s) net %s @ %d,%d\n" ), - ErrorsDRC_Count, - pad_name1.GetData(), module_name1.GetData(), netname1.GetData(), pad1->m_Pos.x, pad1->m_Pos.y, - pad_name2.GetData(), module_name2.GetData(), netname2.GetData(), pad2->m_Pos.x, pad2->m_Pos.y ); - - if( DrcFrame ) - { -// DrcFrame->m_logWindow->AppendText( msg ); - } - else - panel->m_Parent->Affiche_Message( msg ); - - if( s_RptFile ) - fprintf( s_RptFile, "%s", CONV_TO_UTF8( msg ) ); - - if( current_marqueur == NULL ) - current_marqueur = new MARKER( Pcb ); - - current_marqueur->m_Pos = pad1->m_Pos; - current_marqueur->m_Color = WHITE; - current_marqueur->SetMessage( msg ); - current_marqueur->Draw( panel, DC, GR_OR ); -} - - -/**********************************************/ -/* int Tst_Ligne(int x1,int y1,int x2,int y2) */ -/**********************************************/ - -/* Routine utilisee pour tester si une piste est en contact avec une autre piste. - * - * Cette routine controle si la ligne (x1,y1 x2,y2) a une partie s'inscrivant - * dans le cadre (xcliplo,ycliplo xcliphi,ycliphi) (variables globales, - * locales a ce fichier) - * - * Retourne OK_DRC si aucune partie commune - * Retourne BAD_DRC si partie commune - */ -static inline int USCALE( unsigned arg, unsigned num, unsigned den ) -{ - int ii; - - ii = (int) ( ( (double) arg * num ) / den ); - return ii; -} - - -#define WHEN_OUTSIDE return (OK_DRC) -#define WHEN_INSIDE - -static int Tst_Ligne( int x1, int y1, int x2, int y2 ) -{ - int temp; - - if( x1 > x2 ) - { - EXCHG( x1, x2 ); - EXCHG( y1, y2 ); - } - if( (x2 < xcliplo) || (x1 > xcliphi) ) - { - WHEN_OUTSIDE; - } - if( y1 < y2 ) - { - if( (y2 < ycliplo) || (y1 > ycliphi) ) - { - WHEN_OUTSIDE; - } - if( y1 < ycliplo ) - { - temp = USCALE( (x2 - x1), (ycliplo - y1), (y2 - y1) ); - if( (x1 += temp) > xcliphi ) - { - WHEN_OUTSIDE; - } - y1 = ycliplo; - WHEN_INSIDE; - } - if( y2 > ycliphi ) - { - temp = USCALE( (x2 - x1), (y2 - ycliphi), (y2 - y1) ); - if( (x2 -= temp) < xcliplo ) - { - WHEN_OUTSIDE; - } - y2 = ycliphi; - WHEN_INSIDE; - } - if( x1 < xcliplo ) - { - temp = USCALE( (y2 - y1), (xcliplo - x1), (x2 - x1) ); - y1 += temp; x1 = xcliplo; - WHEN_INSIDE; - } - if( x2 > xcliphi ) - { - temp = USCALE( (y2 - y1), (x2 - xcliphi), (x2 - x1) ); - y2 -= temp; x2 = xcliphi; - WHEN_INSIDE; - } - } - else - { - if( (y1 < ycliplo) || (y2 > ycliphi) ) - { - WHEN_OUTSIDE; - } - if( y1 > ycliphi ) - { - temp = USCALE( (x2 - x1), (y1 - ycliphi), (y1 - y2) ); - if( (x1 += temp) > xcliphi ) - { - WHEN_OUTSIDE; - } - y1 = ycliphi; - WHEN_INSIDE; - } - if( y2 < ycliplo ) - { - temp = USCALE( (x2 - x1), (ycliplo - y2), (y1 - y2) ); - if( (x2 -= temp) < xcliplo ) - { - WHEN_OUTSIDE; - } - y2 = ycliplo; - WHEN_INSIDE; - } - if( x1 < xcliplo ) - { - temp = USCALE( (y1 - y2), (xcliplo - x1), (x2 - x1) ); - y1 -= temp; - x1 = xcliplo; - WHEN_INSIDE; - } - if( x2 > xcliphi ) - { - temp = USCALE( (y1 - y2), (x2 - xcliphi), (x2 - x1) ); - y2 += temp; - x2 = xcliphi; - WHEN_INSIDE; - } - } - - if( ( (x2 + x1)/2 <= xcliphi ) && ( (x2 + x1)/2 >= xcliplo ) \ - && ( (y2 + y1)/2 <= ycliphi ) && ( (y2 + y1)/2 >= ycliplo ) ) - { - return BAD_DRC; - } - else - return OK_DRC; -} - -#endif