From 0f725ee2fc093bd83ccf7827120811f100640693 Mon Sep 17 00:00:00 2001 From: charras Date: Mon, 23 Mar 2009 19:54:15 +0000 Subject: [PATCH] DRC: added test pads to holes (pcbnew). Others minor changes --- CHANGELOG.txt | 8 + common/gestfich.cpp | 4 +- .../dialog_edit_component_in_schematic.fbp | 6 +- ...dialog_edit_component_in_schematic_fbp.cpp | 6 +- include/build_version.h | 2 +- pcbnew/class_drc_item.cpp | 4 + pcbnew/class_pad.h | 60 ++-- pcbnew/class_pad_draw_functions.cpp | 4 +- pcbnew/drc.cpp | 324 +++++++++++------- pcbnew/drc_stuff.h | 2 + 10 files changed, 248 insertions(+), 172 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 9d3c7a739d..46676ef9f4 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -5,6 +5,14 @@ Started 2007-June-11 Please add newer entries at the top, list the date and your name with email address. +2009-mar-16 UPDATE Jean-Pierre Charras +================================================================================ +++pcbnew: + in DRC: added test pads to holes. + +++Al: + minor changes. + 2009-mar-16 UPDATE Jean-Pierre Charras ================================================================================ diff --git a/common/gestfich.cpp b/common/gestfich.cpp index 41acbdb1d2..30a8d07d96 100644 --- a/common/gestfich.cpp +++ b/common/gestfich.cpp @@ -198,7 +198,9 @@ wxString MakeFileName( const wxString& dir, { if( !wxIsAbsolutePath( shortname ) ) { - if( !shortname.StartsWith( wxT( "./" ) ) && !shortname.StartsWith( wxT( "../" ) ) ) + if( !shortname.StartsWith( wxT( "./" ) ) && !shortname.StartsWith( wxT( "../" ) ) // under unix + && !shortname.StartsWith( wxT( ".\\" ) ) && !shortname.StartsWith( wxT( "..\\" ) )) // under Windows + { /* no absolute path in shortname, add dir to shortname */ fullfilename = dir; } diff --git a/eeschema/dialog_edit_component_in_schematic.fbp b/eeschema/dialog_edit_component_in_schematic.fbp index 44c527b99f..ada163de5f 100644 --- a/eeschema/dialog_edit_component_in_schematic.fbp +++ b/eeschema/dialog_edit_component_in_schematic.fbp @@ -190,7 +190,7 @@ orientationRadioBox protected - 3 + 0 wxRA_SPECIFY_COLS @@ -255,7 +255,7 @@ mirrorRadioBox protected - 2 + 0 wxRA_SPECIFY_COLS @@ -872,7 +872,7 @@ m_StyleRadioBox protected - 3 + 0 wxRA_SPECIFY_COLS diff --git a/eeschema/dialog_edit_component_in_schematic_fbp.cpp b/eeschema/dialog_edit_component_in_schematic_fbp.cpp index f86dbbef90..6e77799548 100644 --- a/eeschema/dialog_edit_component_in_schematic_fbp.cpp +++ b/eeschema/dialog_edit_component_in_schematic_fbp.cpp @@ -39,7 +39,7 @@ DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_FBP::DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_FBP( wxString orientationRadioBoxChoices[] = { _("0"), _("+90"), _("180"), _("-90") }; int orientationRadioBoxNChoices = sizeof( orientationRadioBoxChoices ) / sizeof( wxString ); orientationRadioBox = new wxRadioBox( this, wxID_ANY, _("Orientation (Degrees)"), wxDefaultPosition, wxDefaultSize, orientationRadioBoxNChoices, orientationRadioBoxChoices, 1, wxRA_SPECIFY_COLS ); - orientationRadioBox->SetSelection( 3 ); + orientationRadioBox->SetSelection( 0 ); orientationRadioBox->SetToolTip( _("Select if the component is to be rotated when drawn") ); orientationSizer->Add( orientationRadioBox, 1, wxALL, 8 ); @@ -52,7 +52,7 @@ DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_FBP::DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_FBP( wxString mirrorRadioBoxChoices[] = { _("Normal"), _("Mirror ---"), _("Mirror |") }; int mirrorRadioBoxNChoices = sizeof( mirrorRadioBoxChoices ) / sizeof( wxString ); mirrorRadioBox = new wxRadioBox( this, wxID_ANY, _("Mirror"), wxDefaultPosition, wxDefaultSize, mirrorRadioBoxNChoices, mirrorRadioBoxChoices, 1, wxRA_SPECIFY_COLS ); - mirrorRadioBox->SetSelection( 2 ); + mirrorRadioBox->SetSelection( 0 ); mirrorRadioBox->SetToolTip( _("Pick the graphical transformation to be used when displaying the component, if any") ); mirrorSizer->Add( mirrorRadioBox, 1, wxALL, 8 ); @@ -134,7 +134,7 @@ DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_FBP::DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_FBP( wxString m_StyleRadioBoxChoices[] = { _("Normal"), _("Italic"), _("Bold"), _("Bold Italic") }; int m_StyleRadioBoxNChoices = sizeof( m_StyleRadioBoxChoices ) / sizeof( wxString ); m_StyleRadioBox = new wxRadioBox( this, wxID_ANY, _("Style:"), wxDefaultPosition, wxDefaultSize, m_StyleRadioBoxNChoices, m_StyleRadioBoxChoices, 1, wxRA_SPECIFY_COLS ); - m_StyleRadioBox->SetSelection( 3 ); + m_StyleRadioBox->SetSelection( 0 ); m_StyleRadioBox->SetToolTip( _("The style of the currently selected field's text in the schemati") ); visibilitySizer->Add( m_StyleRadioBox, 1, wxBOTTOM|wxRIGHT|wxLEFT, 5 ); diff --git a/include/build_version.h b/include/build_version.h index bfdd695058..5fb4261a3e 100644 --- a/include/build_version.h +++ b/include/build_version.h @@ -3,7 +3,7 @@ #ifndef KICAD_BUILD_VERSION #define KICAD_BUILD_VERSION -#define BUILD_VERSION wxT("(20090216-final)") +#define BUILD_VERSION wxT("(20090332-unstable)") COMMON_GLOBL wxString g_BuildVersion #ifdef EDA_BASE diff --git a/pcbnew/class_drc_item.cpp b/pcbnew/class_drc_item.cpp index 375d0d30cb..5a9490aa5c 100644 --- a/pcbnew/class_drc_item.cpp +++ b/pcbnew/class_drc_item.cpp @@ -73,6 +73,10 @@ wxString DRC_ITEM::GetErrorText() const return wxString( _("Copper areas intersect or are too close")); case DRCE_NON_EXISTANT_NET_FOR_ZONE_OUTLINE: return wxString( _("Copper area has a non existent net name")); + case DRCE_HOLE_NEAR_PAD: + return wxString( _("Hole near pad")); + case DRCE_HOLE_NEAR_TRACK: + return wxString( _("Hole near track")); default: diff --git a/pcbnew/class_pad.h b/pcbnew/class_pad.h index 173169c8a2..7900c6c86b 100644 --- a/pcbnew/class_pad.h +++ b/pcbnew/class_pad.h @@ -11,9 +11,9 @@ class Pcb3D_GLCanvas; class D_PAD : public BOARD_CONNECTED_ITEM { private: - int m_NetCode; // Net number for fast comparisons - wxString m_Netname; // Full net name like /mysheet/mysubsheet/vout used by eeschema - wxString m_ShortNetname; // short net name, like vout from /mysheet/mysubsheet/vout + int m_NetCode; // Net number for fast comparisons + wxString m_Netname; // Full net name like /mysheet/mysubsheet/vout used by eeschema + wxString m_ShortNetname; // short net name, like vout from /mysheet/mysubsheet/vout public: @@ -27,17 +27,17 @@ public: */ }; - int m_Masque_Layer; // Bitwise layer :1= copper layer, 15= cmp, + int m_Masque_Layer; // Bitwise layer :1= copper layer, 15= cmp, // 2..14 = internal layers // 16 .. 31 = technical layers - int m_PadShape; // Shape: PAD_CIRCLE, PAD_RECT, PAD_OVAL, PAD_TRAPEZOID - int m_DrillShape; // Shape PAD_CIRCLE, PAD_OVAL + int m_PadShape; // Shape: PAD_CIRCLE, PAD_RECT, PAD_OVAL, PAD_TRAPEZOID + int m_DrillShape; // Shape PAD_CIRCLE, PAD_OVAL - wxSize m_Drill; // Drill diam (drill shape = PAD_CIRCLE) or drill size(shape = OVAL) + wxSize m_Drill; // Drill diam (drill shape = PAD_CIRCLE) or drill size(shape = OVAL) // for drill shape = PAD_CIRCLE, drill diam = m_Drill.x - wxSize m_Offset; /* This parameter is usefull only for oblong pads (it can be used for other + wxSize m_Offset; /* This parameter is usefull only for oblong pads (it can be used for other * shapes, but without any interest). * this is the offset between the pad hole and the pad shape (you must * understand here pad shape = copper area around the hole) @@ -61,15 +61,15 @@ public: int m_Orient; // in 1/10 degrees private: - int m_SubRatsnest; // variable used in rats nest computations - // handle subnet (block) number in ratsnet connection + int m_SubRatsnest; // variable used in rats nest computations + // handle subnet (block) number in ratsnet connection public: D_PAD( MODULE* parent ); D_PAD( D_PAD* pad ); ~D_PAD(); - void Copy( D_PAD* source ); + void Copy( D_PAD* source ); D_PAD* Next() { return (D_PAD*) Pnext; } @@ -79,6 +79,7 @@ public: * @return const wxString * , a pointer to the full netname */ wxString GetNetname() const { return m_Netname; } + /** * Function GetShortNetname * @return const wxString * , a pointer to the short netname @@ -89,13 +90,13 @@ public: * Function SetNetname * @param const wxString : the new netname */ - void SetNetname( const wxString & aNetname ); + void SetNetname( const wxString& aNetname ); /** * Function GetShape * @return the shape of this pad. */ - int GetShape( ) { return (m_PadShape & 0xFF); } + int GetShape() { return m_PadShape & 0xFF; } /** * Function GetPosition @@ -113,8 +114,9 @@ public: m_Pos = aPos; } + /* Reading and writing data on files */ - int ReadDescr( FILE* File, int* LineNum = NULL ); + int ReadDescr( FILE* File, int* LineNum = NULL ); /** * Function Save @@ -122,21 +124,21 @@ public: * @param aFile The FILE to write to. * @return bool - true if success writing else false. */ - bool Save( FILE* aFile ) const; + bool Save( FILE* aFile ) const; /* drawing functions */ - void Draw( WinEDA_DrawPanel* panel, wxDC* DC, - int aDrawMode, const wxPoint& offset = ZeroOffset ); + void Draw( WinEDA_DrawPanel* panel, wxDC* DC, + int aDrawMode, const wxPoint& offset = ZeroOffset ); - void Draw3D( Pcb3D_GLCanvas* glcanvas ); + void Draw3D( Pcb3D_GLCanvas* glcanvas ); // others - void SetPadName( const wxString& name ); // Change pad name - wxString ReturnStringPadName(); // Return pad name as string in a wxString - void ReturnStringPadName( wxString& text ); // Return pad name as string in a buffer - void ComputeRayon(); // compute m_Rayon, rayon du cercle exinscrit - const wxPoint ReturnShapePos(); // retourne la position + void SetPadName( const wxString& name ); // Change pad name + wxString ReturnStringPadName(); // Return pad name as string in a wxString + void ReturnStringPadName( wxString& text ); // Return pad name as string in a buffer + void ComputeRayon(); // compute m_Rayon, rayon du cercle exinscrit + const wxPoint ReturnShapePos(); // retourne la position /** @@ -154,7 +156,7 @@ public: * Is virtual from EDA_BaseStruct. * @param frame A WinEDA_DrawFrame in which to print status information. */ - void Display_Infos( WinEDA_DrawFrame* frame ); + void Display_Infos( WinEDA_DrawFrame* frame ); /** @@ -165,7 +167,7 @@ public: * @param aLayer The layer to test for. * @return bool - true if on given layer, else false. */ - bool IsOnLayer( int aLayer ) const; + bool IsOnLayer( int aLayer ) const; /** @@ -174,7 +176,7 @@ public: * @param refPos A wxPoint to test * @return bool - true if a hit, else false */ - bool HitTest( const wxPoint& refPos ); + bool HitTest( const wxPoint& refPos ); /** * Function GetClass @@ -192,7 +194,7 @@ public: * returns the bounding box of this pad * Mainly used to redraw the screen area occuped by the pad */ - EDA_Rect GetBoundingBox(); + EDA_Rect GetBoundingBox(); /** * Function Compare @@ -202,7 +204,7 @@ public: static int Compare( const D_PAD* padref, const D_PAD* padcmp ); -#if defined (DEBUG) +#if defined(DEBUG) /** * Function Show @@ -216,4 +218,4 @@ public: #endif }; -typedef class D_PAD * LISTE_PAD; +typedef class D_PAD* LISTE_PAD; diff --git a/pcbnew/class_pad_draw_functions.cpp b/pcbnew/class_pad_draw_functions.cpp index eb428090f0..90efb80c81 100644 --- a/pcbnew/class_pad_draw_functions.cpp +++ b/pcbnew/class_pad_draw_functions.cpp @@ -362,8 +362,8 @@ void D_PAD::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode, const wxPoin } RotatePoint( &delta_cx, &delta_cy, angle ); - GRFillCSegm( &panel->m_ClipBox, DC, ux0 + delta_cx, uy0 + delta_cy, - ux0 - delta_cx, uy0 - delta_cy, + GRFillCSegm( &panel->m_ClipBox, DC, cx0 + delta_cx, cy0 + delta_cy, + cx0 - delta_cx, cy0 - delta_cy, rotdx, color ); break; diff --git a/pcbnew/drc.cpp b/pcbnew/drc.cpp index 163edda0d1..9eee93fbc7 100644 --- a/pcbnew/drc.cpp +++ b/pcbnew/drc.cpp @@ -62,7 +62,7 @@ void DRC::ShowDialog() // copy data retained in this DRC object into the m_ui DrcPanel: PutValueInLocalUnits( *m_ui->m_SetClearance, g_DesignSettings.m_TrackClearence, - m_mainWindow->m_InternalUnits );; + m_mainWindow->m_InternalUnits );; m_ui->m_Pad2PadTestCtrl->SetValue( m_doPad2PadTest ); m_ui->m_ZonesTestCtrl->SetValue( m_doZonesTest ); @@ -74,7 +74,7 @@ void DRC::ShowDialog() else updatePointers(); - m_ui->Show(true); + m_ui->Show( true ); } @@ -102,15 +102,15 @@ DRC::DRC( WinEDA_PcbFrame* aPcbWindow ) { m_mainWindow = aPcbWindow; m_drawPanel = aPcbWindow->DrawPanel; - m_pcb = aPcbWindow->GetBoard(); - m_ui = 0; + m_pcb = aPcbWindow->GetBoard(); + m_ui = 0; // establish initial values for everything: m_doPad2PadTest = true; m_doUnconnectedTest = true; - m_doZonesTest = false; + m_doZonesTest = false; - m_doCreateRptFile = false; + m_doCreateRptFile = false; // m_rptFilename set to empty by its constructor @@ -118,10 +118,10 @@ DRC::DRC( WinEDA_PcbFrame* aPcbWindow ) m_spotcx = 0; m_spotcy = 0; - m_finx = 0; - m_finy = 0; + m_finx = 0; + m_finy = 0; - m_segmAngle = 0; + m_segmAngle = 0; m_segmLength = 0; m_xcliplo = 0; @@ -132,13 +132,15 @@ DRC::DRC( WinEDA_PcbFrame* aPcbWindow ) m_drawPanel = 0; } + DRC::~DRC() { // maybe someday look at pointainer.h <- google for "pointainer.h" - for( unsigned i=0; iDisplay_Infos( m_mainWindow ); @@ -184,7 +187,6 @@ int DRC::Drc( ZONE_CONTAINER * aArea, int CornerIndex ) } - void DRC::RunTests() { // Ensure ratsnest is up to date: @@ -216,7 +218,6 @@ void DRC::RunTests() } - /***************************************************************/ void DRC::ListUnconnectedPads() /***************************************************************/ @@ -234,7 +235,7 @@ void DRC::updatePointers() m_drawPanel = m_mainWindow->DrawPanel; m_pcb = m_mainWindow->GetBoard(); - if ( m_ui ) // Use diag list boxes only in DRC dialog + if( m_ui ) // Use diag list boxes only in DRC dialog { m_ui->m_ClearanceListBox->SetList( new DRC_LIST_MARKERS( m_pcb ) ); @@ -245,7 +246,7 @@ void DRC::updatePointers() void DRC::testTracks() { - for( TRACK* segm = m_pcb->m_Track; segm && segm->Next(); segm=segm->Next() ) + for( TRACK* segm = m_pcb->m_Track; segm && segm->Next(); segm = segm->Next() ) { if( !doTrackDrc( segm, segm->Next(), true ) ) { @@ -257,27 +258,29 @@ void DRC::testTracks() } +/***********************/ void DRC::testPad2Pad() +/***********************/ { std::vector sortedPads; CreateSortedPadListByXCoord( m_pcb, &sortedPads ); // find the max size of the pads (used to stop the test) - int max_size = 0; + int max_size = 0; - for( unsigned i=0; im_Rayon > max_size ) + if( pad->m_Rayon > max_size ) // m_Rayon is the radius value of the circle containing the pad max_size = pad->m_Rayon; } // Test the pads D_PAD** listEnd = &sortedPads[ sortedPads.size() ]; - for( unsigned i=0; im_Ratsnest; - for( int i=0; iGetNumRatsnests(); ++i, ++rat ) + for( int i = 0; iGetNumRatsnests(); ++i, ++rat ) { if( (rat->status & CH_ACTIF) == 0 ) continue; - D_PAD* padStart = rat->pad_start; - D_PAD* padEnd = rat->pad_end; + D_PAD* padStart = rat->pad_start; + D_PAD* padEnd = rat->pad_end; DRC_ITEM* uncItem = new DRC_ITEM( DRCE_UNCONNECTED_PADS, padStart->GetPosition(), - padStart->MenuText(m_pcb), padEnd->MenuText(m_pcb), - padStart->GetPosition(), padEnd->GetPosition() ); + padStart->MenuText( m_pcb ), padEnd->MenuText( m_pcb ), + padStart->GetPosition(), padEnd->GetPosition() ); m_unconnected.push_back( uncItem ); } } + /**********************************************/ -void DRC::testZones(bool adoTestFillSegments) +void DRC::testZones( bool adoTestFillSegments ) /**********************************************/ { - // Test copper areas for valide netcodes // if a netcode is < 0 the netname was not found when reading a netlist // if a netcode is == 0 the netname is void, and the zone is not connected. @@ -331,12 +334,12 @@ void DRC::testZones(bool adoTestFillSegments) for( int ii = 0; ii < m_pcb->GetAreaCount(); ii++ ) { ZONE_CONTAINER* Area_To_Test = m_pcb->GetArea( ii ); - if( ! Area_To_Test->IsOnCopperLayer() ) + if( !Area_To_Test->IsOnCopperLayer() ) continue; if( Area_To_Test->GetNet() < 0 ) { m_currentMarker = fillMarker( Area_To_Test, - DRCE_NON_EXISTANT_NET_FOR_ZONE_OUTLINE, m_currentMarker ); + DRCE_NON_EXISTANT_NET_FOR_ZONE_OUTLINE, m_currentMarker ); m_pcb->Add( m_currentMarker ); m_currentMarker = 0; } @@ -375,11 +378,11 @@ void DRC::testZones(bool adoTestFillSegments) MARKER* DRC::fillMarker( TRACK* aTrack, BOARD_ITEM* aItem, int aErrorCode, MARKER* fillMe ) { - wxString textA = aTrack->MenuText( m_pcb ); - wxString textB; + wxString textA = aTrack->MenuText( m_pcb ); + wxString textB; - wxPoint position; - wxPoint posB; + wxPoint position; + wxPoint posB; if( aItem ) // aItem might be NULL { @@ -402,8 +405,8 @@ MARKER* DRC::fillMarker( TRACK* aTrack, BOARD_ITEM* aItem, int aErrorCode, MARKE // distance from end of aTrack. position = track->m_Start; - double dToEnd = hypot( endPos.x - aTrack->m_End.x, - endPos.y - aTrack->m_End.y ); + double dToEnd = hypot( endPos.x - aTrack->m_End.x, + endPos.y - aTrack->m_End.y ); double dToStart = hypot( position.x - aTrack->m_End.x, position.y - aTrack->m_End.y ); @@ -417,23 +420,23 @@ MARKER* DRC::fillMarker( TRACK* aTrack, BOARD_ITEM* aItem, int aErrorCode, MARKE if( fillMe ) { - if ( aItem ) + if( aItem ) fillMe->SetData( aErrorCode, position, - textA, aTrack->GetPosition(), - textB, posB ); + textA, aTrack->GetPosition(), + textB, posB ); else fillMe->SetData( aErrorCode, position, textA, aTrack->GetPosition() ); } else { - if ( aItem ) + if( aItem ) fillMe = new MARKER( aErrorCode, position, - textA, aTrack->GetPosition(), - textB, posB ); + textA, aTrack->GetPosition(), + textB, posB ); else fillMe = new MARKER( aErrorCode, position, - textA, aTrack->GetPosition() ); + textA, aTrack->GetPosition() ); } return fillMe; @@ -442,11 +445,11 @@ MARKER* DRC::fillMarker( TRACK* aTrack, BOARD_ITEM* aItem, int aErrorCode, MARKE MARKER* DRC::fillMarker( D_PAD* aPad, D_PAD* bPad, int aErrorCode, MARKER* fillMe ) { - wxString textA = aPad->MenuText( m_pcb ); - wxString textB = bPad->MenuText( m_pcb ); + wxString textA = aPad->MenuText( m_pcb ); + wxString textB = bPad->MenuText( m_pcb ); - wxPoint posA = aPad->GetPosition(); - wxPoint posB = bPad->GetPosition(); + wxPoint posA = aPad->GetPosition(); + wxPoint posB = bPad->GetPosition(); if( fillMe ) fillMe->SetData( aErrorCode, posA, textA, posA, textB, posB ); @@ -456,11 +459,12 @@ MARKER* DRC::fillMarker( D_PAD* aPad, D_PAD* bPad, int aErrorCode, MARKER* fillM return fillMe; } -MARKER* DRC::fillMarker( ZONE_CONTAINER * aArea, int aErrorCode, MARKER* fillMe ) -{ - wxString textA = aArea->MenuText( m_pcb ); - wxPoint posA = aArea->GetPosition(); +MARKER* DRC::fillMarker( ZONE_CONTAINER* aArea, int aErrorCode, MARKER* fillMe ) +{ + wxString textA = aArea->MenuText( m_pcb ); + + wxPoint posA = aArea->GetPosition(); if( fillMe ) fillMe->SetData( aErrorCode, posA, textA, posA ); @@ -471,11 +475,14 @@ MARKER* DRC::fillMarker( ZONE_CONTAINER * aArea, int aErrorCode, MARKER* fillMe } -MARKER* DRC::fillMarker( const ZONE_CONTAINER * aArea, const wxPoint & aPos, int aErrorCode, MARKER* fillMe ) +MARKER* DRC::fillMarker( const ZONE_CONTAINER* aArea, + const wxPoint& aPos, + int aErrorCode, + MARKER* fillMe ) { - wxString textA = aArea->MenuText( m_pcb ); + wxString textA = aArea->MenuText( m_pcb ); - wxPoint posA = aPos; + wxPoint posA = aPos; if( fillMe ) fillMe->SetData( aErrorCode, posA, textA, posA ); @@ -499,8 +506,8 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) // l'origine du segment de reference wxPoint shape_pos; - org_X = aRefSeg->m_Start.x; - org_Y = aRefSeg->m_Start.y; + org_X = aRefSeg->m_Start.x; + org_Y = aRefSeg->m_Start.y; m_finx = dx = aRefSeg->m_End.x - org_X; m_finy = dy = aRefSeg->m_End.y - org_Y; @@ -515,41 +522,38 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) if( aRefSeg->Type() == TYPE_VIA ) { // test if via's hole is bigger than its diameter - // This test seems necessary since the dialog box that displays the - // desired via hole size and width does not enforce a hole size smaller - // than the via's diameter. + // This test is necessary since the via hole size and width can be modified + // and an default via hole can be bigger than some vias sizes if( aRefSeg->GetDrillValue() > aRefSeg->m_Width ) { -#if 0 // a temporary way to fix a bad board here, change for your values - if( aRefSeg->GetDrillValue()==120 && aRefSeg->m_Width==100 ) - aRefSeg->m_Width = 180; -#else m_currentMarker = fillMarker( aRefSeg, NULL, - DRCE_VIA_HOLE_BIGGER, m_currentMarker ); + DRCE_VIA_HOLE_BIGGER, m_currentMarker ); return false; -#endif } - // For microvias: test if they are blindvias and only between 2 layers + // For microvias: test if they are blind vias and only between 2 layers // because they are used for very small drill size and are drill by laser // and **only** one layer can be drilled if( aRefSeg->Shape() == VIA_MICROVIA ) { - int layer1, layer2; + int layer1, layer2; bool err = true; - ((SEGVIA*)aRefSeg)->ReturnLayerPair(&layer1, &layer2); - if (layer1> layer2 ) EXCHG(layer1,layer2); + ( (SEGVIA*) aRefSeg )->ReturnLayerPair( &layer1, &layer2 ); + if( layer1> layer2 ) + EXCHG( layer1, layer2 ); + // test: - if (layer1 == COPPER_LAYER_N && layer2 == LAYER_N_2 ) err = false; - if (layer1 == (g_DesignSettings.m_CopperLayerCount - 2 ) && layer2 == LAYER_CMP_N ) err = false; - if ( err ) + if( layer1 == COPPER_LAYER_N && layer2 == LAYER_N_2 ) + err = false; + if( layer1 == (g_DesignSettings.m_CopperLayerCount - 2 ) && layer2 == LAYER_CMP_N ) + err = false; + if( err ) { m_currentMarker = fillMarker( aRefSeg, NULL, - DRCE_MICRO_VIA_INCORRECT_LAYER_PAIR, m_currentMarker ); + DRCE_MICRO_VIA_INCORRECT_LAYER_PAIR, m_currentMarker ); return false; } } - } // for a non horizontal or vertical segment Compute the segment angle @@ -577,7 +581,7 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) if( testPads ) { - for( unsigned ii=0; iim_Pads.size(); ++ii ) + for( unsigned ii = 0; iim_Pads.size(); ++ii ) { D_PAD* pad = m_pcb->m_Pads[ii]; @@ -593,7 +597,7 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) if( pad->m_Drill.x == 0 ) continue; - pseudo_pad.m_Size = pad->m_Drill; + pseudo_pad.m_Size = pad->m_Drill; pseudo_pad.SetPosition( pad->GetPosition() ); pseudo_pad.m_PadShape = pad->m_DrillShape; pseudo_pad.m_Orient = pad->m_Orient; @@ -603,10 +607,10 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) m_spotcy = pseudo_pad.GetPosition().y - org_Y; if( !checkClearanceSegmToPad( &pseudo_pad, w_dist, - g_DesignSettings.m_TrackClearence ) ) + g_DesignSettings.m_TrackClearence ) ) { m_currentMarker = fillMarker( aRefSeg, pad, - DRCE_TRACK_NEAR_THROUGH_HOLE, m_currentMarker ); + DRCE_TRACK_NEAR_THROUGH_HOLE, m_currentMarker ); return false; } continue; @@ -615,18 +619,18 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) /* 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( pad->GetNet() && // the pad must be connected - net_code_ref == pad->GetNet() ) // the pad net is the same as current net -> Ok + if( pad->GetNet() // the pad must be connected + && net_code_ref == pad->GetNet() ) // the pad net is the same as current net -> Ok continue; // DRC for the pad shape_pos = pad->ReturnShapePos(); - m_spotcx = shape_pos.x - org_X; - m_spotcy = shape_pos.y - org_Y; + m_spotcx = shape_pos.x - org_X; + m_spotcy = shape_pos.y - org_Y; if( !checkClearanceSegmToPad( pad, w_dist, g_DesignSettings.m_TrackClearence ) ) { m_currentMarker = fillMarker( aRefSeg, pad, - DRCE_TRACK_NEAR_PAD, m_currentMarker ); + DRCE_TRACK_NEAR_PAD, m_currentMarker ); return false; } } @@ -639,7 +643,7 @@ 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() ) + for( track = aStart; track; track = track->Next() ) { // coord des extremites du segment teste dans le repere modifie int x0; @@ -682,7 +686,7 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) if( (int) hypot( x0, y0 ) < w_dist ) { m_currentMarker = fillMarker( aRefSeg, track, - DRCE_VIA_NEAR_VIA, m_currentMarker ); + DRCE_VIA_NEAR_VIA, m_currentMarker ); return false; } } @@ -698,7 +702,7 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) if( !checkMarginToCircle( x0, y0, w_dist, dx ) ) { m_currentMarker = fillMarker( track, aRefSeg, - DRCE_VIA_NEAR_TRACK, m_currentMarker ); + DRCE_VIA_NEAR_TRACK, m_currentMarker ); return false; } } @@ -724,7 +728,7 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) continue; m_currentMarker = fillMarker( aRefSeg, track, - DRCE_TRACK_NEAR_VIA, m_currentMarker ); + DRCE_TRACK_NEAR_VIA, m_currentMarker ); return false; } @@ -739,21 +743,21 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) continue; if( x0 > xf ) - EXCHG( x0, xf ); /* pour que x0 <= xf */ + EXCHG( x0, xf ); /* pour que x0 <= xf */ - if( x0 > (-w_dist) && x0 < (m_segmLength + w_dist) ) /* possible error drc */ + if( x0 > (-w_dist) && x0 < (m_segmLength + w_dist) ) /* possible error drc */ { /* Fine test : we consider the rounded shape of the ends */ if( x0 >= 0 && x0 <= m_segmLength ) { m_currentMarker = fillMarker( aRefSeg, track, - DRCE_TRACK_ENDS1, m_currentMarker ); + DRCE_TRACK_ENDS1, m_currentMarker ); return false; } if( !checkMarginToCircle( x0, y0, w_dist, m_segmLength ) ) { m_currentMarker = fillMarker( aRefSeg, track, - DRCE_TRACK_ENDS2, m_currentMarker ); + DRCE_TRACK_ENDS2, m_currentMarker ); return false; } } @@ -763,13 +767,13 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) if( xf >= 0 && xf <= m_segmLength ) { m_currentMarker = fillMarker( aRefSeg, track, - DRCE_TRACK_ENDS3, m_currentMarker ); + DRCE_TRACK_ENDS3, m_currentMarker ); return false; } if( !checkMarginToCircle( xf, yf, w_dist, m_segmLength ) ) { m_currentMarker = fillMarker( aRefSeg, track, - DRCE_TRACK_ENDS4, m_currentMarker ); + DRCE_TRACK_ENDS4, m_currentMarker ); return false; } } @@ -777,7 +781,7 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) if( x0 <=0 && xf >= 0 ) { m_currentMarker = fillMarker( aRefSeg, track, - DRCE_TRACK_UNKNOWN1, m_currentMarker ); + DRCE_TRACK_UNKNOWN1, m_currentMarker ); return false; } } @@ -792,7 +796,7 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) if( (y0 < 0) && (yf > 0) ) { m_currentMarker = fillMarker( aRefSeg, track, - DRCE_TRACKS_CROSSING, m_currentMarker ); + DRCE_TRACKS_CROSSING, m_currentMarker ); return false; } @@ -800,13 +804,13 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) if( !checkMarginToCircle( x0, y0, w_dist, m_segmLength ) ) { m_currentMarker = fillMarker( aRefSeg, track, - DRCE_ENDS_PROBLEM1, m_currentMarker ); + DRCE_ENDS_PROBLEM1, m_currentMarker ); return false; } if( !checkMarginToCircle( xf, yf, w_dist, m_segmLength ) ) { m_currentMarker = fillMarker( aRefSeg, track, - DRCE_ENDS_PROBLEM2, m_currentMarker ); + DRCE_ENDS_PROBLEM2, m_currentMarker ); return false; } } @@ -834,7 +838,7 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) if( !checkLine( x0, y0, xf, yf ) ) { m_currentMarker = fillMarker( aRefSeg, track, - DRCE_ENDS_PROBLEM3, m_currentMarker ); + DRCE_ENDS_PROBLEM3, m_currentMarker ); return false; } else // The drc error is due to the starting or the ending point of the reference segment @@ -869,13 +873,13 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) if( !checkMarginToCircle( rx0, ry0, w_dist, dx ) ) { m_currentMarker = fillMarker( aRefSeg, track, - DRCE_ENDS_PROBLEM4, m_currentMarker ); + DRCE_ENDS_PROBLEM4, m_currentMarker ); return false; } if( !checkMarginToCircle( rxf, ryf, w_dist, dx ) ) { m_currentMarker = fillMarker( aRefSeg, track, - DRCE_ENDS_PROBLEM5, m_currentMarker ); + DRCE_ENDS_PROBLEM5, m_currentMarker ); return false; } } @@ -889,15 +893,20 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) /*****************************************************************************/ bool DRC::doPadToPadsDrc( D_PAD* aRefPad, LISTE_PAD* aStart, LISTE_PAD* aEnd, - int max_size ) + int max_size ) /*****************************************************************************/ { - int layerMask = aRefPad->m_Masque_Layer & ALL_CU_LAYERS; + int layerMask = aRefPad->m_Masque_Layer & ALL_CU_LAYERS; - int x_limite = max_size + g_DesignSettings.m_TrackClearence + - aRefPad->m_Rayon + aRefPad->GetPosition().x; + int x_limite = max_size + g_DesignSettings.m_TrackClearence + + aRefPad->m_Rayon + aRefPad->GetPosition().x; - for( LISTE_PAD* pad_list=aStart; pad_listm_Pos.x > x_limite ) break; - /* No probleme if pads are on different copper layers */ + + /* No problem if pads are on different copper layers, + * but their hole (if any ) can create RDC error because they are on all copper layers, so we test them + */ if( (pad->m_Masque_Layer & layerMask ) == 0 ) + { + /* if holes are in the same location and have the same size and shape, this can be accepted */ + if( pad->GetPosition() == aRefPad->GetPosition() + && pad->m_Drill == aRefPad->m_Drill + && pad->m_DrillShape == aRefPad->m_DrillShape ) + { + if( aRefPad->m_DrillShape == PAD_CIRCLE ) + continue; + if( pad->m_Orient == aRefPad->m_Orient ) // for oval holes: must also have the same orientation + continue; + } + + /* Here, we must test clearance between holes and pads + * dummypad size and shape is adjusted to pad drill size and shape + */ + if( pad->m_Drill.x ) // pad under testing has a hole, test this hole against pad reference + { + dummypad.SetPosition( pad->GetPosition() ); + dummypad.m_Size = pad->m_Drill; + dummypad.m_PadShape = pad->m_DrillShape == PAD_OVAL ? PAD_OVAL : PAD_CIRCLE; + dummypad.m_Orient = pad->m_Orient; + if( !checkClearancePadToPad( aRefPad, &dummypad, g_DesignSettings.m_TrackClearence ) ) + { + // here we have a drc error on pad! + m_currentMarker = fillMarker( pad, aRefPad, + DRCE_HOLE_NEAR_PAD, m_currentMarker ); + return false; + } + } + if( aRefPad->m_Drill.x ) // pad reference has a hole + { + dummypad.SetPosition( aRefPad->GetPosition() ); + dummypad.m_Size = aRefPad->m_Drill; + dummypad.m_PadShape = aRefPad->m_DrillShape == PAD_OVAL ? PAD_OVAL : PAD_CIRCLE; + dummypad.m_Orient = aRefPad->m_Orient; + if( !checkClearancePadToPad( pad, &dummypad, g_DesignSettings.m_TrackClearence ) ) + { + // here we have a drc erroron aRefPad! + m_currentMarker = fillMarker( aRefPad, pad, + DRCE_HOLE_NEAR_PAD, m_currentMarker ); + return false; + } + } 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() && (aRefPad->GetNet() == pad->GetNet()) ) + if( pad->GetNet() && ( aRefPad->GetNet() == pad->GetNet() ) ) continue; /* No problem if pads are from the same footprint * and have the same pad number ( equivalent pads ) */ - if( (pad->GetParent() == aRefPad->GetParent()) && (pad->m_NumPadName == aRefPad->m_NumPadName) ) + if( ( pad->GetParent() == aRefPad->GetParent() ) + && (pad->m_NumPadName == aRefPad->m_NumPadName) ) continue; if( !checkClearancePadToPad( aRefPad, pad, g_DesignSettings.m_TrackClearence ) ) { // here we have a drc error! m_currentMarker = fillMarker( aRefPad, pad, - DRCE_PAD_NEAR_PAD1, m_currentMarker ); + DRCE_PAD_NEAR_PAD1, m_currentMarker ); return false; } } @@ -941,6 +998,7 @@ bool DRC::checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad, const int dist_mi { wxPoint rel_pos; int dist;; + wxPoint shape_pos; int pad_angle; @@ -980,10 +1038,10 @@ bool DRC::checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad, const int dist_mi switch( aRefPad->m_PadShape ) { case PAD_CIRCLE: // aRefPad is like a track segment with a null lenght - m_segmLength = 0; - m_segmAngle = 0; + m_segmLength = 0; + m_segmAngle = 0; - m_finx = m_finy = 0; + m_finx = m_finy = 0; m_spotcx = rel_pos.x; m_spotcy = rel_pos.y; @@ -998,8 +1056,8 @@ bool DRC::checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad, const int dist_mi if( aPad->m_PadShape == PAD_RECT ) { wxSize size = aPad->m_Size; - if( (pad_angle == 0) || (pad_angle == 900) || (pad_angle == 1800) || - (pad_angle == 2700) ) + if( (pad_angle == 0) || (pad_angle == 900) || (pad_angle == 1800) + || (pad_angle == 2700) ) { if( (pad_angle == 900) || (pad_angle == 2700) ) { @@ -1007,7 +1065,7 @@ bool DRC::checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad, const int dist_mi } // Test DRC: - diag = false; + diag = false; rel_pos.x = ABS( rel_pos.x ); rel_pos.y = ABS( rel_pos.y ); @@ -1020,7 +1078,7 @@ bool DRC::checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad, const int dist_mi } else // Any other orient { - /* TODO : any orient ... */ + /* TODO : any orient ... */ } } break; @@ -1029,34 +1087,35 @@ bool DRC::checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad, const int dist_mi { /* Create and test a track segment with same dimensions */ int segm_width; - m_segmAngle = aRefPad->m_Orient; // Segment orient. - if( aRefPad->m_Size.y < aRefPad->m_Size.x ) /* We suppose the pad is an horizontal oval */ + m_segmAngle = aRefPad->m_Orient; // Segment orient. + if( aRefPad->m_Size.y < aRefPad->m_Size.x ) /* We suppose the pad is an horizontal oval */ { - segm_width = aRefPad->m_Size.y; - m_segmLength = aRefPad->m_Size.x - aRefPad->m_Size.y; + segm_width = aRefPad->m_Size.y; + m_segmLength = aRefPad->m_Size.x - aRefPad->m_Size.y; } else // it was a vertical oval, change to a rotated horizontal one { - segm_width = aRefPad->m_Size.x; - m_segmLength = aRefPad->m_Size.y - aRefPad->m_Size.x; + segm_width = aRefPad->m_Size.x; + m_segmLength = aRefPad->m_Size.y - aRefPad->m_Size.x; m_segmAngle += 900; } /* the start point must be 0,0 and currently rel_pos is relative the center of pad coordinate */ - int sx = -m_segmLength / 2, sy = 0; // Start point coordinate of the horizontal equivalent segment + int sx = -m_segmLength / 2, sy = 0; // Start point coordinate of the horizontal equivalent segment - RotatePoint( &sx, &sy, m_segmAngle ); // True start point coordinate of the equivalent segment + RotatePoint( &sx, &sy, m_segmAngle ); // True start point coordinate of the equivalent segment m_spotcx = rel_pos.x + sx; m_spotcy = rel_pos.y + sy; // pad position / segment origin - m_finx = -sx; - m_finy = -sy; // end of segment coordinate + m_finx = -sx; + m_finy = -sy; // end of segment coordinate diag = checkClearanceSegmToPad( aPad, segm_width / 2, dist_min ); break; } + case PAD_TRAPEZOID: default: /* TODO...*/ break; @@ -1227,6 +1286,7 @@ bool DRC::checkClearanceSegmToPad( const D_PAD* pad_to_test, int w_segm, int dis return true; } + /**********************************************************************/ bool DRC::checkMarginToCircle( int cx, int cy, int radius, int longueur ) /**********************************************************************/ @@ -1250,7 +1310,6 @@ bool DRC::checkMarginToCircle( int cx, int cy, int radius, int longueur ) } - /**********************************************/ /* int Tst_Ligne(int x1,int y1,int x2,int y2) */ /**********************************************/ @@ -1310,14 +1369,14 @@ bool DRC::checkLine( int x1, int y1, int x2, int y2 ) { temp = USCALE( (y2 - y1), (m_xcliplo - x1), (x2 - x1) ); y1 += temp; - x1 = m_xcliplo; + x1 = m_xcliplo; WHEN_INSIDE; } if( x2 > m_xcliphi ) { temp = USCALE( (y2 - y1), (x2 - m_xcliphi), (x2 - x1) ); y2 -= temp; - x2 = m_xcliphi; + x2 = m_xcliphi; WHEN_INSIDE; } } @@ -1351,24 +1410,23 @@ bool DRC::checkLine( int x1, int y1, int x2, int y2 ) { temp = USCALE( (y1 - y2), (m_xcliplo - x1), (x2 - x1) ); y1 -= temp; - x1 = m_xcliplo; + x1 = m_xcliplo; WHEN_INSIDE; } if( x2 > m_xcliphi ) { temp = USCALE( (y1 - y2), (x2 - m_xcliphi), (x2 - x1) ); y2 += temp; - x2 = m_xcliphi; + x2 = m_xcliphi; WHEN_INSIDE; } } - if( ( (x2 + x1)/2 <= m_xcliphi ) && ( (x2 + x1)/2 >= m_xcliplo ) \ - && ( (y2 + y1)/2 <= m_ycliphi ) && ( (y2 + y1)/2 >= m_ycliplo ) ) + if( ( (x2 + x1) / 2 <= m_xcliphi ) && ( (x2 + x1) / 2 >= m_xcliplo ) \ + && ( (y2 + y1) / 2 <= m_ycliphi ) && ( (y2 + y1) / 2 >= m_ycliplo ) ) { return false; } else return true; } - diff --git a/pcbnew/drc_stuff.h b/pcbnew/drc_stuff.h index decb7d5abf..c74d1ee96e 100644 --- a/pcbnew/drc_stuff.h +++ b/pcbnew/drc_stuff.h @@ -58,6 +58,8 @@ #define COPPERAREA_INSIDE_COPPERAREA 22 ///< copper area outlines intersect #define COPPERAREA_CLOSE_TO_COPPERAREA 23 ///< copper area outlines are too close #define DRCE_NON_EXISTANT_NET_FOR_ZONE_OUTLINE 24 ///< copper area outline has an incorrect netcode due to a netname not found +#define DRCE_HOLE_NEAR_PAD 25 ///< hole too close to pad +#define DRCE_HOLE_NEAR_TRACK 26 ///< hole too close to track /** * Class DRC_ITEM