drc: more code cleaning. Added comments and fixed some erroneous comments. Fixed bug 638839.
fixed bug 641982 (I hope)
This commit is contained in:
parent
577a79bc59
commit
ed54bdfc9d
|
@ -10,7 +10,7 @@ else(ZLIB_FOUND)
|
||||||
# and we try to use it
|
# and we try to use it
|
||||||
# Unfortunately, we have no way to know exactlty the path of zlib.h becuase this file
|
# Unfortunately, we have no way to know exactlty the path of zlib.h becuase this file
|
||||||
# is in wxWidgets sources, not in wxWidgets include path.
|
# is in wxWidgets sources, not in wxWidgets include path.
|
||||||
find_path(ZLIB_INCLUDE_DIR PATHS ${wxWidgets_ROOT_DIR}/../src/zlib/ ${wxWidgets_ROOT_DIR}/src/zlib/ DOC "location of zlib include files")
|
find_path(ZLIB_INCLUDE_DIR zlib.h PATHS ${wxWidgets_ROOT_DIR}/../src/zlib/ ${wxWidgets_ROOT_DIR}/src/zlib/ DOC "location of zlib include files")
|
||||||
find_file(ZLIB_LIBRARIES NAMES ${wxWidgets_LIB_DIR}/libwxzlib-2.8.a ZLIB_LIBRARIES NAMES ${wxWidgets_LIB_DIR}/libwxzlib-2.9.a libwxzlib.a PATHS ${wxWidgets_ROOT_DIR}/lib/ PATH_SUFFIXES gcc_dll DOC "location of wxzlib library file")
|
find_file(ZLIB_LIBRARIES NAMES ${wxWidgets_LIB_DIR}/libwxzlib-2.8.a ZLIB_LIBRARIES NAMES ${wxWidgets_LIB_DIR}/libwxzlib-2.9.a libwxzlib.a PATHS ${wxWidgets_ROOT_DIR}/lib/ PATH_SUFFIXES gcc_dll DOC "location of wxzlib library file")
|
||||||
endif(ZLIB_FOUND)
|
endif(ZLIB_FOUND)
|
||||||
|
|
||||||
|
|
|
@ -96,6 +96,7 @@ set(PCBNEW_SRCS
|
||||||
dist.cpp
|
dist.cpp
|
||||||
dragsegm.cpp
|
dragsegm.cpp
|
||||||
drc.cpp
|
drc.cpp
|
||||||
|
drc_marker_functions.cpp
|
||||||
edgemod.cpp
|
edgemod.cpp
|
||||||
edit.cpp
|
edit.cpp
|
||||||
editedge.cpp
|
editedge.cpp
|
||||||
|
|
|
@ -697,7 +697,7 @@ void MODULE::Set_Rectangle_Encadrement()
|
||||||
*/
|
*/
|
||||||
for( D_PAD* pad = m_Pads; pad; pad = pad->Next() )
|
for( D_PAD* pad = m_Pads; pad; pad = pad->Next() )
|
||||||
{
|
{
|
||||||
rayon = pad->m_Rayon;
|
rayon = pad->m_ShapeMaxRadius;
|
||||||
cx = pad->m_Pos0.x;
|
cx = pad->m_Pos0.x;
|
||||||
cy = pad->m_Pos0.y;
|
cy = pad->m_Pos0.y;
|
||||||
xmin = MIN( xmin, cx - rayon );
|
xmin = MIN( xmin, cx - rayon );
|
||||||
|
|
|
@ -44,7 +44,7 @@ D_PAD::D_PAD( MODULE* parent ) : BOARD_CONNECTED_ITEM( parent, TYPE_PAD )
|
||||||
|
|
||||||
SetSubRatsnest( 0 ); // used in ratsnest
|
SetSubRatsnest( 0 ); // used in ratsnest
|
||||||
// calculations
|
// calculations
|
||||||
ComputeRayon();
|
ComputeShapeMaxRadius();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -53,25 +53,33 @@ D_PAD::~D_PAD()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Calculate the radius of the pad.
|
/* Calculate the radius of the circle containing the pad.
|
||||||
*/
|
*/
|
||||||
void D_PAD::ComputeRayon()
|
void D_PAD::ComputeShapeMaxRadius()
|
||||||
{
|
{
|
||||||
switch( m_PadShape & 0x7F )
|
switch( m_PadShape & 0x7F )
|
||||||
{
|
{
|
||||||
case PAD_CIRCLE:
|
case PAD_CIRCLE:
|
||||||
m_Rayon = m_Size.x / 2;
|
m_ShapeMaxRadius = m_Size.x / 2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PAD_OVAL:
|
case PAD_OVAL:
|
||||||
m_Rayon = MAX( m_Size.x, m_Size.y ) / 2;
|
m_ShapeMaxRadius = MAX( m_Size.x, m_Size.y ) / 2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PAD_RECT:
|
case PAD_RECT:
|
||||||
case PAD_TRAPEZOID:
|
m_ShapeMaxRadius = 1 + (int) ( sqrt( (double) m_Size.y * m_Size.y
|
||||||
m_Rayon = (int) ( sqrt( (double) m_Size.y * m_Size.y
|
|
||||||
+ (double) m_Size.x * m_Size.x ) / 2 );
|
+ (double) m_Size.x * m_Size.x ) / 2 );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PAD_TRAPEZOID:
|
||||||
|
{ wxSize fullsize = m_Size;
|
||||||
|
fullsize.x += ABS(m_DeltaSize.y); // Remember: m_DeltaSize.y is the m_Size.x change
|
||||||
|
fullsize.y += ABS(m_DeltaSize.x); // Remember: m_DeltaSize.x is the m_Size.y change
|
||||||
|
m_ShapeMaxRadius = 1 + (int) ( sqrt( (double) m_Size.y * m_Size.y
|
||||||
|
+ (double) m_Size.x * m_Size.x ) / 2 );
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,11 +92,11 @@ void D_PAD::ComputeRayon()
|
||||||
EDA_Rect D_PAD::GetBoundingBox()
|
EDA_Rect D_PAD::GetBoundingBox()
|
||||||
{
|
{
|
||||||
// Calculate area:
|
// Calculate area:
|
||||||
ComputeRayon(); // calculate the radius of the area, considered as a
|
ComputeShapeMaxRadius(); // calculate the radius of the area, considered as a
|
||||||
// circle
|
// circle
|
||||||
EDA_Rect area;
|
EDA_Rect area;
|
||||||
area.SetOrigin( m_Pos );
|
area.SetOrigin( m_Pos );
|
||||||
area.Inflate( m_Rayon, m_Rayon );
|
area.Inflate( m_ShapeMaxRadius, m_ShapeMaxRadius );
|
||||||
|
|
||||||
return area;
|
return area;
|
||||||
}
|
}
|
||||||
|
@ -185,7 +193,7 @@ void D_PAD::Copy( D_PAD* source )
|
||||||
m_Size = source->m_Size;
|
m_Size = source->m_Size;
|
||||||
m_DeltaSize = source->m_DeltaSize;
|
m_DeltaSize = source->m_DeltaSize;
|
||||||
m_Pos0 = source->m_Pos0;
|
m_Pos0 = source->m_Pos0;
|
||||||
m_Rayon = source->m_Rayon;
|
m_ShapeMaxRadius = source->m_ShapeMaxRadius;
|
||||||
m_PadShape = source->m_PadShape;
|
m_PadShape = source->m_PadShape;
|
||||||
m_Attribut = source->m_Attribut;
|
m_Attribut = source->m_Attribut;
|
||||||
m_Orient = source->m_Orient;
|
m_Orient = source->m_Orient;
|
||||||
|
@ -401,7 +409,7 @@ int D_PAD::ReadDescr( FILE* File, int* LineNum )
|
||||||
m_PadShape = PAD_TRAPEZOID; break;
|
m_PadShape = PAD_TRAPEZOID; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ComputeRayon();
|
ComputeShapeMaxRadius();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'D':
|
case 'D':
|
||||||
|
@ -766,7 +774,7 @@ bool D_PAD::HitTest( const wxPoint& ref_pos )
|
||||||
deltaY = ref_pos.y - shape_pos.y;
|
deltaY = ref_pos.y - shape_pos.y;
|
||||||
|
|
||||||
/* Quick test: a test point must be inside the circle. */
|
/* Quick test: a test point must be inside the circle. */
|
||||||
if( ( abs( deltaX ) > m_Rayon ) || ( abs( deltaY ) > m_Rayon ) )
|
if( ( abs( deltaX ) > m_ShapeMaxRadius ) || ( abs( deltaY ) > m_ShapeMaxRadius ) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
dx = m_Size.x >> 1; // dx also is the radius for rounded pads
|
dx = m_Size.x >> 1; // dx also is the radius for rounded pads
|
||||||
|
|
|
@ -95,7 +95,7 @@ public:
|
||||||
|
|
||||||
wxPoint m_Pos0; // Initial Pad position (i.e. pas position relative to the module anchor, orientation 0
|
wxPoint m_Pos0; // Initial Pad position (i.e. pas position relative to the module anchor, orientation 0
|
||||||
|
|
||||||
int m_Rayon; // radius of pad circle
|
int m_ShapeMaxRadius; // radius of the circle containing the pad shape
|
||||||
int m_Attribut; // NORMAL, PAD_SMD, PAD_CONN
|
int m_Attribut; // NORMAL, PAD_SMD, PAD_CONN
|
||||||
int m_Orient; // in 1/10 degrees
|
int m_Orient; // in 1/10 degrees
|
||||||
static int m_PadSketchModePenSize; // Pen size used to draw pads in sketch mode
|
static int m_PadSketchModePenSize; // Pen size used to draw pads in sketch mode
|
||||||
|
@ -252,7 +252,7 @@ public:
|
||||||
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 radius
|
void ComputeShapeMaxRadius(); // compute radius
|
||||||
const wxPoint ReturnShapePos();
|
const wxPoint ReturnShapePos();
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -647,7 +647,7 @@ void DIALOG_PAD_PROPERTIES::PadPropertiesAccept( wxCommandEvent& event )
|
||||||
m_CurrentPad->m_LocalSolderPasteMargin = g_Pad_Master.m_LocalSolderPasteMargin;
|
m_CurrentPad->m_LocalSolderPasteMargin = g_Pad_Master.m_LocalSolderPasteMargin;
|
||||||
m_CurrentPad->m_LocalSolderPasteMarginRatio = g_Pad_Master.m_LocalSolderPasteMarginRatio;
|
m_CurrentPad->m_LocalSolderPasteMarginRatio = g_Pad_Master.m_LocalSolderPasteMarginRatio;
|
||||||
|
|
||||||
m_CurrentPad->ComputeRayon();
|
m_CurrentPad->ComputeShapeMaxRadius();
|
||||||
|
|
||||||
Module->Set_Rectangle_Encadrement();
|
Module->Set_Rectangle_Encadrement();
|
||||||
m_CurrentPad->DisplayInfo( m_Parent );
|
m_CurrentPad->DisplayInfo( m_Parent );
|
||||||
|
|
312
pcbnew/drc.cpp
312
pcbnew/drc.cpp
|
@ -2,7 +2,7 @@
|
||||||
/*
|
/*
|
||||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2004-2007 Jean-Pierre Charras, jean-pierre.charras@inpg.fr
|
* Copyright (C) 2004-2007 Jean-Pierre Charras, jean-pierre.charras@gipsa-lab.inpg.fr
|
||||||
* Copyright (C) 2007 Dick Hollenbeck, dick@softplc.com
|
* Copyright (C) 2007 Dick Hollenbeck, dick@softplc.com
|
||||||
* Copyright (C) 2007 Kicad Developers, see change_log.txt for contributors.
|
* Copyright (C) 2007 Kicad Developers, see change_log.txt for contributors.
|
||||||
*
|
*
|
||||||
|
@ -24,7 +24,6 @@
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/****************************/
|
/****************************/
|
||||||
/* DRC control */
|
/* DRC control */
|
||||||
/****************************/
|
/****************************/
|
||||||
|
@ -94,7 +93,6 @@ void DRC::DestroyDialog( int aReason )
|
||||||
DRC::DRC( WinEDA_PcbFrame* aPcbWindow )
|
DRC::DRC( WinEDA_PcbFrame* aPcbWindow )
|
||||||
{
|
{
|
||||||
m_mainWindow = aPcbWindow;
|
m_mainWindow = aPcbWindow;
|
||||||
m_drawPanel = aPcbWindow->DrawPanel;
|
|
||||||
m_pcb = aPcbWindow->GetBoard();
|
m_pcb = aPcbWindow->GetBoard();
|
||||||
m_ui = 0;
|
m_ui = 0;
|
||||||
|
|
||||||
|
@ -116,8 +114,6 @@ DRC::DRC( WinEDA_PcbFrame* aPcbWindow )
|
||||||
m_ycliplo = 0;
|
m_ycliplo = 0;
|
||||||
m_xcliphi = 0;
|
m_xcliphi = 0;
|
||||||
m_ycliphi = 0;
|
m_ycliphi = 0;
|
||||||
|
|
||||||
m_drawPanel = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -288,13 +284,11 @@ void DRC::ListUnconnectedPads()
|
||||||
void DRC::updatePointers()
|
void DRC::updatePointers()
|
||||||
{
|
{
|
||||||
// update my pointers, m_mainWindow is the only unchangable one
|
// update my pointers, m_mainWindow is the only unchangable one
|
||||||
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 ) );
|
||||||
|
|
||||||
m_ui->m_UnconnectedListBox->SetList( new DRC_LIST_UNCONNECTED( &m_unconnected ) );
|
m_ui->m_UnconnectedListBox->SetList( new DRC_LIST_UNCONNECTED( &m_unconnected ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -450,8 +444,8 @@ void DRC::testPad2Pad()
|
||||||
{
|
{
|
||||||
D_PAD* pad = sortedPads[i];
|
D_PAD* pad = sortedPads[i];
|
||||||
|
|
||||||
if( pad->m_Rayon > max_size ) // m_Rayon is the radius value of the circle containing the pad
|
if( pad->m_ShapeMaxRadius > max_size ) // m_ShapeMaxRadius is the radius value of the circle containing the pad
|
||||||
max_size = pad->m_Rayon;
|
max_size = pad->m_ShapeMaxRadius;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test the pads
|
// Test the pads
|
||||||
|
@ -462,7 +456,7 @@ void DRC::testPad2Pad()
|
||||||
D_PAD* pad = sortedPads[i];
|
D_PAD* pad = sortedPads[i];
|
||||||
|
|
||||||
int x_limit = max_size + pad->GetClearance() +
|
int x_limit = max_size + pad->GetClearance() +
|
||||||
pad->m_Rayon + pad->GetPosition().x;
|
pad->m_ShapeMaxRadius + pad->GetPosition().x;
|
||||||
|
|
||||||
if( !doPadToPadsDrc( pad, &sortedPads[i], listEnd, x_limit ) )
|
if( !doPadToPadsDrc( pad, &sortedPads[i], listEnd, x_limit ) )
|
||||||
{
|
{
|
||||||
|
@ -558,137 +552,6 @@ void DRC::testZones( bool adoTestFillSegments )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MARKER_PCB* DRC::fillMarker( TRACK* aTrack, BOARD_ITEM* aItem, int aErrorCode, MARKER_PCB* fillMe )
|
|
||||||
{
|
|
||||||
wxString textA = aTrack->MenuText( m_pcb );
|
|
||||||
wxString textB;
|
|
||||||
|
|
||||||
wxPoint position;
|
|
||||||
wxPoint posB;
|
|
||||||
|
|
||||||
if( aItem ) // aItem might be NULL
|
|
||||||
{
|
|
||||||
textB = aItem->MenuText( m_pcb );
|
|
||||||
posB = aItem->GetPosition();
|
|
||||||
|
|
||||||
if( aItem->Type() == TYPE_PAD )
|
|
||||||
position = aItem->GetPosition();
|
|
||||||
|
|
||||||
else if( aItem->Type() == TYPE_VIA )
|
|
||||||
position = aItem->GetPosition();
|
|
||||||
|
|
||||||
else if( aItem->Type() == TYPE_TRACK )
|
|
||||||
{
|
|
||||||
TRACK* track = (TRACK*) aItem;
|
|
||||||
wxPoint endPos = track->m_End;
|
|
||||||
|
|
||||||
// either of aItem's start or end will be used for the marker position
|
|
||||||
// first assume start, then switch at end if needed. decision made on
|
|
||||||
// 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 dToStart = hypot( position.x - aTrack->m_End.x,
|
|
||||||
position.y - aTrack->m_End.y );
|
|
||||||
|
|
||||||
if( dToEnd < dToStart )
|
|
||||||
position = endPos;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
position = aTrack->GetPosition();
|
|
||||||
|
|
||||||
if( fillMe )
|
|
||||||
{
|
|
||||||
if( aItem )
|
|
||||||
fillMe->SetData( aErrorCode, position,
|
|
||||||
textA, aTrack->GetPosition(),
|
|
||||||
textB, posB );
|
|
||||||
else
|
|
||||||
fillMe->SetData( aErrorCode, position,
|
|
||||||
textA, aTrack->GetPosition() );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if( aItem )
|
|
||||||
fillMe = new MARKER_PCB( aErrorCode, position,
|
|
||||||
textA, aTrack->GetPosition(),
|
|
||||||
textB, posB );
|
|
||||||
else
|
|
||||||
fillMe = new MARKER_PCB( aErrorCode, position,
|
|
||||||
textA, aTrack->GetPosition() );
|
|
||||||
}
|
|
||||||
|
|
||||||
return fillMe;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
MARKER_PCB* DRC::fillMarker( D_PAD* aPad, D_PAD* bPad, int aErrorCode, MARKER_PCB* fillMe )
|
|
||||||
{
|
|
||||||
wxString textA = aPad->MenuText( m_pcb );
|
|
||||||
wxString textB = bPad->MenuText( m_pcb );
|
|
||||||
|
|
||||||
wxPoint posA = aPad->GetPosition();
|
|
||||||
wxPoint posB = bPad->GetPosition();
|
|
||||||
|
|
||||||
if( fillMe )
|
|
||||||
fillMe->SetData( aErrorCode, posA, textA, posA, textB, posB );
|
|
||||||
else
|
|
||||||
fillMe = new MARKER_PCB( aErrorCode, posA, textA, posA, textB, posB );
|
|
||||||
|
|
||||||
return fillMe;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
MARKER_PCB* DRC::fillMarker( ZONE_CONTAINER* aArea, int aErrorCode, MARKER_PCB* fillMe )
|
|
||||||
{
|
|
||||||
wxString textA = aArea->MenuText( m_pcb );
|
|
||||||
|
|
||||||
wxPoint posA = aArea->GetPosition();
|
|
||||||
|
|
||||||
if( fillMe )
|
|
||||||
fillMe->SetData( aErrorCode, posA, textA, posA );
|
|
||||||
else
|
|
||||||
fillMe = new MARKER_PCB( aErrorCode, posA, textA, posA );
|
|
||||||
|
|
||||||
return fillMe;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
MARKER_PCB* DRC::fillMarker( const ZONE_CONTAINER* aArea,
|
|
||||||
const wxPoint& aPos,
|
|
||||||
int aErrorCode,
|
|
||||||
MARKER_PCB* fillMe )
|
|
||||||
{
|
|
||||||
wxString textA = aArea->MenuText( m_pcb );
|
|
||||||
|
|
||||||
wxPoint posA = aPos;
|
|
||||||
|
|
||||||
if( fillMe )
|
|
||||||
fillMe->SetData( aErrorCode, posA, textA, posA );
|
|
||||||
else
|
|
||||||
fillMe = new MARKER_PCB( aErrorCode, posA, textA, posA );
|
|
||||||
|
|
||||||
return fillMe;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
MARKER_PCB* DRC::fillMarker( int aErrorCode, const wxString& aMessage, MARKER_PCB* fillMe )
|
|
||||||
{
|
|
||||||
wxPoint posA; // not displayed
|
|
||||||
|
|
||||||
if( fillMe )
|
|
||||||
fillMe->SetData( aErrorCode, posA, aMessage, posA );
|
|
||||||
else
|
|
||||||
fillMe = new MARKER_PCB( aErrorCode, posA, aMessage, posA );
|
|
||||||
|
|
||||||
fillMe->SetShowNoCoordinate();
|
|
||||||
|
|
||||||
return fillMe;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
|
bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
@ -801,11 +664,12 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
|
||||||
/* Phase 1 : test DRC track to pads : */
|
/* Phase 1 : test DRC track to pads : */
|
||||||
/******************************************/
|
/******************************************/
|
||||||
|
|
||||||
D_PAD pseudo_pad( (MODULE*) NULL ); // construct this once outside following loop
|
// Use a dummy pad to test DRC tracks versus holes, for pads not on all copper layers
|
||||||
|
// but having a hole
|
||||||
|
D_PAD dummypad( (MODULE*) NULL ); // construct this once outside following loop
|
||||||
|
dummypad.m_Masque_Layer = ALL_CU_LAYERS; // Ensure the hole is on all layers
|
||||||
|
|
||||||
// Compute the min distance to pads
|
// Compute the min distance to pads
|
||||||
int refsegm_half_width = aRefSeg->m_Width >> 1;
|
|
||||||
|
|
||||||
if( testPads )
|
if( testPads )
|
||||||
{
|
{
|
||||||
for( unsigned ii = 0; ii<m_pcb->GetPadsCount(); ++ii )
|
for( unsigned ii = 0; ii<m_pcb->GetPadsCount(); ++ii )
|
||||||
|
@ -818,22 +682,21 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
|
||||||
*/
|
*/
|
||||||
if( (pad->m_Masque_Layer & layerMask ) == 0 )
|
if( (pad->m_Masque_Layer & layerMask ) == 0 )
|
||||||
{
|
{
|
||||||
/* We must test the pad hole. In order to use the function "checkClearanceSegmToPad",
|
/* We must test the pad hole. In order to use the function checkClearanceSegmToPad(),
|
||||||
* a pseudo pad is used, with a shape and a size like the hole
|
* a pseudo pad is used, with a shape and a size like the hole
|
||||||
*/
|
*/
|
||||||
if( pad->m_Drill.x == 0 )
|
if( pad->m_Drill.x == 0 )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
pseudo_pad.m_Size = pad->m_Drill;
|
dummypad.m_Size = pad->m_Drill;
|
||||||
pseudo_pad.SetPosition( pad->GetPosition() );
|
dummypad.SetPosition( pad->GetPosition() );
|
||||||
pseudo_pad.m_PadShape = pad->m_DrillShape;
|
dummypad.m_PadShape = pad->m_DrillShape;
|
||||||
pseudo_pad.m_Orient = pad->m_Orient;
|
dummypad.m_Orient = pad->m_Orient;
|
||||||
pseudo_pad.ComputeRayon(); // compute the radius
|
dummypad.ComputeShapeMaxRadius(); // compute the radius of the circle containing this pad
|
||||||
|
m_padToTestPos.x = dummypad.GetPosition().x - origin.x;
|
||||||
|
m_padToTestPos.y = dummypad.GetPosition().y - origin.y;
|
||||||
|
|
||||||
m_padToTestPos.x = pseudo_pad.GetPosition().x - origin.x;
|
if( !checkClearanceSegmToPad( &dummypad, aRefSeg->m_Width,
|
||||||
m_padToTestPos.y = pseudo_pad.GetPosition().y - origin.y;
|
|
||||||
|
|
||||||
if( !checkClearanceSegmToPad( &pseudo_pad, refsegm_half_width,
|
|
||||||
netclass->GetClearance() ) )
|
netclass->GetClearance() ) )
|
||||||
{
|
{
|
||||||
m_currentMarker = fillMarker( aRefSeg, pad,
|
m_currentMarker = fillMarker( aRefSeg, pad,
|
||||||
|
@ -855,7 +718,7 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
|
||||||
m_padToTestPos.x = shape_pos.x - origin.x;
|
m_padToTestPos.x = shape_pos.x - origin.x;
|
||||||
m_padToTestPos.y = shape_pos.y - origin.y;
|
m_padToTestPos.y = shape_pos.y - origin.y;
|
||||||
|
|
||||||
if( !checkClearanceSegmToPad( pad, refsegm_half_width, aRefSeg->GetClearance( pad ) ) )
|
if( !checkClearanceSegmToPad( pad, aRefSeg->m_Width, aRefSeg->GetClearance( pad ) ) )
|
||||||
{
|
{
|
||||||
m_currentMarker = fillMarker( aRefSeg, pad,
|
m_currentMarker = fillMarker( aRefSeg, pad,
|
||||||
DRCE_TRACK_NEAR_PAD, m_currentMarker );
|
DRCE_TRACK_NEAR_PAD, m_currentMarker );
|
||||||
|
@ -1120,9 +983,16 @@ bool DRC::doPadToPadsDrc( D_PAD* aRefPad, LISTE_PAD* aStart, LISTE_PAD* aEnd,
|
||||||
{
|
{
|
||||||
int layerMask = aRefPad->m_Masque_Layer & ALL_CU_LAYERS;
|
int layerMask = aRefPad->m_Masque_Layer & ALL_CU_LAYERS;
|
||||||
|
|
||||||
static D_PAD dummypad( (MODULE*) NULL ); // used to test DRC pad to holes: this dummypad is the hole to test
|
// used to test DRC pad to holes: this dummypad is a pad hole to test
|
||||||
|
// pad to pad hole DRC, using pad to pad DRC test.
|
||||||
dummypad.m_Masque_Layer = ALL_CU_LAYERS;
|
// this dummy pad is a circle or an oval.
|
||||||
|
static D_PAD dummypad( (MODULE*) NULL );
|
||||||
|
dummypad.m_Masque_Layer = ALL_CU_LAYERS; // za hole is on all layers
|
||||||
|
dummypad.m_LocalClearance = 1; /* Use the minimal local clerance value for the dummy pad
|
||||||
|
* the clearance of the active pad will be used
|
||||||
|
* as minimum distance to a hole
|
||||||
|
* (a value = 0 means use netclass value)
|
||||||
|
*/
|
||||||
|
|
||||||
for( LISTE_PAD* pad_list = aStart; pad_list<aEnd; ++pad_list )
|
for( LISTE_PAD* pad_list = aStart; pad_list<aEnd; ++pad_list )
|
||||||
{
|
{
|
||||||
|
@ -1159,8 +1029,9 @@ bool DRC::doPadToPadsDrc( D_PAD* aRefPad, LISTE_PAD* aStart, LISTE_PAD* aEnd,
|
||||||
{
|
{
|
||||||
dummypad.SetPosition( pad->GetPosition() );
|
dummypad.SetPosition( pad->GetPosition() );
|
||||||
dummypad.m_Size = pad->m_Drill;
|
dummypad.m_Size = pad->m_Drill;
|
||||||
dummypad.m_PadShape = pad->m_DrillShape == PAD_OVAL ? PAD_OVAL : PAD_CIRCLE;
|
dummypad.m_PadShape = (pad->m_DrillShape == PAD_OVAL) ? PAD_OVAL : PAD_CIRCLE;
|
||||||
dummypad.m_Orient = pad->m_Orient;
|
dummypad.m_Orient = pad->m_Orient;
|
||||||
|
dummypad.ComputeShapeMaxRadius(); // compute the radius of the circle containing this pad
|
||||||
if( !checkClearancePadToPad( aRefPad, &dummypad ) )
|
if( !checkClearancePadToPad( aRefPad, &dummypad ) )
|
||||||
{
|
{
|
||||||
// here we have a drc error on pad!
|
// here we have a drc error on pad!
|
||||||
|
@ -1174,8 +1045,9 @@ bool DRC::doPadToPadsDrc( D_PAD* aRefPad, LISTE_PAD* aStart, LISTE_PAD* aEnd,
|
||||||
{
|
{
|
||||||
dummypad.SetPosition( aRefPad->GetPosition() );
|
dummypad.SetPosition( aRefPad->GetPosition() );
|
||||||
dummypad.m_Size = aRefPad->m_Drill;
|
dummypad.m_Size = aRefPad->m_Drill;
|
||||||
dummypad.m_PadShape = aRefPad->m_DrillShape == PAD_OVAL ? PAD_OVAL : PAD_CIRCLE;
|
dummypad.m_PadShape = (aRefPad->m_DrillShape == PAD_OVAL) ? PAD_OVAL : PAD_CIRCLE;
|
||||||
dummypad.m_Orient = aRefPad->m_Orient;
|
dummypad.m_Orient = aRefPad->m_Orient;
|
||||||
|
dummypad.ComputeShapeMaxRadius(); // compute the radius of the circle containing this pad
|
||||||
if( !checkClearancePadToPad( pad, &dummypad ) )
|
if( !checkClearancePadToPad( pad, &dummypad ) )
|
||||||
{
|
{
|
||||||
// here we have a drc erroron aRefPad!
|
// here we have a drc erroron aRefPad!
|
||||||
|
@ -1187,6 +1059,7 @@ bool DRC::doPadToPadsDrc( D_PAD* aRefPad, LISTE_PAD* aStart, LISTE_PAD* aEnd,
|
||||||
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() ) )
|
||||||
|
@ -1229,28 +1102,29 @@ wxPoint rotate( wxPoint p, int angle )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* test DRC between 2 pads.
|
||||||
|
* this function can be also used to test DRC between a pas and a hole,
|
||||||
|
* because a hole is like a round pad.
|
||||||
|
*/
|
||||||
bool DRC::checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad )
|
bool DRC::checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad )
|
||||||
{
|
{
|
||||||
wxPoint rel_pos;
|
int dist;
|
||||||
int dist;;
|
|
||||||
|
|
||||||
wxPoint shape_pos;
|
|
||||||
int pad_angle;
|
int pad_angle;
|
||||||
|
|
||||||
|
// Get the clerance between the 2 pads. this is the min distance between aRefPad and aPad
|
||||||
int dist_min = aRefPad->GetClearance( aPad );
|
int dist_min = aRefPad->GetClearance( aPad );
|
||||||
|
|
||||||
rel_pos = aPad->ReturnShapePos();
|
// relativePadPos is the aPad shape position relative to the aRefPad shape position
|
||||||
shape_pos = aRefPad->ReturnShapePos();
|
wxPoint relativePadPos = aPad->ReturnShapePos() - aRefPad->ReturnShapePos();
|
||||||
|
|
||||||
// rel_pos is the aPad position relative to the aRefPad position
|
dist = (int) hypot( relativePadPos.x, relativePadPos.y );
|
||||||
rel_pos -= shape_pos;
|
|
||||||
|
|
||||||
dist = (int) hypot( rel_pos.x, rel_pos.y );
|
|
||||||
|
|
||||||
|
// return true if clearance between aRefPad and aPad is >= dist_min, else false
|
||||||
bool diag = true;
|
bool diag = true;
|
||||||
|
|
||||||
// Quick test: Clearance is OK if the bounding circles are further away than "dist_min"
|
// Quick test: Clearance is OK if the bounding circles are further away than "dist_min"
|
||||||
if( (dist - aRefPad->m_Rayon - aPad->m_Rayon) >= dist_min )
|
if( (dist - aRefPad->m_ShapeMaxRadius - aPad->m_ShapeMaxRadius) >= dist_min )
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
/* Here, pads are near and DRC depend on the pad shapes
|
/* Here, pads are near and DRC depend on the pad shapes
|
||||||
|
@ -1268,7 +1142,7 @@ bool DRC::checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad )
|
||||||
if( swap_pads )
|
if( swap_pads )
|
||||||
{
|
{
|
||||||
EXCHG( aRefPad, aPad );
|
EXCHG( aRefPad, aPad );
|
||||||
rel_pos = -rel_pos;
|
relativePadPos = -relativePadPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Because pad exchange, aRefPad shape is PAD_CIRCLE or PAD_OVAL,
|
/* Because pad exchange, aRefPad shape is PAD_CIRCLE or PAD_OVAL,
|
||||||
|
@ -1278,20 +1152,22 @@ bool DRC::checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad )
|
||||||
*/
|
*/
|
||||||
switch( aRefPad->m_PadShape )
|
switch( aRefPad->m_PadShape )
|
||||||
{
|
{
|
||||||
case PAD_CIRCLE: // aRefPad is like a track segment with a null lenght
|
case PAD_CIRCLE:
|
||||||
|
/* One can use checkClearanceSegmToPad to test clearance
|
||||||
|
* aRefPad is like a track segment with a null lenght and a witdth = m_Size.x
|
||||||
|
*/
|
||||||
m_segmLength = 0;
|
m_segmLength = 0;
|
||||||
m_segmAngle = 0;
|
m_segmAngle = 0;
|
||||||
|
|
||||||
m_segmEnd.x = m_segmEnd.y = 0;
|
m_segmEnd.x = m_segmEnd.y = 0;
|
||||||
|
|
||||||
m_padToTestPos.x = rel_pos.x;
|
m_padToTestPos.x = relativePadPos.x;
|
||||||
m_padToTestPos.y = rel_pos.y;
|
m_padToTestPos.y = relativePadPos.y;
|
||||||
|
diag = checkClearanceSegmToPad( aPad, aRefPad->m_Size.x, dist_min );
|
||||||
diag = checkClearanceSegmToPad( aPad, aRefPad->m_Rayon, dist_min );
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PAD_RECT:
|
case PAD_RECT:
|
||||||
RotatePoint( &rel_pos, aRefPad->m_Orient );
|
RotatePoint( &relativePadPos, aRefPad->m_Orient );
|
||||||
|
|
||||||
// pad_angle = pad orient relative to the aRefPad orient
|
// pad_angle = pad orient relative to the aRefPad orient
|
||||||
pad_angle = aRefPad->m_Orient + aPad->m_Orient;
|
pad_angle = aRefPad->m_Orient + aPad->m_Orient;
|
||||||
|
@ -1315,13 +1191,13 @@ bool DRC::checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad )
|
||||||
// Test DRC:
|
// Test DRC:
|
||||||
diag = false;
|
diag = false;
|
||||||
|
|
||||||
rel_pos.x = ABS( rel_pos.x );
|
relativePadPos.x = ABS( relativePadPos.x );
|
||||||
rel_pos.y = ABS( rel_pos.y );
|
relativePadPos.y = ABS( relativePadPos.y );
|
||||||
|
|
||||||
if( ( rel_pos.x - ( (size.x + aRefPad->m_Size.x) / 2 ) ) >= dist_min )
|
if( ( relativePadPos.x - ( (size.x + aRefPad->m_Size.x) / 2 ) ) >= dist_min )
|
||||||
diag = true;
|
diag = true;
|
||||||
|
|
||||||
if( ( rel_pos.y - ( (size.y + aRefPad->m_Size.y) / 2 ) ) >= dist_min )
|
if( ( relativePadPos.y - ( (size.y + aRefPad->m_Size.y) / 2 ) ) >= dist_min )
|
||||||
diag = true;
|
diag = true;
|
||||||
}
|
}
|
||||||
else // al least on pad has any other orient. Test is more tricky
|
else // al least on pad has any other orient. Test is more tricky
|
||||||
|
@ -1420,7 +1296,7 @@ bool DRC::checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad )
|
||||||
m_segmAngle += 900;
|
m_segmAngle += 900;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* the start point must be 0,0 and currently rel_pos
|
/* the start point must be 0,0 and currently relativePadPos
|
||||||
* is relative the center of pad coordinate */
|
* is relative the center of pad coordinate */
|
||||||
wxPoint segstart;
|
wxPoint segstart;
|
||||||
segstart.x = -m_segmLength / 2; // Start point coordinate of the horizontal equivalent segment
|
segstart.x = -m_segmLength / 2; // Start point coordinate of the horizontal equivalent segment
|
||||||
|
@ -1428,11 +1304,12 @@ bool DRC::checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad )
|
||||||
RotatePoint( &segstart, m_segmAngle ); // True start point coordinate of the equivalent segment
|
RotatePoint( &segstart, m_segmAngle ); // True start point coordinate of the equivalent segment
|
||||||
|
|
||||||
// move pad position relative to the segment origin
|
// move pad position relative to the segment origin
|
||||||
m_padToTestPos = rel_pos - segstart;
|
m_padToTestPos = relativePadPos - segstart;
|
||||||
|
|
||||||
// Calculate segment end
|
// Calculate segment end
|
||||||
m_segmEnd.x = -2 * segstart.x;
|
m_segmEnd.x = -2 * segstart.x;
|
||||||
m_segmEnd.y = -2 * segstart.y; // end of segment coordinate
|
m_segmEnd.y = -2 * segstart.y; // end of segment coordinate
|
||||||
diag = checkClearanceSegmToPad( aPad, segm_width / 2, dist_min );
|
diag = checkClearanceSegmToPad( aPad, segm_width, dist_min );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1448,7 +1325,11 @@ exit: // the only way out (hopefully) for simpler debugging
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool DRC::checkClearanceSegmToPad( const D_PAD* pad_to_test, int w_segm, int aMinDist )
|
/* test if distance between a segment is > aMinDist
|
||||||
|
* segment start point is assumed in (0,0) and segment start point in m_segmEnd
|
||||||
|
* and have aSegmentWidth.
|
||||||
|
*/
|
||||||
|
bool DRC::checkClearanceSegmToPad( const D_PAD* aPad, int aSegmentWidth, int aMinDist )
|
||||||
{
|
{
|
||||||
wxSize padHalfsize; // half the dimension of the pad
|
wxSize padHalfsize; // half the dimension of the pad
|
||||||
int orient;
|
int orient;
|
||||||
|
@ -1456,20 +1337,27 @@ bool DRC::checkClearanceSegmToPad( const D_PAD* pad_to_test, int w_segm, int aMi
|
||||||
int seuil;
|
int seuil;
|
||||||
int deltay;
|
int deltay;
|
||||||
|
|
||||||
seuil = w_segm + aMinDist;
|
int segmHalfWidth = aSegmentWidth / 2;
|
||||||
padHalfsize.x = pad_to_test->m_Size.x >> 1;
|
seuil = segmHalfWidth + aMinDist;
|
||||||
padHalfsize.y = pad_to_test->m_Size.y >> 1;
|
padHalfsize.x = aPad->m_Size.x >> 1;
|
||||||
|
padHalfsize.y = aPad->m_Size.y >> 1;
|
||||||
|
|
||||||
if( pad_to_test->m_PadShape == PAD_CIRCLE )
|
if( aPad->m_PadShape == PAD_CIRCLE )
|
||||||
{
|
{
|
||||||
/* calcul des coord centre du pad dans le repere axe X confondu
|
/* Easy case: just test the distance between segment and pad centre
|
||||||
* avec le segment en tst */
|
* calculate pad coordinates in the X,Y axis with X axis = segment to test
|
||||||
|
*/
|
||||||
RotatePoint( &m_padToTestPos.x, &m_padToTestPos.y, m_segmAngle );
|
RotatePoint( &m_padToTestPos.x, &m_padToTestPos.y, m_segmAngle );
|
||||||
return checkMarginToCircle( m_padToTestPos.x, m_padToTestPos.y, seuil + padHalfsize.x, m_segmLength );
|
return checkMarginToCircle( m_padToTestPos.x, m_padToTestPos.y,
|
||||||
|
seuil + padHalfsize.x, m_segmLength );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* calcul de la "surface de securite" du pad de reference */
|
/* calculate the bounding box of the pad, including the clearance and the segment width
|
||||||
|
* if the line from 0 to m_segmEnd does not intersect this bounding box,
|
||||||
|
* the clearance is always OK
|
||||||
|
* But if intersect, a better analysis of the pad shape must be done.
|
||||||
|
*/
|
||||||
m_xcliplo = m_padToTestPos.x - seuil - padHalfsize.x;
|
m_xcliplo = m_padToTestPos.x - seuil - padHalfsize.x;
|
||||||
m_ycliplo = m_padToTestPos.y - seuil - padHalfsize.y;
|
m_ycliplo = m_padToTestPos.y - seuil - padHalfsize.y;
|
||||||
m_xcliphi = m_padToTestPos.x + seuil + padHalfsize.x;
|
m_xcliphi = m_padToTestPos.x + seuil + padHalfsize.x;
|
||||||
|
@ -1480,7 +1368,7 @@ bool DRC::checkClearanceSegmToPad( const D_PAD* pad_to_test, int w_segm, int aMi
|
||||||
xf = m_segmEnd.x;
|
xf = m_segmEnd.x;
|
||||||
yf = m_segmEnd.y;
|
yf = m_segmEnd.y;
|
||||||
|
|
||||||
orient = pad_to_test->m_Orient;
|
orient = aPad->m_Orient;
|
||||||
|
|
||||||
RotatePoint( &x0, &y0, m_padToTestPos.x, m_padToTestPos.y, -orient );
|
RotatePoint( &x0, &y0, m_padToTestPos.x, m_padToTestPos.y, -orient );
|
||||||
RotatePoint( &xf, &yf, m_padToTestPos.x, m_padToTestPos.y, -orient );
|
RotatePoint( &xf, &yf, m_padToTestPos.x, m_padToTestPos.y, -orient );
|
||||||
|
@ -1488,15 +1376,19 @@ bool DRC::checkClearanceSegmToPad( const D_PAD* pad_to_test, int w_segm, int aMi
|
||||||
if( checkLine( x0, y0, xf, yf ) )
|
if( checkLine( x0, y0, xf, yf ) )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
/* Erreur DRC : analyse fine de la forme de la pastille */
|
/* segment intersects the bounding box. But there is not always a DRC error.
|
||||||
|
* A fine analysis of the pad shape must be done.
|
||||||
switch( pad_to_test->m_PadShape )
|
*/
|
||||||
|
switch( aPad->m_PadShape )
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
case PAD_OVAL:
|
case PAD_OVAL:
|
||||||
/* test de la pastille ovale ramenee au type ovale vertical */
|
/* an oval is a complex shape, but is a rectangle and 2 circles
|
||||||
|
* these 3 basic shapes are more easy to test.
|
||||||
|
*/
|
||||||
|
/* We use a vertical oval shape. for horizontal ovals, swap x and y size and rotate the shape*/
|
||||||
if( padHalfsize.x > padHalfsize.y )
|
if( padHalfsize.x > padHalfsize.y )
|
||||||
{
|
{
|
||||||
EXCHG( padHalfsize.x, padHalfsize.y );
|
EXCHG( padHalfsize.x, padHalfsize.y );
|
||||||
|
@ -1506,28 +1398,30 @@ bool DRC::checkClearanceSegmToPad( const D_PAD* pad_to_test, int w_segm, int aMi
|
||||||
}
|
}
|
||||||
deltay = padHalfsize.y - padHalfsize.x;
|
deltay = padHalfsize.y - padHalfsize.x;
|
||||||
|
|
||||||
/* ici: padHalfsize.x = rayon,
|
// ici: padHalfsize.x = rayon, delta = dist centre cercles a centre pad
|
||||||
* delta = dist centre cercles a centre pad */
|
|
||||||
|
|
||||||
/* Test du rectangle separant les 2 demi cercles */
|
// Test the rectangle area between the two circles
|
||||||
m_xcliplo = m_padToTestPos.x - seuil - padHalfsize.x;
|
m_xcliplo = m_padToTestPos.x - seuil - padHalfsize.x;
|
||||||
m_ycliplo = m_padToTestPos.y - w_segm - deltay;
|
m_ycliplo = m_padToTestPos.y - segmHalfWidth - deltay;
|
||||||
m_xcliphi = m_padToTestPos.x + seuil + padHalfsize.x;
|
m_xcliphi = m_padToTestPos.x + seuil + padHalfsize.x;
|
||||||
m_ycliphi = m_padToTestPos.y + w_segm + deltay;
|
m_ycliphi = m_padToTestPos.y + segmHalfWidth + deltay;
|
||||||
|
|
||||||
if( !checkLine( x0, y0, xf, yf ) )
|
if( !checkLine( x0, y0, xf, yf ) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* test des 2 cercles */
|
// test the first circle
|
||||||
x0 = m_padToTestPos.x; /* x0,y0 = centre du cercle superieur du pad ovale */
|
x0 = m_padToTestPos.x; // x0,y0 = centre of the upper circle of the oval shape
|
||||||
y0 = m_padToTestPos.y + deltay;
|
y0 = m_padToTestPos.y + deltay;
|
||||||
RotatePoint( &x0, &y0, m_padToTestPos.x, m_padToTestPos.y, orient );
|
|
||||||
RotatePoint( &x0, &y0, m_segmAngle );
|
|
||||||
|
|
||||||
|
// Calculate the actual position of the circle, given the pad orientation:
|
||||||
|
RotatePoint( &x0, &y0, m_padToTestPos.x, m_padToTestPos.y, orient );
|
||||||
|
|
||||||
|
// Calculate the actual position of the circle in the new X,Y axis:
|
||||||
|
RotatePoint( &x0, &y0, m_segmAngle );
|
||||||
if( !checkMarginToCircle( x0, y0, padHalfsize.x + seuil, m_segmLength ) )
|
if( !checkMarginToCircle( x0, y0, padHalfsize.x + seuil, m_segmLength ) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
x0 = m_padToTestPos.x; /* x0,y0 = centre du cercle inferieur du pad ovale */
|
// test the second circle
|
||||||
|
x0 = m_padToTestPos.x; // x0,y0 = centre of the lower circle of the oval shape
|
||||||
y0 = m_padToTestPos.y - deltay;
|
y0 = m_padToTestPos.y - deltay;
|
||||||
RotatePoint( &x0, &y0, m_padToTestPos.x, m_padToTestPos.y, orient );
|
RotatePoint( &x0, &y0, m_padToTestPos.x, m_padToTestPos.y, orient );
|
||||||
RotatePoint( &x0, &y0, m_segmAngle );
|
RotatePoint( &x0, &y0, m_segmAngle );
|
||||||
|
|
|
@ -0,0 +1,172 @@
|
||||||
|
/*
|
||||||
|
* drc_marker_functions.cpp
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 Dick Hollenbeck, dick@softplc.com
|
||||||
|
* Copyright (C) 2004-2010 Jean-Pierre Charras, jean-pierre.charras@gipsa-lab.inpg.fr
|
||||||
|
* Copyright (C) 2007 Kicad Developers, see change_log.txt for contributors.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, you may find one here:
|
||||||
|
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||||
|
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||||
|
* or you may write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* Methods of class DRC to initialize drc markers with messages
|
||||||
|
* according to items and error ode
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "fctsys.h"
|
||||||
|
#include "common.h"
|
||||||
|
//#include "class_drawpanel.h"
|
||||||
|
#include "pcbnew.h"
|
||||||
|
//#include "wxPcbStruct.h"
|
||||||
|
#include "class_board_design_settings.h"
|
||||||
|
|
||||||
|
#include "drc_stuff.h"
|
||||||
|
|
||||||
|
MARKER_PCB* DRC::fillMarker( TRACK* aTrack, BOARD_ITEM* aItem, int aErrorCode, MARKER_PCB* fillMe )
|
||||||
|
{
|
||||||
|
wxString textA = aTrack->MenuText( m_pcb );
|
||||||
|
wxString textB;
|
||||||
|
|
||||||
|
wxPoint position;
|
||||||
|
wxPoint posB;
|
||||||
|
|
||||||
|
if( aItem ) // aItem might be NULL
|
||||||
|
{
|
||||||
|
textB = aItem->MenuText( m_pcb );
|
||||||
|
posB = aItem->GetPosition();
|
||||||
|
|
||||||
|
if( aItem->Type() == TYPE_PAD )
|
||||||
|
position = aItem->GetPosition();
|
||||||
|
|
||||||
|
else if( aItem->Type() == TYPE_VIA )
|
||||||
|
position = aItem->GetPosition();
|
||||||
|
|
||||||
|
else if( aItem->Type() == TYPE_TRACK )
|
||||||
|
{
|
||||||
|
TRACK* track = (TRACK*) aItem;
|
||||||
|
wxPoint endPos = track->m_End;
|
||||||
|
|
||||||
|
// either of aItem's start or end will be used for the marker position
|
||||||
|
// first assume start, then switch at end if needed. decision made on
|
||||||
|
// 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 dToStart = hypot( position.x - aTrack->m_End.x,
|
||||||
|
position.y - aTrack->m_End.y );
|
||||||
|
|
||||||
|
if( dToEnd < dToStart )
|
||||||
|
position = endPos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
position = aTrack->GetPosition();
|
||||||
|
|
||||||
|
if( fillMe )
|
||||||
|
{
|
||||||
|
if( aItem )
|
||||||
|
fillMe->SetData( aErrorCode, position,
|
||||||
|
textA, aTrack->GetPosition(),
|
||||||
|
textB, posB );
|
||||||
|
else
|
||||||
|
fillMe->SetData( aErrorCode, position,
|
||||||
|
textA, aTrack->GetPosition() );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( aItem )
|
||||||
|
fillMe = new MARKER_PCB( aErrorCode, position,
|
||||||
|
textA, aTrack->GetPosition(),
|
||||||
|
textB, posB );
|
||||||
|
else
|
||||||
|
fillMe = new MARKER_PCB( aErrorCode, position,
|
||||||
|
textA, aTrack->GetPosition() );
|
||||||
|
}
|
||||||
|
|
||||||
|
return fillMe;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MARKER_PCB* DRC::fillMarker( D_PAD* aPad, D_PAD* bPad, int aErrorCode, MARKER_PCB* fillMe )
|
||||||
|
{
|
||||||
|
wxString textA = aPad->MenuText( m_pcb );
|
||||||
|
wxString textB = bPad->MenuText( m_pcb );
|
||||||
|
|
||||||
|
wxPoint posA = aPad->GetPosition();
|
||||||
|
wxPoint posB = bPad->GetPosition();
|
||||||
|
|
||||||
|
if( fillMe )
|
||||||
|
fillMe->SetData( aErrorCode, posA, textA, posA, textB, posB );
|
||||||
|
else
|
||||||
|
fillMe = new MARKER_PCB( aErrorCode, posA, textA, posA, textB, posB );
|
||||||
|
|
||||||
|
return fillMe;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MARKER_PCB* DRC::fillMarker( ZONE_CONTAINER* aArea, int aErrorCode, MARKER_PCB* fillMe )
|
||||||
|
{
|
||||||
|
wxString textA = aArea->MenuText( m_pcb );
|
||||||
|
|
||||||
|
wxPoint posA = aArea->GetPosition();
|
||||||
|
|
||||||
|
if( fillMe )
|
||||||
|
fillMe->SetData( aErrorCode, posA, textA, posA );
|
||||||
|
else
|
||||||
|
fillMe = new MARKER_PCB( aErrorCode, posA, textA, posA );
|
||||||
|
|
||||||
|
return fillMe;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MARKER_PCB* DRC::fillMarker( const ZONE_CONTAINER* aArea,
|
||||||
|
const wxPoint& aPos,
|
||||||
|
int aErrorCode,
|
||||||
|
MARKER_PCB* fillMe )
|
||||||
|
{
|
||||||
|
wxString textA = aArea->MenuText( m_pcb );
|
||||||
|
|
||||||
|
wxPoint posA = aPos;
|
||||||
|
|
||||||
|
if( fillMe )
|
||||||
|
fillMe->SetData( aErrorCode, posA, textA, posA );
|
||||||
|
else
|
||||||
|
fillMe = new MARKER_PCB( aErrorCode, posA, textA, posA );
|
||||||
|
|
||||||
|
return fillMe;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MARKER_PCB* DRC::fillMarker( int aErrorCode, const wxString& aMessage, MARKER_PCB* fillMe )
|
||||||
|
{
|
||||||
|
wxPoint posA; // not displayed
|
||||||
|
|
||||||
|
if( fillMe )
|
||||||
|
fillMe->SetData( aErrorCode, posA, aMessage, posA );
|
||||||
|
else
|
||||||
|
fillMe = new MARKER_PCB( aErrorCode, posA, aMessage, posA );
|
||||||
|
|
||||||
|
fillMe->SetShowNoCoordinate();
|
||||||
|
|
||||||
|
return fillMe;
|
||||||
|
}
|
||||||
|
|
|
@ -179,7 +179,6 @@ private:
|
||||||
int m_ycliphi;
|
int m_ycliphi;
|
||||||
|
|
||||||
WinEDA_PcbFrame* m_mainWindow;
|
WinEDA_PcbFrame* m_mainWindow;
|
||||||
WinEDA_DrawPanel* m_drawPanel;
|
|
||||||
BOARD* m_pcb;
|
BOARD* m_pcb;
|
||||||
DIALOG_DRC_CONTROL* m_ui;
|
DIALOG_DRC_CONTROL* m_ui;
|
||||||
|
|
||||||
|
@ -306,7 +305,7 @@ private:
|
||||||
* Function checkClearancePadToPad
|
* Function checkClearancePadToPad
|
||||||
* @param aRefPad The reference pad to check
|
* @param aRefPad The reference pad to check
|
||||||
* @param aPad Another pad to check against
|
* @param aPad Another pad to check against
|
||||||
* @return bool - true if clearance between aRefPad and pad is >= dist_min, else false
|
* @return bool - true if clearance between aRefPad and aPad is >= dist_min, else false
|
||||||
*/
|
*/
|
||||||
bool checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad );
|
bool checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad );
|
||||||
|
|
||||||
|
@ -315,18 +314,18 @@ private:
|
||||||
* Function checkClearanceSegmToPad
|
* Function checkClearanceSegmToPad
|
||||||
* check the distance from a pad to segment. This function uses several
|
* check the distance from a pad to segment. This function uses several
|
||||||
* instance variable not passed in:
|
* instance variable not passed in:
|
||||||
* segmLength = length of the segment being tested
|
* m_segmLength = length of the segment being tested
|
||||||
* segmAngle = angle d'inclinaison du segment;
|
* m_segmAngle = angle of the segment with the X axis;
|
||||||
* finx, finy = end coordinate of the segment
|
* m_segmEnd = end coordinate of the segment
|
||||||
* spot_cX, spot_cY = position of pad / origin of segment
|
* m_padToTestPos = position of pad relative to the origin of segment
|
||||||
* @param pad_to_test Is the pad involved in the check
|
* @param aPad Is the pad involved in the check
|
||||||
* @param w_segm Hhalf width of the segment to test
|
* @param aSegmentWidth width of the segment to test
|
||||||
* @param dist_min Is the minimum clearance needed
|
* @param aMinDist Is the minimum clearance needed
|
||||||
*
|
*
|
||||||
* @return false distance >= dist_min,
|
* @return true distance >= dist_min,
|
||||||
* true if distance < dist_min
|
* false if distance < dist_min
|
||||||
*/
|
*/
|
||||||
bool checkClearanceSegmToPad( const D_PAD* pad_to_test, int w_segm, int dist_min );
|
bool checkClearanceSegmToPad( const D_PAD* aPad, int aSegmentWidth, int aMinDist );
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -4,17 +4,10 @@
|
||||||
|
|
||||||
#include "fctsys.h"
|
#include "fctsys.h"
|
||||||
|
|
||||||
//#include "gr_basic.h"
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "class_drawpanel.h"
|
#include "class_drawpanel.h"
|
||||||
#include "confirm.h"
|
#include "confirm.h"
|
||||||
#include "pcbnew.h"
|
#include "pcbnew.h"
|
||||||
|
|
||||||
//#include "trigo.h"
|
|
||||||
|
|
||||||
//#include "drag.h"
|
|
||||||
|
|
||||||
//#include "protos.h"
|
|
||||||
#include "dialog_global_pads_edition_base.h"
|
#include "dialog_global_pads_edition_base.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -104,6 +97,8 @@ void DIALOG_GLOBAL_PADS_EDITION::PadPropertiesAccept( wxCommandEvent& event )
|
||||||
EndModal( returncode );
|
EndModal( returncode );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_Parent->OnModify();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -272,7 +267,7 @@ void WinEDA_BasePcbFrame::Global_Import_Pad_Settings( D_PAD* aPad, bool aDraw )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
pt_pad->ComputeRayon();
|
pt_pad->ComputeShapeMaxRadius();
|
||||||
}
|
}
|
||||||
|
|
||||||
Module->Set_Rectangle_Encadrement();
|
Module->Set_Rectangle_Encadrement();
|
||||||
|
|
|
@ -110,7 +110,7 @@ void WinEDA_BasePcbFrame::Export_Pad_Settings( D_PAD* pt_pad )
|
||||||
( (MODULE*) pt_pad->GetParent() )->m_Orient;
|
( (MODULE*) pt_pad->GetParent() )->m_Orient;
|
||||||
g_Pad_Master.m_Size = pt_pad->m_Size;
|
g_Pad_Master.m_Size = pt_pad->m_Size;
|
||||||
g_Pad_Master.m_DeltaSize = pt_pad->m_DeltaSize;
|
g_Pad_Master.m_DeltaSize = pt_pad->m_DeltaSize;
|
||||||
pt_pad->ComputeRayon();
|
pt_pad->ComputeShapeMaxRadius();
|
||||||
|
|
||||||
g_Pad_Master.m_Offset = pt_pad->m_Offset;
|
g_Pad_Master.m_Offset = pt_pad->m_Offset;
|
||||||
g_Pad_Master.m_Drill = pt_pad->m_Drill;
|
g_Pad_Master.m_Drill = pt_pad->m_Drill;
|
||||||
|
@ -163,7 +163,7 @@ void WinEDA_BasePcbFrame::Import_Pad_Settings( D_PAD* aPad, bool aDraw )
|
||||||
aPad->m_Offset.y = 0;
|
aPad->m_Offset.y = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
aPad->ComputeRayon();
|
aPad->ComputeShapeMaxRadius();
|
||||||
|
|
||||||
if( aDraw )
|
if( aDraw )
|
||||||
DrawPanel->PostDirtyRect( aPad->GetBoundingBox() );
|
DrawPanel->PostDirtyRect( aPad->GetBoundingBox() );
|
||||||
|
|
|
@ -265,7 +265,7 @@ MODULE* WinEDA_PcbFrame::Genere_Self( wxDC* DC )
|
||||||
PtPad->m_Masque_Layer = g_TabOneLayerMask[Module->GetLayer()];
|
PtPad->m_Masque_Layer = g_TabOneLayerMask[Module->GetLayer()];
|
||||||
PtPad->m_Attribut = PAD_SMD;
|
PtPad->m_Attribut = PAD_SMD;
|
||||||
PtPad->m_PadShape = PAD_CIRCLE;
|
PtPad->m_PadShape = PAD_CIRCLE;
|
||||||
PtPad->m_Rayon = PtPad->m_Size.x / 2;
|
PtPad->ComputeShapeMaxRadius();
|
||||||
|
|
||||||
D_PAD* newpad = new D_PAD( Module );
|
D_PAD* newpad = new D_PAD( Module );
|
||||||
newpad->Copy( PtPad );
|
newpad->Copy( PtPad );
|
||||||
|
|
Loading…
Reference in New Issue