DRC: added test pads to holes (pcbnew). Others minor changes

This commit is contained in:
charras 2009-03-23 19:54:15 +00:00
parent aa45e5a441
commit 0f725ee2fc
10 changed files with 248 additions and 172 deletions

View File

@ -5,6 +5,14 @@ Started 2007-June-11
Please add newer entries at the top, list the date and your name with Please add newer entries at the top, list the date and your name with
email address. email address.
2009-mar-16 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr>
================================================================================
++pcbnew:
in DRC: added test pads to holes.
++Al:
minor changes.
2009-mar-16 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr> 2009-mar-16 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr>
================================================================================ ================================================================================

View File

@ -198,7 +198,9 @@ wxString MakeFileName( const wxString& dir,
{ {
if( !wxIsAbsolutePath( shortname ) ) 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 */ { /* no absolute path in shortname, add dir to shortname */
fullfilename = dir; fullfilename = dir;
} }

View File

@ -190,7 +190,7 @@
<property name="name">orientationRadioBox</property> <property name="name">orientationRadioBox</property>
<property name="permission">protected</property> <property name="permission">protected</property>
<property name="pos"></property> <property name="pos"></property>
<property name="selection">3</property> <property name="selection">0</property>
<property name="size"></property> <property name="size"></property>
<property name="style">wxRA_SPECIFY_COLS</property> <property name="style">wxRA_SPECIFY_COLS</property>
<property name="subclass"></property> <property name="subclass"></property>
@ -255,7 +255,7 @@
<property name="name">mirrorRadioBox</property> <property name="name">mirrorRadioBox</property>
<property name="permission">protected</property> <property name="permission">protected</property>
<property name="pos"></property> <property name="pos"></property>
<property name="selection">2</property> <property name="selection">0</property>
<property name="size"></property> <property name="size"></property>
<property name="style">wxRA_SPECIFY_COLS</property> <property name="style">wxRA_SPECIFY_COLS</property>
<property name="subclass"></property> <property name="subclass"></property>
@ -872,7 +872,7 @@
<property name="name">m_StyleRadioBox</property> <property name="name">m_StyleRadioBox</property>
<property name="permission">protected</property> <property name="permission">protected</property>
<property name="pos"></property> <property name="pos"></property>
<property name="selection">3</property> <property name="selection">0</property>
<property name="size"></property> <property name="size"></property>
<property name="style">wxRA_SPECIFY_COLS</property> <property name="style">wxRA_SPECIFY_COLS</property>
<property name="subclass"></property> <property name="subclass"></property>

View File

@ -39,7 +39,7 @@ DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_FBP::DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_FBP(
wxString orientationRadioBoxChoices[] = { _("0"), _("+90"), _("180"), _("-90") }; wxString orientationRadioBoxChoices[] = { _("0"), _("+90"), _("180"), _("-90") };
int orientationRadioBoxNChoices = sizeof( orientationRadioBoxChoices ) / sizeof( wxString ); int orientationRadioBoxNChoices = sizeof( orientationRadioBoxChoices ) / sizeof( wxString );
orientationRadioBox = new wxRadioBox( this, wxID_ANY, _("Orientation (Degrees)"), wxDefaultPosition, wxDefaultSize, orientationRadioBoxNChoices, orientationRadioBoxChoices, 1, wxRA_SPECIFY_COLS ); 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") ); orientationRadioBox->SetToolTip( _("Select if the component is to be rotated when drawn") );
orientationSizer->Add( orientationRadioBox, 1, wxALL, 8 ); 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 |") }; wxString mirrorRadioBoxChoices[] = { _("Normal"), _("Mirror ---"), _("Mirror |") };
int mirrorRadioBoxNChoices = sizeof( mirrorRadioBoxChoices ) / sizeof( wxString ); int mirrorRadioBoxNChoices = sizeof( mirrorRadioBoxChoices ) / sizeof( wxString );
mirrorRadioBox = new wxRadioBox( this, wxID_ANY, _("Mirror"), wxDefaultPosition, wxDefaultSize, mirrorRadioBoxNChoices, mirrorRadioBoxChoices, 1, wxRA_SPECIFY_COLS ); 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") ); mirrorRadioBox->SetToolTip( _("Pick the graphical transformation to be used when displaying the component, if any") );
mirrorSizer->Add( mirrorRadioBox, 1, wxALL, 8 ); 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") }; wxString m_StyleRadioBoxChoices[] = { _("Normal"), _("Italic"), _("Bold"), _("Bold Italic") };
int m_StyleRadioBoxNChoices = sizeof( m_StyleRadioBoxChoices ) / sizeof( wxString ); 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 = 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") ); m_StyleRadioBox->SetToolTip( _("The style of the currently selected field's text in the schemati") );
visibilitySizer->Add( m_StyleRadioBox, 1, wxBOTTOM|wxRIGHT|wxLEFT, 5 ); visibilitySizer->Add( m_StyleRadioBox, 1, wxBOTTOM|wxRIGHT|wxLEFT, 5 );

View File

@ -3,7 +3,7 @@
#ifndef KICAD_BUILD_VERSION #ifndef KICAD_BUILD_VERSION
#define KICAD_BUILD_VERSION #define KICAD_BUILD_VERSION
#define BUILD_VERSION wxT("(20090216-final)") #define BUILD_VERSION wxT("(20090332-unstable)")
COMMON_GLOBL wxString g_BuildVersion COMMON_GLOBL wxString g_BuildVersion
#ifdef EDA_BASE #ifdef EDA_BASE

View File

@ -73,6 +73,10 @@ wxString DRC_ITEM::GetErrorText() const
return wxString( _("Copper areas intersect or are too close")); return wxString( _("Copper areas intersect or are too close"));
case DRCE_NON_EXISTANT_NET_FOR_ZONE_OUTLINE: case DRCE_NON_EXISTANT_NET_FOR_ZONE_OUTLINE:
return wxString( _("Copper area has a non existent net name")); 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: default:

View File

@ -11,9 +11,9 @@ class Pcb3D_GLCanvas;
class D_PAD : public BOARD_CONNECTED_ITEM class D_PAD : public BOARD_CONNECTED_ITEM
{ {
private: private:
int m_NetCode; // Net number for fast comparisons int m_NetCode; // Net number for fast comparisons
wxString m_Netname; // Full net name like /mysheet/mysubsheet/vout used by eeschema 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 wxString m_ShortNetname; // short net name, like vout from /mysheet/mysubsheet/vout
public: 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 // 2..14 = internal layers
// 16 .. 31 = technical layers // 16 .. 31 = technical layers
int m_PadShape; // Shape: PAD_CIRCLE, PAD_RECT, PAD_OVAL, PAD_TRAPEZOID int m_PadShape; // Shape: PAD_CIRCLE, PAD_RECT, PAD_OVAL, PAD_TRAPEZOID
int m_DrillShape; // Shape PAD_CIRCLE, PAD_OVAL 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 // 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). * shapes, but without any interest).
* this is the offset between the pad hole and the pad shape (you must * this is the offset between the pad hole and the pad shape (you must
* understand here pad shape = copper area around the hole) * understand here pad shape = copper area around the hole)
@ -61,15 +61,15 @@ public:
int m_Orient; // in 1/10 degrees int m_Orient; // in 1/10 degrees
private: private:
int m_SubRatsnest; // variable used in rats nest computations int m_SubRatsnest; // variable used in rats nest computations
// handle subnet (block) number in ratsnet connection // handle subnet (block) number in ratsnet connection
public: public:
D_PAD( MODULE* parent ); D_PAD( MODULE* parent );
D_PAD( D_PAD* pad ); D_PAD( D_PAD* pad );
~D_PAD(); ~D_PAD();
void Copy( D_PAD* source ); void Copy( D_PAD* source );
D_PAD* Next() { return (D_PAD*) Pnext; } D_PAD* Next() { return (D_PAD*) Pnext; }
@ -79,6 +79,7 @@ public:
* @return const wxString * , a pointer to the full netname * @return const wxString * , a pointer to the full netname
*/ */
wxString GetNetname() const { return m_Netname; } wxString GetNetname() const { return m_Netname; }
/** /**
* Function GetShortNetname * Function GetShortNetname
* @return const wxString * , a pointer to the short netname * @return const wxString * , a pointer to the short netname
@ -89,13 +90,13 @@ public:
* Function SetNetname * Function SetNetname
* @param const wxString : the new netname * @param const wxString : the new netname
*/ */
void SetNetname( const wxString & aNetname ); void SetNetname( const wxString& aNetname );
/** /**
* Function GetShape * Function GetShape
* @return the shape of this pad. * @return the shape of this pad.
*/ */
int GetShape( ) { return (m_PadShape & 0xFF); } int GetShape() { return m_PadShape & 0xFF; }
/** /**
* Function GetPosition * Function GetPosition
@ -113,8 +114,9 @@ public:
m_Pos = aPos; m_Pos = aPos;
} }
/* Reading and writing data on files */ /* Reading and writing data on files */
int ReadDescr( FILE* File, int* LineNum = NULL ); int ReadDescr( FILE* File, int* LineNum = NULL );
/** /**
* Function Save * Function Save
@ -122,21 +124,21 @@ public:
* @param aFile The FILE to write to. * @param aFile The FILE to write to.
* @return bool - true if success writing else false. * @return bool - true if success writing else false.
*/ */
bool Save( FILE* aFile ) const; bool Save( FILE* aFile ) const;
/* drawing functions */ /* drawing functions */
void Draw( WinEDA_DrawPanel* panel, wxDC* DC, void Draw( WinEDA_DrawPanel* panel, wxDC* DC,
int aDrawMode, const wxPoint& offset = ZeroOffset ); int aDrawMode, const wxPoint& offset = ZeroOffset );
void Draw3D( Pcb3D_GLCanvas* glcanvas ); void Draw3D( Pcb3D_GLCanvas* glcanvas );
// others // others
void SetPadName( const wxString& name ); // Change pad name void SetPadName( const wxString& name ); // Change pad name
wxString ReturnStringPadName(); // Return pad name as string in a wxString wxString ReturnStringPadName(); // Return pad name as string in a wxString
void ReturnStringPadName( wxString& text ); // Return pad name as string in a buffer void ReturnStringPadName( wxString& text ); // Return pad name as string in a buffer
void ComputeRayon(); // compute m_Rayon, rayon du cercle exinscrit void ComputeRayon(); // compute m_Rayon, rayon du cercle exinscrit
const wxPoint ReturnShapePos(); // retourne la position const wxPoint ReturnShapePos(); // retourne la position
/** /**
@ -154,7 +156,7 @@ public:
* Is virtual from EDA_BaseStruct. * Is virtual from EDA_BaseStruct.
* @param frame A WinEDA_DrawFrame in which to print status information. * @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. * @param aLayer The layer to test for.
* @return bool - true if on given layer, else false. * @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 * @param refPos A wxPoint to test
* @return bool - true if a hit, else false * @return bool - true if a hit, else false
*/ */
bool HitTest( const wxPoint& refPos ); bool HitTest( const wxPoint& refPos );
/** /**
* Function GetClass * Function GetClass
@ -192,7 +194,7 @@ public:
* returns the bounding box of this pad * returns the bounding box of this pad
* Mainly used to redraw the screen area occuped by the pad * Mainly used to redraw the screen area occuped by the pad
*/ */
EDA_Rect GetBoundingBox(); EDA_Rect GetBoundingBox();
/** /**
* Function Compare * Function Compare
@ -202,7 +204,7 @@ public:
static int Compare( const D_PAD* padref, const D_PAD* padcmp ); static int Compare( const D_PAD* padref, const D_PAD* padcmp );
#if defined (DEBUG) #if defined(DEBUG)
/** /**
* Function Show * Function Show
@ -216,4 +218,4 @@ public:
#endif #endif
}; };
typedef class D_PAD * LISTE_PAD; typedef class D_PAD* LISTE_PAD;

View File

@ -362,8 +362,8 @@ void D_PAD::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode, const wxPoin
} }
RotatePoint( &delta_cx, &delta_cy, angle ); RotatePoint( &delta_cx, &delta_cy, angle );
GRFillCSegm( &panel->m_ClipBox, DC, ux0 + delta_cx, uy0 + delta_cy, GRFillCSegm( &panel->m_ClipBox, DC, cx0 + delta_cx, cy0 + delta_cy,
ux0 - delta_cx, uy0 - delta_cy, cx0 - delta_cx, cy0 - delta_cy,
rotdx, color ); rotdx, color );
break; break;

View File

@ -62,7 +62,7 @@ void DRC::ShowDialog()
// copy data retained in this DRC object into the m_ui DrcPanel: // copy data retained in this DRC object into the m_ui DrcPanel:
PutValueInLocalUnits( *m_ui->m_SetClearance, g_DesignSettings.m_TrackClearence, 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_Pad2PadTestCtrl->SetValue( m_doPad2PadTest );
m_ui->m_ZonesTestCtrl->SetValue( m_doZonesTest ); m_ui->m_ZonesTestCtrl->SetValue( m_doZonesTest );
@ -74,7 +74,7 @@ void DRC::ShowDialog()
else else
updatePointers(); updatePointers();
m_ui->Show(true); m_ui->Show( true );
} }
@ -102,15 +102,15 @@ DRC::DRC( WinEDA_PcbFrame* aPcbWindow )
{ {
m_mainWindow = aPcbWindow; m_mainWindow = aPcbWindow;
m_drawPanel = aPcbWindow->DrawPanel; m_drawPanel = aPcbWindow->DrawPanel;
m_pcb = aPcbWindow->GetBoard(); m_pcb = aPcbWindow->GetBoard();
m_ui = 0; m_ui = 0;
// establish initial values for everything: // establish initial values for everything:
m_doPad2PadTest = true; m_doPad2PadTest = true;
m_doUnconnectedTest = true; m_doUnconnectedTest = true;
m_doZonesTest = false; m_doZonesTest = false;
m_doCreateRptFile = false; m_doCreateRptFile = false;
// m_rptFilename set to empty by its constructor // m_rptFilename set to empty by its constructor
@ -118,10 +118,10 @@ DRC::DRC( WinEDA_PcbFrame* aPcbWindow )
m_spotcx = 0; m_spotcx = 0;
m_spotcy = 0; m_spotcy = 0;
m_finx = 0; m_finx = 0;
m_finy = 0; m_finy = 0;
m_segmAngle = 0; m_segmAngle = 0;
m_segmLength = 0; m_segmLength = 0;
m_xcliplo = 0; m_xcliplo = 0;
@ -132,13 +132,15 @@ DRC::DRC( WinEDA_PcbFrame* aPcbWindow )
m_drawPanel = 0; m_drawPanel = 0;
} }
DRC::~DRC() DRC::~DRC()
{ {
// maybe someday look at pointainer.h <- google for "pointainer.h" // maybe someday look at pointainer.h <- google for "pointainer.h"
for( unsigned i=0; i<m_unconnected.size(); ++i ) for( unsigned i = 0; i<m_unconnected.size(); ++i )
delete m_unconnected[i]; delete m_unconnected[i];
} }
/*********************************************/ /*********************************************/
int DRC::Drc( TRACK* aRefSegm, TRACK* aList ) int DRC::Drc( TRACK* aRefSegm, TRACK* aList )
/*********************************************/ /*********************************************/
@ -158,8 +160,9 @@ int DRC::Drc( TRACK* aRefSegm, TRACK* aList )
/**************************************************************/ /**************************************************************/
int DRC::Drc( ZONE_CONTAINER * aArea, int CornerIndex ) int DRC::Drc( ZONE_CONTAINER* aArea, int CornerIndex )
/*************************************************************/ /*************************************************************/
/** /**
* Function Drc * Function Drc
* tests the outline segment starting at CornerIndex and returns the result and displays the error * tests the outline segment starting at CornerIndex and returns the result and displays the error
@ -173,7 +176,7 @@ int DRC::Drc( ZONE_CONTAINER * aArea, int CornerIndex )
{ {
updatePointers(); updatePointers();
if( ! doEdgeZoneDrc( aArea, CornerIndex ) ) if( !doEdgeZoneDrc( aArea, CornerIndex ) )
{ {
wxASSERT( m_currentMarker ); wxASSERT( m_currentMarker );
m_currentMarker->Display_Infos( m_mainWindow ); m_currentMarker->Display_Infos( m_mainWindow );
@ -184,7 +187,6 @@ int DRC::Drc( ZONE_CONTAINER * aArea, int CornerIndex )
} }
void DRC::RunTests() void DRC::RunTests()
{ {
// Ensure ratsnest is up to date: // Ensure ratsnest is up to date:
@ -216,7 +218,6 @@ void DRC::RunTests()
} }
/***************************************************************/ /***************************************************************/
void DRC::ListUnconnectedPads() void DRC::ListUnconnectedPads()
/***************************************************************/ /***************************************************************/
@ -234,7 +235,7 @@ void DRC::updatePointers()
m_drawPanel = m_mainWindow->DrawPanel; m_drawPanel = m_mainWindow->DrawPanel;
m_pcb = m_mainWindow->GetBoard(); 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 ) ); m_ui->m_ClearanceListBox->SetList( new DRC_LIST_MARKERS( m_pcb ) );
@ -245,7 +246,7 @@ void DRC::updatePointers()
void DRC::testTracks() 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 ) ) if( !doTrackDrc( segm, segm->Next(), true ) )
{ {
@ -257,27 +258,29 @@ void DRC::testTracks()
} }
/***********************/
void DRC::testPad2Pad() void DRC::testPad2Pad()
/***********************/
{ {
std::vector<D_PAD*> sortedPads; std::vector<D_PAD*> sortedPads;
CreateSortedPadListByXCoord( m_pcb, &sortedPads ); CreateSortedPadListByXCoord( m_pcb, &sortedPads );
// find the max size of the pads (used to stop the test) // find the max size of the pads (used to stop the test)
int max_size = 0; int max_size = 0;
for( unsigned i=0; i<sortedPads.size(); ++i ) for( unsigned i = 0; i<sortedPads.size(); ++i )
{ {
D_PAD* pad = sortedPads[i]; D_PAD* pad = sortedPads[i];
if( pad->m_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; max_size = pad->m_Rayon;
} }
// Test the pads // Test the pads
D_PAD** listEnd = &sortedPads[ sortedPads.size() ]; D_PAD** listEnd = &sortedPads[ sortedPads.size() ];
for( unsigned i=0; i<sortedPads.size(); ++i ) for( unsigned i = 0; i<sortedPads.size(); ++i )
{ {
D_PAD* pad = sortedPads[i]; D_PAD* pad = sortedPads[i];
@ -303,27 +306,27 @@ void DRC::testUnconnected()
return; return;
CHEVELU* rat = m_pcb->m_Ratsnest; CHEVELU* rat = m_pcb->m_Ratsnest;
for( int i=0; i<m_pcb->GetNumRatsnests(); ++i, ++rat ) for( int i = 0; i<m_pcb->GetNumRatsnests(); ++i, ++rat )
{ {
if( (rat->status & CH_ACTIF) == 0 ) if( (rat->status & CH_ACTIF) == 0 )
continue; continue;
D_PAD* padStart = rat->pad_start; D_PAD* padStart = rat->pad_start;
D_PAD* padEnd = rat->pad_end; D_PAD* padEnd = rat->pad_end;
DRC_ITEM* uncItem = new DRC_ITEM( DRCE_UNCONNECTED_PADS, padStart->GetPosition(), DRC_ITEM* uncItem = new DRC_ITEM( DRCE_UNCONNECTED_PADS, padStart->GetPosition(),
padStart->MenuText(m_pcb), padEnd->MenuText(m_pcb), padStart->MenuText( m_pcb ), padEnd->MenuText( m_pcb ),
padStart->GetPosition(), padEnd->GetPosition() ); padStart->GetPosition(), padEnd->GetPosition() );
m_unconnected.push_back( uncItem ); m_unconnected.push_back( uncItem );
} }
} }
/**********************************************/ /**********************************************/
void DRC::testZones(bool adoTestFillSegments) void DRC::testZones( bool adoTestFillSegments )
/**********************************************/ /**********************************************/
{ {
// Test copper areas for valide netcodes // 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 was not found when reading a netlist
// if a netcode is == 0 the netname is void, and the zone is not connected. // 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++ ) for( int ii = 0; ii < m_pcb->GetAreaCount(); ii++ )
{ {
ZONE_CONTAINER* Area_To_Test = m_pcb->GetArea( ii ); ZONE_CONTAINER* Area_To_Test = m_pcb->GetArea( ii );
if( ! Area_To_Test->IsOnCopperLayer() ) if( !Area_To_Test->IsOnCopperLayer() )
continue; continue;
if( Area_To_Test->GetNet() < 0 ) if( Area_To_Test->GetNet() < 0 )
{ {
m_currentMarker = fillMarker( Area_To_Test, 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_pcb->Add( m_currentMarker );
m_currentMarker = 0; m_currentMarker = 0;
} }
@ -375,11 +378,11 @@ void DRC::testZones(bool adoTestFillSegments)
MARKER* DRC::fillMarker( TRACK* aTrack, BOARD_ITEM* aItem, int aErrorCode, MARKER* fillMe ) MARKER* DRC::fillMarker( TRACK* aTrack, BOARD_ITEM* aItem, int aErrorCode, MARKER* fillMe )
{ {
wxString textA = aTrack->MenuText( m_pcb ); wxString textA = aTrack->MenuText( m_pcb );
wxString textB; wxString textB;
wxPoint position; wxPoint position;
wxPoint posB; wxPoint posB;
if( aItem ) // aItem might be NULL 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. // distance from end of aTrack.
position = track->m_Start; position = track->m_Start;
double dToEnd = hypot( endPos.x - aTrack->m_End.x, double dToEnd = hypot( endPos.x - aTrack->m_End.x,
endPos.y - aTrack->m_End.y ); endPos.y - aTrack->m_End.y );
double dToStart = hypot( position.x - aTrack->m_End.x, double dToStart = hypot( position.x - aTrack->m_End.x,
position.y - aTrack->m_End.y ); position.y - aTrack->m_End.y );
@ -417,23 +420,23 @@ MARKER* DRC::fillMarker( TRACK* aTrack, BOARD_ITEM* aItem, int aErrorCode, MARKE
if( fillMe ) if( fillMe )
{ {
if ( aItem ) if( aItem )
fillMe->SetData( aErrorCode, position, fillMe->SetData( aErrorCode, position,
textA, aTrack->GetPosition(), textA, aTrack->GetPosition(),
textB, posB ); textB, posB );
else else
fillMe->SetData( aErrorCode, position, fillMe->SetData( aErrorCode, position,
textA, aTrack->GetPosition() ); textA, aTrack->GetPosition() );
} }
else else
{ {
if ( aItem ) if( aItem )
fillMe = new MARKER( aErrorCode, position, fillMe = new MARKER( aErrorCode, position,
textA, aTrack->GetPosition(), textA, aTrack->GetPosition(),
textB, posB ); textB, posB );
else else
fillMe = new MARKER( aErrorCode, position, fillMe = new MARKER( aErrorCode, position,
textA, aTrack->GetPosition() ); textA, aTrack->GetPosition() );
} }
return fillMe; 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 ) MARKER* DRC::fillMarker( D_PAD* aPad, D_PAD* bPad, int aErrorCode, MARKER* fillMe )
{ {
wxString textA = aPad->MenuText( m_pcb ); wxString textA = aPad->MenuText( m_pcb );
wxString textB = bPad->MenuText( m_pcb ); wxString textB = bPad->MenuText( m_pcb );
wxPoint posA = aPad->GetPosition(); wxPoint posA = aPad->GetPosition();
wxPoint posB = bPad->GetPosition(); wxPoint posB = bPad->GetPosition();
if( fillMe ) if( fillMe )
fillMe->SetData( aErrorCode, posA, textA, posA, textB, posB ); 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; 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 ) if( fillMe )
fillMe->SetData( aErrorCode, posA, textA, posA ); 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 ) if( fillMe )
fillMe->SetData( aErrorCode, posA, textA, posA ); 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 // l'origine du segment de reference
wxPoint shape_pos; wxPoint shape_pos;
org_X = aRefSeg->m_Start.x; org_X = aRefSeg->m_Start.x;
org_Y = aRefSeg->m_Start.y; org_Y = aRefSeg->m_Start.y;
m_finx = dx = aRefSeg->m_End.x - org_X; m_finx = dx = aRefSeg->m_End.x - org_X;
m_finy = dy = aRefSeg->m_End.y - org_Y; 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 ) if( aRefSeg->Type() == TYPE_VIA )
{ {
// test if via's hole is bigger than its diameter // test if via's hole is bigger than its diameter
// This test seems necessary since the dialog box that displays the // This test is necessary since the via hole size and width can be modified
// desired via hole size and width does not enforce a hole size smaller // and an default via hole can be bigger than some vias sizes
// than the via's diameter.
if( aRefSeg->GetDrillValue() > aRefSeg->m_Width ) 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, m_currentMarker = fillMarker( aRefSeg, NULL,
DRCE_VIA_HOLE_BIGGER, m_currentMarker ); DRCE_VIA_HOLE_BIGGER, m_currentMarker );
return false; 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 // because they are used for very small drill size and are drill by laser
// and **only** one layer can be drilled // and **only** one layer can be drilled
if( aRefSeg->Shape() == VIA_MICROVIA ) if( aRefSeg->Shape() == VIA_MICROVIA )
{ {
int layer1, layer2; int layer1, layer2;
bool err = true; bool err = true;
((SEGVIA*)aRefSeg)->ReturnLayerPair(&layer1, &layer2); ( (SEGVIA*) aRefSeg )->ReturnLayerPair( &layer1, &layer2 );
if (layer1> layer2 ) EXCHG(layer1,layer2); if( layer1> layer2 )
EXCHG( layer1, layer2 );
// test: // test:
if (layer1 == COPPER_LAYER_N && layer2 == LAYER_N_2 ) err = false; if( layer1 == COPPER_LAYER_N && layer2 == LAYER_N_2 )
if (layer1 == (g_DesignSettings.m_CopperLayerCount - 2 ) && layer2 == LAYER_CMP_N ) err = false; err = false;
if ( err ) if( layer1 == (g_DesignSettings.m_CopperLayerCount - 2 ) && layer2 == LAYER_CMP_N )
err = false;
if( err )
{ {
m_currentMarker = fillMarker( aRefSeg, NULL, m_currentMarker = fillMarker( aRefSeg, NULL,
DRCE_MICRO_VIA_INCORRECT_LAYER_PAIR, m_currentMarker ); DRCE_MICRO_VIA_INCORRECT_LAYER_PAIR, m_currentMarker );
return false; return false;
} }
} }
} }
// for a non horizontal or vertical segment Compute the segment angle // 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 ) if( testPads )
{ {
for( unsigned ii=0; ii<m_pcb->m_Pads.size(); ++ii ) for( unsigned ii = 0; ii<m_pcb->m_Pads.size(); ++ii )
{ {
D_PAD* pad = m_pcb->m_Pads[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 ) if( pad->m_Drill.x == 0 )
continue; continue;
pseudo_pad.m_Size = pad->m_Drill; pseudo_pad.m_Size = pad->m_Drill;
pseudo_pad.SetPosition( pad->GetPosition() ); pseudo_pad.SetPosition( pad->GetPosition() );
pseudo_pad.m_PadShape = pad->m_DrillShape; pseudo_pad.m_PadShape = pad->m_DrillShape;
pseudo_pad.m_Orient = pad->m_Orient; 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; m_spotcy = pseudo_pad.GetPosition().y - org_Y;
if( !checkClearanceSegmToPad( &pseudo_pad, w_dist, if( !checkClearanceSegmToPad( &pseudo_pad, w_dist,
g_DesignSettings.m_TrackClearence ) ) g_DesignSettings.m_TrackClearence ) )
{ {
m_currentMarker = fillMarker( aRefSeg, pad, m_currentMarker = fillMarker( aRefSeg, pad,
DRCE_TRACK_NEAR_THROUGH_HOLE, m_currentMarker ); DRCE_TRACK_NEAR_THROUGH_HOLE, m_currentMarker );
return false; return false;
} }
continue; 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 ) /* 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) * but no problem if the pad netcode is the current netcode (same net)
*/ */
if( pad->GetNet() && // the pad must be connected if( pad->GetNet() // the pad must be connected
net_code_ref == pad->GetNet() ) // the pad net is the same as current net -> Ok && net_code_ref == pad->GetNet() ) // the pad net is the same as current net -> Ok
continue; continue;
// DRC for the pad // DRC for the pad
shape_pos = pad->ReturnShapePos(); shape_pos = pad->ReturnShapePos();
m_spotcx = shape_pos.x - org_X; m_spotcx = shape_pos.x - org_X;
m_spotcy = shape_pos.y - org_Y; m_spotcy = shape_pos.y - org_Y;
if( !checkClearanceSegmToPad( pad, w_dist, g_DesignSettings.m_TrackClearence ) ) if( !checkClearanceSegmToPad( pad, w_dist, g_DesignSettings.m_TrackClearence ) )
{ {
m_currentMarker = fillMarker( aRefSeg, pad, m_currentMarker = fillMarker( aRefSeg, pad,
DRCE_TRACK_NEAR_PAD, m_currentMarker ); DRCE_TRACK_NEAR_PAD, m_currentMarker );
return false; 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 // At this point the reference segment is the X axis
// Test the reference segment with other track segments // 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 // coord des extremites du segment teste dans le repere modifie
int x0; int x0;
@ -682,7 +686,7 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
if( (int) hypot( x0, y0 ) < w_dist ) if( (int) hypot( x0, y0 ) < w_dist )
{ {
m_currentMarker = fillMarker( aRefSeg, track, m_currentMarker = fillMarker( aRefSeg, track,
DRCE_VIA_NEAR_VIA, m_currentMarker ); DRCE_VIA_NEAR_VIA, m_currentMarker );
return false; return false;
} }
} }
@ -698,7 +702,7 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
if( !checkMarginToCircle( x0, y0, w_dist, dx ) ) if( !checkMarginToCircle( x0, y0, w_dist, dx ) )
{ {
m_currentMarker = fillMarker( track, aRefSeg, m_currentMarker = fillMarker( track, aRefSeg,
DRCE_VIA_NEAR_TRACK, m_currentMarker ); DRCE_VIA_NEAR_TRACK, m_currentMarker );
return false; return false;
} }
} }
@ -724,7 +728,7 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
continue; continue;
m_currentMarker = fillMarker( aRefSeg, track, m_currentMarker = fillMarker( aRefSeg, track,
DRCE_TRACK_NEAR_VIA, m_currentMarker ); DRCE_TRACK_NEAR_VIA, m_currentMarker );
return false; return false;
} }
@ -739,21 +743,21 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
continue; continue;
if( x0 > xf ) 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 */ /* Fine test : we consider the rounded shape of the ends */
if( x0 >= 0 && x0 <= m_segmLength ) if( x0 >= 0 && x0 <= m_segmLength )
{ {
m_currentMarker = fillMarker( aRefSeg, track, m_currentMarker = fillMarker( aRefSeg, track,
DRCE_TRACK_ENDS1, m_currentMarker ); DRCE_TRACK_ENDS1, m_currentMarker );
return false; return false;
} }
if( !checkMarginToCircle( x0, y0, w_dist, m_segmLength ) ) if( !checkMarginToCircle( x0, y0, w_dist, m_segmLength ) )
{ {
m_currentMarker = fillMarker( aRefSeg, track, m_currentMarker = fillMarker( aRefSeg, track,
DRCE_TRACK_ENDS2, m_currentMarker ); DRCE_TRACK_ENDS2, m_currentMarker );
return false; return false;
} }
} }
@ -763,13 +767,13 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
if( xf >= 0 && xf <= m_segmLength ) if( xf >= 0 && xf <= m_segmLength )
{ {
m_currentMarker = fillMarker( aRefSeg, track, m_currentMarker = fillMarker( aRefSeg, track,
DRCE_TRACK_ENDS3, m_currentMarker ); DRCE_TRACK_ENDS3, m_currentMarker );
return false; return false;
} }
if( !checkMarginToCircle( xf, yf, w_dist, m_segmLength ) ) if( !checkMarginToCircle( xf, yf, w_dist, m_segmLength ) )
{ {
m_currentMarker = fillMarker( aRefSeg, track, m_currentMarker = fillMarker( aRefSeg, track,
DRCE_TRACK_ENDS4, m_currentMarker ); DRCE_TRACK_ENDS4, m_currentMarker );
return false; return false;
} }
} }
@ -777,7 +781,7 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
if( x0 <=0 && xf >= 0 ) if( x0 <=0 && xf >= 0 )
{ {
m_currentMarker = fillMarker( aRefSeg, track, m_currentMarker = fillMarker( aRefSeg, track,
DRCE_TRACK_UNKNOWN1, m_currentMarker ); DRCE_TRACK_UNKNOWN1, m_currentMarker );
return false; return false;
} }
} }
@ -792,7 +796,7 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
if( (y0 < 0) && (yf > 0) ) if( (y0 < 0) && (yf > 0) )
{ {
m_currentMarker = fillMarker( aRefSeg, track, m_currentMarker = fillMarker( aRefSeg, track,
DRCE_TRACKS_CROSSING, m_currentMarker ); DRCE_TRACKS_CROSSING, m_currentMarker );
return false; return false;
} }
@ -800,13 +804,13 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
if( !checkMarginToCircle( x0, y0, w_dist, m_segmLength ) ) if( !checkMarginToCircle( x0, y0, w_dist, m_segmLength ) )
{ {
m_currentMarker = fillMarker( aRefSeg, track, m_currentMarker = fillMarker( aRefSeg, track,
DRCE_ENDS_PROBLEM1, m_currentMarker ); DRCE_ENDS_PROBLEM1, m_currentMarker );
return false; return false;
} }
if( !checkMarginToCircle( xf, yf, w_dist, m_segmLength ) ) if( !checkMarginToCircle( xf, yf, w_dist, m_segmLength ) )
{ {
m_currentMarker = fillMarker( aRefSeg, track, m_currentMarker = fillMarker( aRefSeg, track,
DRCE_ENDS_PROBLEM2, m_currentMarker ); DRCE_ENDS_PROBLEM2, m_currentMarker );
return false; return false;
} }
} }
@ -834,7 +838,7 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
if( !checkLine( x0, y0, xf, yf ) ) if( !checkLine( x0, y0, xf, yf ) )
{ {
m_currentMarker = fillMarker( aRefSeg, track, m_currentMarker = fillMarker( aRefSeg, track,
DRCE_ENDS_PROBLEM3, m_currentMarker ); DRCE_ENDS_PROBLEM3, m_currentMarker );
return false; return false;
} }
else // The drc error is due to the starting or the ending point of the reference segment 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 ) ) if( !checkMarginToCircle( rx0, ry0, w_dist, dx ) )
{ {
m_currentMarker = fillMarker( aRefSeg, track, m_currentMarker = fillMarker( aRefSeg, track,
DRCE_ENDS_PROBLEM4, m_currentMarker ); DRCE_ENDS_PROBLEM4, m_currentMarker );
return false; return false;
} }
if( !checkMarginToCircle( rxf, ryf, w_dist, dx ) ) if( !checkMarginToCircle( rxf, ryf, w_dist, dx ) )
{ {
m_currentMarker = fillMarker( aRefSeg, track, m_currentMarker = fillMarker( aRefSeg, track,
DRCE_ENDS_PROBLEM5, m_currentMarker ); DRCE_ENDS_PROBLEM5, m_currentMarker );
return false; 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, 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 + int x_limite = max_size + g_DesignSettings.m_TrackClearence +
aRefPad->m_Rayon + aRefPad->GetPosition().x; aRefPad->m_Rayon + aRefPad->GetPosition().x;
for( LISTE_PAD* pad_list=aStart; pad_list<aEnd; ++pad_list ) static D_PAD dummypad( (MODULE*) NULL ); // used to test DRC pad to holes: this dummypad is the hole to test
dummypad.m_Masque_Layer = ALL_CU_LAYERS;
for( LISTE_PAD* pad_list = aStart; pad_list<aEnd; ++pad_list )
{ {
D_PAD* pad = *pad_list; D_PAD* pad = *pad_list;
if( pad == aRefPad ) if( pad == aRefPad )
@ -908,25 +917,73 @@ bool DRC::doPadToPadsDrc( D_PAD* aRefPad, LISTE_PAD* aStart, LISTE_PAD* aEnd,
if( pad->m_Pos.x > x_limite ) if( pad->m_Pos.x > x_limite )
break; 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( (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; continue;
}
/* The pad must be in a net (i.e pt_pad->GetNet() != 0 ), /* The pad must be in a net (i.e pt_pad->GetNet() != 0 ),
* But no problem if pads have the same netcode (same net)*/ * 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; continue;
/* No problem if pads are from the same footprint /* No problem if pads are from the same footprint
* and have the same pad number ( equivalent pads ) */ * 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; continue;
if( !checkClearancePadToPad( aRefPad, pad, g_DesignSettings.m_TrackClearence ) ) if( !checkClearancePadToPad( aRefPad, pad, g_DesignSettings.m_TrackClearence ) )
{ {
// here we have a drc error! // here we have a drc error!
m_currentMarker = fillMarker( aRefPad, pad, m_currentMarker = fillMarker( aRefPad, pad,
DRCE_PAD_NEAR_PAD1, m_currentMarker ); DRCE_PAD_NEAR_PAD1, m_currentMarker );
return false; return false;
} }
} }
@ -941,6 +998,7 @@ bool DRC::checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad, const int dist_mi
{ {
wxPoint rel_pos; wxPoint rel_pos;
int dist;; int dist;;
wxPoint shape_pos; wxPoint shape_pos;
int pad_angle; int pad_angle;
@ -980,10 +1038,10 @@ bool DRC::checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad, const int dist_mi
switch( aRefPad->m_PadShape ) switch( aRefPad->m_PadShape )
{ {
case PAD_CIRCLE: // aRefPad is like a track segment with a null lenght case PAD_CIRCLE: // aRefPad is like a track segment with a null lenght
m_segmLength = 0; m_segmLength = 0;
m_segmAngle = 0; m_segmAngle = 0;
m_finx = m_finy = 0; m_finx = m_finy = 0;
m_spotcx = rel_pos.x; m_spotcx = rel_pos.x;
m_spotcy = rel_pos.y; 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 ) if( aPad->m_PadShape == PAD_RECT )
{ {
wxSize size = aPad->m_Size; wxSize size = aPad->m_Size;
if( (pad_angle == 0) || (pad_angle == 900) || (pad_angle == 1800) || if( (pad_angle == 0) || (pad_angle == 900) || (pad_angle == 1800)
(pad_angle == 2700) ) || (pad_angle == 2700) )
{ {
if( (pad_angle == 900) || (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: // Test DRC:
diag = false; diag = false;
rel_pos.x = ABS( rel_pos.x ); rel_pos.x = ABS( rel_pos.x );
rel_pos.y = ABS( rel_pos.y ); 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 else // Any other orient
{ {
/* TODO : any orient ... */ /* TODO : any orient ... */
} }
} }
break; 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 */ /* Create and test a track segment with same dimensions */
int segm_width; int segm_width;
m_segmAngle = aRefPad->m_Orient; // Segment orient. m_segmAngle = aRefPad->m_Orient; // Segment orient.
if( aRefPad->m_Size.y < aRefPad->m_Size.x ) /* We suppose the pad is an horizontal oval */ if( aRefPad->m_Size.y < aRefPad->m_Size.x ) /* We suppose the pad is an horizontal oval */
{ {
segm_width = aRefPad->m_Size.y; segm_width = aRefPad->m_Size.y;
m_segmLength = aRefPad->m_Size.x - 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 else // it was a vertical oval, change to a rotated horizontal one
{ {
segm_width = aRefPad->m_Size.x; segm_width = aRefPad->m_Size.x;
m_segmLength = aRefPad->m_Size.y - aRefPad->m_Size.x; m_segmLength = aRefPad->m_Size.y - aRefPad->m_Size.x;
m_segmAngle += 900; m_segmAngle += 900;
} }
/* the start point must be 0,0 and currently rel_pos is relative the center of pad coordinate */ /* 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_spotcx = rel_pos.x + sx;
m_spotcy = rel_pos.y + sy; // pad position / segment origin m_spotcy = rel_pos.y + sy; // pad position / segment origin
m_finx = -sx; m_finx = -sx;
m_finy = -sy; // end of segment coordinate m_finy = -sy; // end of segment coordinate
diag = checkClearanceSegmToPad( aPad, segm_width / 2, dist_min ); diag = checkClearanceSegmToPad( aPad, segm_width / 2, dist_min );
break; break;
} }
case PAD_TRAPEZOID:
default: default:
/* TODO...*/ /* TODO...*/
break; break;
@ -1227,6 +1286,7 @@ bool DRC::checkClearanceSegmToPad( const D_PAD* pad_to_test, int w_segm, int dis
return true; return true;
} }
/**********************************************************************/ /**********************************************************************/
bool DRC::checkMarginToCircle( int cx, int cy, int radius, int longueur ) 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) */ /* 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) ); temp = USCALE( (y2 - y1), (m_xcliplo - x1), (x2 - x1) );
y1 += temp; y1 += temp;
x1 = m_xcliplo; x1 = m_xcliplo;
WHEN_INSIDE; WHEN_INSIDE;
} }
if( x2 > m_xcliphi ) if( x2 > m_xcliphi )
{ {
temp = USCALE( (y2 - y1), (x2 - m_xcliphi), (x2 - x1) ); temp = USCALE( (y2 - y1), (x2 - m_xcliphi), (x2 - x1) );
y2 -= temp; y2 -= temp;
x2 = m_xcliphi; x2 = m_xcliphi;
WHEN_INSIDE; 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) ); temp = USCALE( (y1 - y2), (m_xcliplo - x1), (x2 - x1) );
y1 -= temp; y1 -= temp;
x1 = m_xcliplo; x1 = m_xcliplo;
WHEN_INSIDE; WHEN_INSIDE;
} }
if( x2 > m_xcliphi ) if( x2 > m_xcliphi )
{ {
temp = USCALE( (y1 - y2), (x2 - m_xcliphi), (x2 - x1) ); temp = USCALE( (y1 - y2), (x2 - m_xcliphi), (x2 - x1) );
y2 += temp; y2 += temp;
x2 = m_xcliphi; x2 = m_xcliphi;
WHEN_INSIDE; WHEN_INSIDE;
} }
} }
if( ( (x2 + x1)/2 <= m_xcliphi ) && ( (x2 + x1)/2 >= m_xcliplo ) \ if( ( (x2 + x1) / 2 <= m_xcliphi ) && ( (x2 + x1) / 2 >= m_xcliplo ) \
&& ( (y2 + y1)/2 <= m_ycliphi ) && ( (y2 + y1)/2 >= m_ycliplo ) ) && ( (y2 + y1) / 2 <= m_ycliphi ) && ( (y2 + y1) / 2 >= m_ycliplo ) )
{ {
return false; return false;
} }
else else
return true; return true;
} }

View File

@ -58,6 +58,8 @@
#define COPPERAREA_INSIDE_COPPERAREA 22 ///< copper area outlines intersect #define COPPERAREA_INSIDE_COPPERAREA 22 ///< copper area outlines intersect
#define COPPERAREA_CLOSE_TO_COPPERAREA 23 ///< copper area outlines are too close #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_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 * Class DRC_ITEM