Commit 809aacb4 authored by jean-pierre charras's avatar jean-pierre charras

drc code cleaning

parent e149951b
...@@ -55,13 +55,13 @@ void DRC::ShowDialog() ...@@ -55,13 +55,13 @@ void DRC::ShowDialog()
PutValueInLocalUnits( *m_ui->m_SetTrackMinWidthCtrl, PutValueInLocalUnits( *m_ui->m_SetTrackMinWidthCtrl,
m_pcb->GetBoardDesignSettings()->m_TrackMinWidth, m_pcb->GetBoardDesignSettings()->m_TrackMinWidth,
m_mainWindow->m_InternalUnits );; m_mainWindow->m_InternalUnits );
PutValueInLocalUnits( *m_ui->m_SetViaMinSizeCtrl, PutValueInLocalUnits( *m_ui->m_SetViaMinSizeCtrl,
m_pcb->GetBoardDesignSettings()->m_ViasMinSize, m_pcb->GetBoardDesignSettings()->m_ViasMinSize,
m_mainWindow->m_InternalUnits );; m_mainWindow->m_InternalUnits );
PutValueInLocalUnits( *m_ui->m_SetMicroViakMinSizeCtrl, PutValueInLocalUnits( *m_ui->m_SetMicroViakMinSizeCtrl,
m_pcb->GetBoardDesignSettings()->m_MicroViasMinSize, m_pcb->GetBoardDesignSettings()->m_MicroViasMinSize,
m_mainWindow->m_InternalUnits );; m_mainWindow->m_InternalUnits );
m_ui->m_CreateRptCtrl->SetValue( m_doCreateRptFile ); m_ui->m_CreateRptCtrl->SetValue( m_doCreateRptFile );
m_ui->m_RptFilenameCtrl->SetValue( m_rptFilename ); m_ui->m_RptFilenameCtrl->SetValue( m_rptFilename );
...@@ -557,7 +557,7 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) ...@@ -557,7 +557,7 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
/***********************************************************************/ /***********************************************************************/
{ {
TRACK* track; TRACK* track;
int dx, dy; // utilise pour calcul des dim x et dim y des segments wxPoint delta; // lenght on X and Y axis of segments
int layerMask; int layerMask;
int net_code_ref; int net_code_ref;
wxPoint shape_pos; wxPoint shape_pos;
...@@ -569,8 +569,7 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) ...@@ -569,8 +569,7 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
*/ */
wxPoint origin = aRefSeg->m_Start; // origin will be the origin of other coordinates wxPoint origin = aRefSeg->m_Start; // origin will be the origin of other coordinates
m_segmEnd.x = dx = aRefSeg->m_End.x - origin.x; m_segmEnd = delta = aRefSeg->m_End - origin;
m_segmEnd.y = dy = aRefSeg->m_End.y - origin.y;
layerMask = aRefSeg->ReturnMaskLayer(); layerMask = aRefSeg->ReturnMaskLayer();
net_code_ref = aRefSeg->GetNet(); net_code_ref = aRefSeg->GetNet();
...@@ -612,7 +611,7 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) ...@@ -612,7 +611,7 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
// For microvias: test if they are blind vias 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;
...@@ -648,17 +647,17 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) ...@@ -648,17 +647,17 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
// for a non horizontal or vertical segment Compute the segment angle // for a non horizontal or vertical segment Compute the segment angle
// in tenths of degrees and its length // in tenths of degrees and its length
if( dx || dy ) if( delta.x || delta.y )
{ {
// Compute the segment angle in 0,1 degrees // Compute the segment angle in 0,1 degrees
m_segmAngle = ArcTangente( dy, dx ); m_segmAngle = ArcTangente( delta.y, delta.x );
// Compute the segment length: we build an equivalent rotated segment, // Compute the segment length: we build an equivalent rotated segment,
// this segment is horizontal, therefore dx = length // this segment is horizontal, therefore dx = length
RotatePoint( &dx, &dy, m_segmAngle ); // dx = length, dy = 0 RotatePoint( &delta, m_segmAngle ); // delta.x = length, delta.y = 0
} }
m_segmLength = dx; m_segmLength = delta.x;
/******************************************/ /******************************************/
/* Phase 1 : test DRC track to pads : */ /* Phase 1 : test DRC track to pads : */
...@@ -693,8 +692,7 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) ...@@ -693,8 +692,7 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
dummypad.m_PadShape = pad->m_DrillShape; dummypad.m_PadShape = pad->m_DrillShape;
dummypad.m_Orient = pad->m_Orient; dummypad.m_Orient = pad->m_Orient;
dummypad.ComputeShapeMaxRadius(); // compute the radius of the circle containing this pad dummypad.ComputeShapeMaxRadius(); // compute the radius of the circle containing this pad
m_padToTestPos.x = dummypad.GetPosition().x - origin.x; m_padToTestPos = dummypad.GetPosition() - origin;
m_padToTestPos.y = dummypad.GetPosition().y - origin.y;
if( !checkClearanceSegmToPad( &dummypad, aRefSeg->m_Width, if( !checkClearanceSegmToPad( &dummypad, aRefSeg->m_Width,
netclass->GetClearance() ) ) netclass->GetClearance() ) )
...@@ -715,8 +713,7 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) ...@@ -715,8 +713,7 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
// DRC for the pad // DRC for the pad
shape_pos = pad->ReturnShapePos(); shape_pos = pad->ReturnShapePos();
m_padToTestPos.x = shape_pos.x - origin.x; m_padToTestPos = shape_pos - origin;
m_padToTestPos.y = shape_pos.y - origin.y;
if( !checkClearanceSegmToPad( pad, aRefSeg->m_Width, aRefSeg->GetClearance( pad ) ) ) if( !checkClearanceSegmToPad( pad, aRefSeg->m_Width, aRefSeg->GetClearance( pad ) ) )
{ {
...@@ -737,10 +734,8 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) ...@@ -737,10 +734,8 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
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; wxPoint segStartPoint;
int y0; wxPoint segEndPoint;
int xf;
int yf;
// No problem if segments have the same net code: // No problem if segments have the same net code:
if( net_code_ref == track->GetNet() ) if( net_code_ref == track->GetNet() )
...@@ -760,16 +755,13 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) ...@@ -760,16 +755,13 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
{ {
int angle = 0; // angle du segment a tester; int angle = 0; // angle du segment a tester;
dx = track->m_End.x - track->m_Start.x; delta = track->m_End - track->m_Start;
dy = track->m_End.y - track->m_Start.y; segStartPoint = aRefSeg->m_Start - track->m_Start;
x0 = aRefSeg->m_Start.x - track->m_Start.x;
y0 = aRefSeg->m_Start.y - track->m_Start.y;
if( track->Type() == TYPE_VIA ) if( track->Type() == TYPE_VIA )
{ {
// Test distance between two vias, i.e. two circles, trivial case // Test distance between two vias, i.e. two circles, trivial case
if( (int) hypot( x0, y0 ) < w_dist ) if( (int) hypot( segStartPoint.x, segStartPoint.y ) < w_dist )
{ {
m_currentMarker = fillMarker( aRefSeg, track, m_currentMarker = fillMarker( aRefSeg, track,
DRCE_VIA_NEAR_VIA, m_currentMarker ); DRCE_VIA_NEAR_VIA, m_currentMarker );
...@@ -779,13 +771,13 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) ...@@ -779,13 +771,13 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
else // test via to segment else // test via to segment
{ {
// Compute l'angle // Compute l'angle
angle = ArcTangente( dy, dx ); angle = ArcTangente( delta.y, delta.x );
// Compute new coordinates ( the segment become horizontal) // Compute new coordinates ( the segment become horizontal)
RotatePoint( &dx, &dy, angle ); RotatePoint( &delta, angle );
RotatePoint( &x0, &y0, angle ); RotatePoint( &segStartPoint, angle );
if( !checkMarginToCircle( x0, y0, w_dist, dx ) ) if( !checkMarginToCircle( segStartPoint, w_dist, delta.x ) )
{ {
m_currentMarker = fillMarker( track, aRefSeg, m_currentMarker = fillMarker( track, aRefSeg,
DRCE_VIA_NEAR_TRACK, m_currentMarker ); DRCE_VIA_NEAR_TRACK, m_currentMarker );
...@@ -795,22 +787,19 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) ...@@ -795,22 +787,19 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
continue; continue;
} }
/* We compute x0,y0, xf,yf = starting and ending point coordinates for /* We compute segStartPoint.x,segStartPoint.y, segEndPoint.x,segEndPoint.y = starting and ending point coordinates for
* the segment to test in the new axis : the new X axis is the * the segment to test in the new axis : the new X axis is the
* reference segment. We must translate and rotate the segment to test * reference segment. We must translate and rotate the segment to test
*/ */
x0 = track->m_Start.x - origin.x; segStartPoint = track->m_Start - origin;
y0 = track->m_Start.y - origin.y; segEndPoint = track->m_End - origin;
xf = track->m_End.x - origin.x;
yf = track->m_End.y - origin.y;
RotatePoint( &x0, &y0, m_segmAngle ); RotatePoint( &segStartPoint, m_segmAngle );
RotatePoint( &xf, &yf, m_segmAngle ); RotatePoint( &segEndPoint, m_segmAngle );
if( track->Type() == TYPE_VIA ) if( track->Type() == TYPE_VIA )
{ {
if( checkMarginToCircle( x0, y0, w_dist, m_segmLength ) ) if( checkMarginToCircle( segStartPoint, w_dist, m_segmLength ) )
continue; continue;
m_currentMarker = fillMarker( aRefSeg, track, m_currentMarker = fillMarker( aRefSeg, track,
...@@ -822,40 +811,41 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) ...@@ -822,40 +811,41 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
* the reference segment is Horizontal. * the reference segment is Horizontal.
* 3 cases : the segment to test can be parallel, perpendicular or have an other direction * 3 cases : the segment to test can be parallel, perpendicular or have an other direction
*/ */
if( y0 == yf ) // parallel segments if( segStartPoint.y == segEndPoint.y ) // parallel segments
{ {
if( abs( y0 ) >= w_dist ) if( abs( segStartPoint.y ) >= w_dist )
continue; continue;
if( x0 > xf ) // Ensure segStartPoint.x <= segEndPoint.x
EXCHG( x0, xf ); /* pour que x0 <= xf */ if( segStartPoint.x > segEndPoint.x )
EXCHG( segStartPoint.x, segEndPoint.x );
if( x0 > (-w_dist) && x0 < (m_segmLength + w_dist) ) /* possible error drc */ if( segStartPoint.x > (-w_dist) && segStartPoint.x < (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 each end of the track segment:
if( x0 >= 0 && x0 <= m_segmLength ) if( segStartPoint.x >= 0 && segStartPoint.x <= 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( segStartPoint, 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;
} }
} }
if( xf > (-w_dist) && xf < (m_segmLength + w_dist) ) if( segEndPoint.x > (-w_dist) && segEndPoint.x < (m_segmLength + w_dist) )
{ {
/* Fine test : we consider the rounded shape of the ends */ /* Fine test : we consider the rounded shape of the ends */
if( xf >= 0 && xf <= m_segmLength ) if( segEndPoint.x >= 0 && segEndPoint.x <= 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( segEndPoint, w_dist, m_segmLength ) )
{ {
m_currentMarker = fillMarker( aRefSeg, track, m_currentMarker = fillMarker( aRefSeg, track,
DRCE_TRACK_ENDS4, m_currentMarker ); DRCE_TRACK_ENDS4, m_currentMarker );
...@@ -863,22 +853,22 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) ...@@ -863,22 +853,22 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
} }
} }
if( x0 <=0 && xf >= 0 ) if( segStartPoint.x <=0 && segEndPoint.x >= 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;
} }
} }
else if( x0 == xf ) // perpendicular segments else if( segStartPoint.x == segEndPoint.x ) // perpendicular segments
{ {
if( ( x0 <= (-w_dist) ) || ( x0 >= (m_segmLength + w_dist) ) ) if( ( segStartPoint.x <= (-w_dist) ) || ( segStartPoint.x >= (m_segmLength + w_dist) ) )
continue; continue;
// Test if segments are crossing // Test if segments are crossing
if( y0 > yf ) if( segStartPoint.y > segEndPoint.y )
EXCHG( y0, yf ); EXCHG( segStartPoint.y, segEndPoint.y );
if( (y0 < 0) && (yf > 0) ) if( (segStartPoint.y < 0) && (segEndPoint.y > 0) )
{ {
m_currentMarker = fillMarker( aRefSeg, track, m_currentMarker = fillMarker( aRefSeg, track,
DRCE_TRACKS_CROSSING, m_currentMarker ); DRCE_TRACKS_CROSSING, m_currentMarker );
...@@ -886,13 +876,13 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) ...@@ -886,13 +876,13 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
} }
// At this point the drc error is due to an end near a reference segm end // At this point the drc error is due to an end near a reference segm end
if( !checkMarginToCircle( x0, y0, w_dist, m_segmLength ) ) if( !checkMarginToCircle( segStartPoint, 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( segEndPoint, w_dist, m_segmLength ) )
{ {
m_currentMarker = fillMarker( aRefSeg, track, m_currentMarker = fillMarker( aRefSeg, track,
DRCE_ENDS_PROBLEM2, m_currentMarker ); DRCE_ENDS_PROBLEM2, m_currentMarker );
...@@ -910,7 +900,7 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) ...@@ -910,7 +900,7 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
// A fine test is needed because a serment is not exactly a // A fine test is needed because a serment is not exactly a
// rectangle, it has rounded ends // rectangle, it has rounded ends
if( !checkLine( x0, y0, xf, yf ) ) if( !checkLine( segStartPoint, segEndPoint ) )
{ {
/* 2eme passe : the track has rounded ends. /* 2eme passe : the track has rounded ends.
* we must a fine test for each rounded end and the * we must a fine test for each rounded end and the
...@@ -920,7 +910,7 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) ...@@ -920,7 +910,7 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
m_xcliplo = 0; m_xcliplo = 0;
m_xcliphi = m_segmLength; m_xcliphi = m_segmLength;
if( !checkLine( x0, y0, xf, yf ) ) if( !checkLine( segStartPoint, segEndPoint ) )
{ {
m_currentMarker = fillMarker( aRefSeg, track, m_currentMarker = fillMarker( aRefSeg, track,
DRCE_ENDS_PROBLEM3, m_currentMarker ); DRCE_ENDS_PROBLEM3, m_currentMarker );
...@@ -929,39 +919,31 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) ...@@ -929,39 +919,31 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
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
{ {
// Test the starting and the ending point // Test the starting and the ending point
int angle, rx0, ry0, rxf, ryf; segStartPoint = track->m_Start;
x0 = track->m_Start.x; segEndPoint = track->m_End;
y0 = track->m_Start.y; delta = segEndPoint - segStartPoint;
xf = track->m_End.x;
yf = track->m_End.y;
dx = xf - x0;
dy = yf - y0;
/* Compute the segment orientation (angle) en 0,1 degre */ /* Compute the segment orientation (angle) en 0,1 degre */
angle = ArcTangente( dy, dx ); int angle = ArcTangente( delta.y, delta.x );
/* Compute the segment lenght: dx = longueur */ // Compute the segment lenght: delta.x = lenght after rotation
RotatePoint( &dx, &dy, angle ); RotatePoint( &delta, angle );
/* Comute the reference segment coordinates relatives to a /* Comute the reference segment coordinates relatives to a
* X axis = current tested segment * X axis = current tested segment
*/ */
rx0 = aRefSeg->m_Start.x - x0; wxPoint relStartPos = aRefSeg->m_Start - segStartPoint;
ry0 = aRefSeg->m_Start.y - y0; wxPoint relEndPos = aRefSeg->m_End - segStartPoint;
rxf = aRefSeg->m_End.x - x0;
ryf = aRefSeg->m_End.y - y0; RotatePoint( &relStartPos, angle );
RotatePoint( &relEndPos, angle );
RotatePoint( &rx0, &ry0, angle ); if( !checkMarginToCircle( relStartPos, w_dist, delta.x ) )
RotatePoint( &rxf, &ryf, angle );
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( relEndPos, w_dist, delta.x ) )
{ {
m_currentMarker = fillMarker( aRefSeg, track, m_currentMarker = fillMarker( aRefSeg, track,
DRCE_ENDS_PROBLEM5, m_currentMarker ); DRCE_ENDS_PROBLEM5, m_currentMarker );
...@@ -987,7 +969,7 @@ bool DRC::doPadToPadsDrc( D_PAD* aRefPad, LISTE_PAD* aStart, LISTE_PAD* aEnd, ...@@ -987,7 +969,7 @@ bool DRC::doPadToPadsDrc( D_PAD* aRefPad, LISTE_PAD* aStart, LISTE_PAD* aEnd,
// pad to pad hole DRC, using pad to pad DRC test. // pad to pad hole DRC, using pad to pad DRC test.
// this dummy pad is a circle or an oval. // this dummy pad is a circle or an oval.
static D_PAD dummypad( (MODULE*) NULL ); static D_PAD dummypad( (MODULE*) NULL );
dummypad.m_Masque_Layer = ALL_CU_LAYERS; // za hole is on all layers dummypad.m_Masque_Layer |= ALL_CU_LAYERS; // Ensure the hole is on all copper layers
dummypad.m_LocalClearance = 1; /* Use the minimal local clerance value for the dummy pad dummypad.m_LocalClearance = 1; /* Use the minimal local clerance value for the dummy pad
* the clearance of the active pad will be used * the clearance of the active pad will be used
* as minimum distance to a hole * as minimum distance to a hole
...@@ -1333,7 +1315,7 @@ bool DRC::checkClearanceSegmToPad( const D_PAD* aPad, int aSegmentWidth, int aMi ...@@ -1333,7 +1315,7 @@ bool DRC::checkClearanceSegmToPad( const D_PAD* aPad, int aSegmentWidth, int aMi
{ {
wxSize padHalfsize; // half the dimension of the pad wxSize padHalfsize; // half the dimension of the pad
int orient; int orient;
int x0, y0, xf, yf; wxPoint startPoint, endPoint;
int seuil; int seuil;
int deltay; int deltay;
...@@ -1347,9 +1329,8 @@ bool DRC::checkClearanceSegmToPad( const D_PAD* aPad, int aSegmentWidth, int aMi ...@@ -1347,9 +1329,8 @@ bool DRC::checkClearanceSegmToPad( const D_PAD* aPad, int aSegmentWidth, int aMi
/* Easy case: just test the distance between segment and pad centre /* Easy case: just test the distance between segment and pad centre
* calculate pad coordinates in the X,Y axis with X axis = segment to test * 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, m_segmAngle );
return checkMarginToCircle( m_padToTestPos.x, m_padToTestPos.y, return checkMarginToCircle( m_padToTestPos, seuil + padHalfsize.x, m_segmLength );
seuil + padHalfsize.x, m_segmLength );
} }
else else
{ {
...@@ -1363,17 +1344,15 @@ bool DRC::checkClearanceSegmToPad( const D_PAD* aPad, int aSegmentWidth, int aMi ...@@ -1363,17 +1344,15 @@ bool DRC::checkClearanceSegmToPad( const D_PAD* aPad, int aSegmentWidth, int aMi
m_xcliphi = m_padToTestPos.x + seuil + padHalfsize.x; m_xcliphi = m_padToTestPos.x + seuil + padHalfsize.x;
m_ycliphi = m_padToTestPos.y + seuil + padHalfsize.y; m_ycliphi = m_padToTestPos.y + seuil + padHalfsize.y;
x0 = y0 = 0; startPoint.x = startPoint.y = 0;
endPoint = m_segmEnd;
xf = m_segmEnd.x;
yf = m_segmEnd.y;
orient = aPad->m_Orient; orient = aPad->m_Orient;
RotatePoint( &x0, &y0, m_padToTestPos.x, m_padToTestPos.y, -orient ); RotatePoint( &startPoint, m_padToTestPos, -orient );
RotatePoint( &xf, &yf, m_padToTestPos.x, m_padToTestPos.y, -orient ); RotatePoint( &endPoint, m_padToTestPos, -orient );
if( checkLine( x0, y0, xf, yf ) ) if( checkLine( startPoint, endPoint ) )
return true; return true;
/* segment intersects the bounding box. But there is not always a DRC error. /* segment intersects the bounding box. But there is not always a DRC error.
...@@ -1405,28 +1384,28 @@ bool DRC::checkClearanceSegmToPad( const D_PAD* aPad, int aSegmentWidth, int aMi ...@@ -1405,28 +1384,28 @@ bool DRC::checkClearanceSegmToPad( const D_PAD* aPad, int aSegmentWidth, int aMi
m_ycliplo = m_padToTestPos.y - segmHalfWidth - 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 + segmHalfWidth + deltay; m_ycliphi = m_padToTestPos.y + segmHalfWidth + deltay;
if( !checkLine( x0, y0, xf, yf ) ) if( !checkLine( startPoint, endPoint ) )
return false; return false;
// test the first circle // test the first circle
x0 = m_padToTestPos.x; // x0,y0 = centre of the upper circle of the oval shape startPoint.x = m_padToTestPos.x; // segStartPoint.x,segStartPoint.y = centre of the upper circle of the oval shape
y0 = m_padToTestPos.y + deltay; startPoint.y = m_padToTestPos.y + deltay;
// Calculate the actual position of the circle, given the pad orientation: // Calculate the actual position of the circle, given the pad orientation:
RotatePoint( &x0, &y0, m_padToTestPos.x, m_padToTestPos.y, orient ); RotatePoint( &startPoint, m_padToTestPos, orient );
// Calculate the actual position of the circle in the new X,Y axis: // Calculate the actual position of the circle in the new X,Y axis:
RotatePoint( &x0, &y0, m_segmAngle ); RotatePoint( &startPoint, m_segmAngle );
if( !checkMarginToCircle( x0, y0, padHalfsize.x + seuil, m_segmLength ) ) if( !checkMarginToCircle( startPoint, padHalfsize.x + seuil, m_segmLength ) )
return false; return false;
// test the second circle // test the second circle
x0 = m_padToTestPos.x; // x0,y0 = centre of the lower circle of the oval shape startPoint.x = m_padToTestPos.x; // segStartPoint.x,segStartPoint.y = centre of the lower circle of the oval shape
y0 = m_padToTestPos.y - deltay; startPoint.y = m_padToTestPos.y - deltay;
RotatePoint( &x0, &y0, m_padToTestPos.x, m_padToTestPos.y, orient ); RotatePoint( &startPoint, m_padToTestPos, orient );
RotatePoint( &x0, &y0, m_segmAngle ); RotatePoint( &startPoint, m_segmAngle );
if( !checkMarginToCircle( x0, y0, padHalfsize.x + seuil, m_segmLength ) ) if( !checkMarginToCircle( startPoint, padHalfsize.x + seuil, m_segmLength ) )
return false; return false;
break; break;
...@@ -1437,7 +1416,7 @@ bool DRC::checkClearanceSegmToPad( const D_PAD* aPad, int aSegmentWidth, int aMi ...@@ -1437,7 +1416,7 @@ bool DRC::checkClearanceSegmToPad( const D_PAD* aPad, int aSegmentWidth, int aMi
m_xcliphi = m_padToTestPos.x + padHalfsize.x + seuil; m_xcliphi = m_padToTestPos.x + padHalfsize.x + seuil;
m_ycliphi = m_padToTestPos.y + padHalfsize.y; m_ycliphi = m_padToTestPos.y + padHalfsize.y;
if( !checkLine( x0, y0, xf, yf ) ) if( !checkLine( startPoint, endPoint ) )
{ {
return false; return false;
} }
...@@ -1448,48 +1427,48 @@ bool DRC::checkClearanceSegmToPad( const D_PAD* aPad, int aSegmentWidth, int aMi ...@@ -1448,48 +1427,48 @@ bool DRC::checkClearanceSegmToPad( const D_PAD* aPad, int aSegmentWidth, int aMi
m_xcliphi = m_padToTestPos.x + padHalfsize.x; m_xcliphi = m_padToTestPos.x + padHalfsize.x;
m_ycliphi = m_padToTestPos.y + padHalfsize.y + seuil; m_ycliphi = m_padToTestPos.y + padHalfsize.y + seuil;
if( !checkLine( x0, y0, xf, yf ) ) if( !checkLine( startPoint, endPoint ) )
{ {
return false; return false;
} }
/* test des 4 cercles ( surface d'solation autour des sommets */ /* test des 4 cercles ( surface d'solation autour des sommets */
/* test du coin sup. gauche du pad */ /* test du coin sup. gauche du pad */
x0 = m_padToTestPos.x - padHalfsize.x; startPoint.x = m_padToTestPos.x - padHalfsize.x;
y0 = m_padToTestPos.y - padHalfsize.y; startPoint.y = m_padToTestPos.y - padHalfsize.y;
RotatePoint( &x0, &y0, m_padToTestPos.x, m_padToTestPos.y, orient ); RotatePoint( &startPoint, m_padToTestPos, orient );
RotatePoint( &x0, &y0, m_segmAngle ); RotatePoint( &startPoint, m_segmAngle );
if( !checkMarginToCircle( x0, y0, seuil, m_segmLength ) ) if( !checkMarginToCircle( startPoint, seuil, m_segmLength ) )
{ {
return false; return false;
} }
/* test du coin sup. droit du pad */ /* test du coin sup. droit du pad */
x0 = m_padToTestPos.x + padHalfsize.x; startPoint.x = m_padToTestPos.x + padHalfsize.x;
y0 = m_padToTestPos.y - padHalfsize.y; startPoint.y = m_padToTestPos.y - padHalfsize.y;
RotatePoint( &x0, &y0, m_padToTestPos.x, m_padToTestPos.y, orient ); RotatePoint( &startPoint, m_padToTestPos, orient );
RotatePoint( &x0, &y0, m_segmAngle ); RotatePoint( &startPoint, m_segmAngle );
if( !checkMarginToCircle( x0, y0, seuil, m_segmLength ) ) if( !checkMarginToCircle( startPoint, seuil, m_segmLength ) )
{ {
return false; return false;
} }
/* test du coin inf. gauche du pad */ /* test du coin inf. gauche du pad */
x0 = m_padToTestPos.x - padHalfsize.x; startPoint.x = m_padToTestPos.x - padHalfsize.x;
y0 = m_padToTestPos.y + padHalfsize.y; startPoint.y = m_padToTestPos.y + padHalfsize.y;
RotatePoint( &x0, &y0, m_padToTestPos.x, m_padToTestPos.y, orient ); RotatePoint( &startPoint, m_padToTestPos, orient );
RotatePoint( &x0, &y0, m_segmAngle ); RotatePoint( &startPoint, m_segmAngle );
if( !checkMarginToCircle( x0, y0, seuil, m_segmLength ) ) if( !checkMarginToCircle( startPoint, seuil, m_segmLength ) )
{ {
return false; return false;
} }
/* test du coin inf. droit du pad */ /* test du coin inf. droit du pad */
x0 = m_padToTestPos.x + padHalfsize.x; startPoint.x = m_padToTestPos.x + padHalfsize.x;
y0 = m_padToTestPos.y + padHalfsize.y; startPoint.y = m_padToTestPos.y + padHalfsize.y;
RotatePoint( &x0, &y0, m_padToTestPos.x, m_padToTestPos.y, orient ); RotatePoint( &startPoint, m_padToTestPos, orient );
RotatePoint( &x0, &y0, m_segmAngle ); RotatePoint( &startPoint, m_segmAngle );
if( !checkMarginToCircle( x0, y0, seuil, m_segmLength ) ) if( !checkMarginToCircle( startPoint, seuil, m_segmLength ) )
{ {
return false; return false;
} }
...@@ -1504,22 +1483,28 @@ bool DRC::checkClearanceSegmToPad( const D_PAD* aPad, int aSegmentWidth, int aMi ...@@ -1504,22 +1483,28 @@ bool DRC::checkClearanceSegmToPad( const D_PAD* aPad, int aSegmentWidth, int aMi
} }
/**********************************************************************/ /**
bool DRC::checkMarginToCircle( int cx, int cy, int radius, int longueur ) * Helper function checkMarginToCircle
/**********************************************************************/ * Check the distance from a circle (round pad, via or round end of track) to
* a segment. the segment is expected starting at 0,0, and on the X axis
* return true if distance >= aRadius
*/
bool DRC::checkMarginToCircle( wxPoint aCentre, int aRadius, int aLength )
{ {
if( abs( cy ) > radius ) if( abs( aCentre.y ) > aRadius ) // trivial case
return true; return true;
if( (cx >= -radius ) && ( cx <= (longueur + radius) ) ) // Here, didstance between aCentre and X axis is < aRadius
if( (aCentre.x >= -aRadius ) && ( aCentre.x <= (aLength + aRadius) ) )
{ {
if( (cx >= 0) && (cx <= longueur) ) if( (aCentre.x >= 0) && (aCentre.x <= aLength) )
return false; return false; // aCentre is between the starting point and the ending point of the segm
if( cx > longueur ) if( aCentre.x > aLength ) // aCentre is after the ending point
cx -= longueur; aCentre.x -= aLength; // move aCentre to the starting point of the segment
if( hypot( cx, cy ) < radius ) if( hypot( aCentre.x, aCentre.y ) < aRadius )
// distance between aCentre and the starting point or the ending point is < aRadius
return false; return false;
} }
...@@ -1527,10 +1512,7 @@ bool DRC::checkMarginToCircle( int cx, int cy, int radius, int longueur ) ...@@ -1527,10 +1512,7 @@ bool DRC::checkMarginToCircle( int cx, int cy, int radius, int longueur )
} }
/**********************************************/ // Helper function used in checkLine::
/* int Tst_Ligne(int x1,int y1,int x2,int y2) */
/**********************************************/
static inline int USCALE( unsigned arg, unsigned num, unsigned den ) static inline int USCALE( unsigned arg, unsigned num, unsigned den )
{ {
int ii; int ii;
...@@ -1540,107 +1522,109 @@ static inline int USCALE( unsigned arg, unsigned num, unsigned den ) ...@@ -1540,107 +1522,109 @@ static inline int USCALE( unsigned arg, unsigned num, unsigned den )
} }
/** Helper function checkLine
* Test if a line intersects a bounding box (a rectangle)
* The rectangle is defined by m_xcliplo, m_ycliplo and m_xcliphi, m_ycliphi
* return true if the line from aSegStart to aSegEnd is outside the bounding box
*/
bool DRC::checkLine( wxPoint aSegStart, wxPoint aSegEnd )
{
#define WHEN_OUTSIDE return true #define WHEN_OUTSIDE return true
#define WHEN_INSIDE #define WHEN_INSIDE
bool DRC::checkLine( int x1, int y1, int x2, int y2 )
{
int temp; int temp;
if( x1 > x2 ) if( aSegStart.x > aSegEnd.x )
{ EXCHG( aSegStart, aSegEnd );
EXCHG( x1, x2 );
EXCHG( y1, y2 ); if( (aSegEnd.x < m_xcliplo) || (aSegStart.x > m_xcliphi) )
}
if( (x2 < m_xcliplo) || (x1 > m_xcliphi) )
{ {
WHEN_OUTSIDE; WHEN_OUTSIDE;
} }
if( y1 < y2 ) if( aSegStart.y < aSegEnd.y )
{ {
if( (y2 < m_ycliplo) || (y1 > m_ycliphi) ) if( (aSegEnd.y < m_ycliplo) || (aSegStart.y > m_ycliphi) )
{ {
WHEN_OUTSIDE; WHEN_OUTSIDE;
} }
if( y1 < m_ycliplo ) if( aSegStart.y < m_ycliplo )
{ {
temp = USCALE( (x2 - x1), (m_ycliplo - y1), (y2 - y1) ); temp = USCALE( (aSegEnd.x - aSegStart.x), (m_ycliplo - aSegStart.y), (aSegEnd.y - aSegStart.y) );
if( (x1 += temp) > m_xcliphi ) if( (aSegStart.x += temp) > m_xcliphi )
{ {
WHEN_OUTSIDE; WHEN_OUTSIDE;
} }
y1 = m_ycliplo; aSegStart.y = m_ycliplo;
WHEN_INSIDE; WHEN_INSIDE;
} }
if( y2 > m_ycliphi ) if( aSegEnd.y > m_ycliphi )
{ {
temp = USCALE( (x2 - x1), (y2 - m_ycliphi), (y2 - y1) ); temp = USCALE( (aSegEnd.x - aSegStart.x), (aSegEnd.y - m_ycliphi), (aSegEnd.y - aSegStart.y) );
if( (x2 -= temp) < m_xcliplo ) if( (aSegEnd.x -= temp) < m_xcliplo )
{ {
WHEN_OUTSIDE; WHEN_OUTSIDE;
} }
y2 = m_ycliphi; aSegEnd.y = m_ycliphi;
WHEN_INSIDE; WHEN_INSIDE;
} }
if( x1 < m_xcliplo ) if( aSegStart.x < m_xcliplo )
{ {
temp = USCALE( (y2 - y1), (m_xcliplo - x1), (x2 - x1) ); temp = USCALE( (aSegEnd.y - aSegStart.y), (m_xcliplo - aSegStart.x), (aSegEnd.x - aSegStart.x) );
y1 += temp; aSegStart.y += temp;
x1 = m_xcliplo; aSegStart.x = m_xcliplo;
WHEN_INSIDE; WHEN_INSIDE;
} }
if( x2 > m_xcliphi ) if( aSegEnd.x > m_xcliphi )
{ {
temp = USCALE( (y2 - y1), (x2 - m_xcliphi), (x2 - x1) ); temp = USCALE( (aSegEnd.y - aSegStart.y), (aSegEnd.x - m_xcliphi), (aSegEnd.x - aSegStart.x) );
y2 -= temp; aSegEnd.y -= temp;
x2 = m_xcliphi; aSegEnd.x = m_xcliphi;
WHEN_INSIDE; WHEN_INSIDE;
} }
} }
else else
{ {
if( (y1 < m_ycliplo) || (y2 > m_ycliphi) ) if( (aSegStart.y < m_ycliplo) || (aSegEnd.y > m_ycliphi) )
{ {
WHEN_OUTSIDE; WHEN_OUTSIDE;
} }
if( y1 > m_ycliphi ) if( aSegStart.y > m_ycliphi )
{ {
temp = USCALE( (x2 - x1), (y1 - m_ycliphi), (y1 - y2) ); temp = USCALE( (aSegEnd.x - aSegStart.x), (aSegStart.y - m_ycliphi), (aSegStart.y - aSegEnd.y) );
if( (x1 += temp) > m_xcliphi ) if( (aSegStart.x += temp) > m_xcliphi )
{ {
WHEN_OUTSIDE; WHEN_OUTSIDE;
} }
y1 = m_ycliphi; aSegStart.y = m_ycliphi;
WHEN_INSIDE; WHEN_INSIDE;
} }
if( y2 < m_ycliplo ) if( aSegEnd.y < m_ycliplo )
{ {
temp = USCALE( (x2 - x1), (m_ycliplo - y2), (y1 - y2) ); temp = USCALE( (aSegEnd.x - aSegStart.x), (m_ycliplo - aSegEnd.y), (aSegStart.y - aSegEnd.y) );
if( (x2 -= temp) < m_xcliplo ) if( (aSegEnd.x -= temp) < m_xcliplo )
{ {
WHEN_OUTSIDE; WHEN_OUTSIDE;
} }
y2 = m_ycliplo; aSegEnd.y = m_ycliplo;
WHEN_INSIDE; WHEN_INSIDE;
} }
if( x1 < m_xcliplo ) if( aSegStart.x < m_xcliplo )
{ {
temp = USCALE( (y1 - y2), (m_xcliplo - x1), (x2 - x1) ); temp = USCALE( (aSegStart.y - aSegEnd.y), (m_xcliplo - aSegStart.x), (aSegEnd.x - aSegStart.x) );
y1 -= temp; aSegStart.y -= temp;
x1 = m_xcliplo; aSegStart.x = m_xcliplo;
WHEN_INSIDE; WHEN_INSIDE;
} }
if( x2 > m_xcliphi ) if( aSegEnd.x > m_xcliphi )
{ {
temp = USCALE( (y1 - y2), (x2 - m_xcliphi), (x2 - x1) ); temp = USCALE( (aSegStart.y - aSegEnd.y), (aSegEnd.x - m_xcliphi), (aSegEnd.x - aSegStart.x) );
y2 += temp; aSegEnd.y += temp;
x2 = m_xcliphi; aSegEnd.x = m_xcliphi;
WHEN_INSIDE; WHEN_INSIDE;
} }
} }
if( ( (x2 + x1) / 2 <= m_xcliphi ) && ( (x2 + x1) / 2 >= m_xcliplo ) \ if( ( (aSegEnd.x + aSegStart.x) / 2 <= m_xcliphi ) && ( (aSegEnd.x + aSegStart.x) / 2 >= m_xcliplo ) \
&& ( (y2 + y1) / 2 <= m_ycliphi ) && ( (y2 + y1) / 2 >= m_ycliplo ) ) && ( (aSegEnd.y + aSegStart.y) / 2 <= m_ycliphi ) && ( (aSegEnd.y + aSegStart.y) / 2 >= m_ycliplo ) )
{ {
return false; return false;
} }
......
...@@ -173,10 +173,10 @@ private: ...@@ -173,10 +173,10 @@ private:
/* variables used in checkLine to test DRC segm to segm: /* variables used in checkLine to test DRC segm to segm:
* define the area relative to the ref segment that does not contains anu other segment * define the area relative to the ref segment that does not contains anu other segment
*/ */
int m_xcliplo; int m_xcliplo;
int m_ycliplo; int m_ycliplo;
int m_xcliphi; int m_xcliphi;
int m_ycliphi; int m_ycliphi;
WinEDA_PcbFrame* m_mainWindow; WinEDA_PcbFrame* m_mainWindow;
BOARD* m_pcb; BOARD* m_pcb;
...@@ -329,30 +329,27 @@ private: ...@@ -329,30 +329,27 @@ private:
/** /**
* Function checkMarginToCircle * Helper function checkMarginToCircle
* @todo this translation is no good, fix this: * Check the distance from a point to
* calculates the distance from a circle (via or round end of track) to the * a segment. the segment is expected starting at 0,0, and on the X axis
* segment of reference on the right hand side. * (used to test DRC between a segment and a round pad, via or round end of a track
* * @param aCentre The coordinate of the circle's center
* @param cx The x coordinate of the circle's center * @param aRadius A "keep out" radius centered over the circle
* @param cy The y coordinate of the circle's center * @param aLength The length of the segment (i.e. coordinate of end, becuase it is on the X axis)
* @param radius A "keep out" radius centered over the circle
* @param length The length of the segment (i.e. coordinate of end)
* @return bool - true if distance >= radius, else * @return bool - true if distance >= radius, else
* false when distance < radius * false when distance < aRadius
*/ */
static bool checkMarginToCircle( int cx, int cy, int radius, int length ); static bool checkMarginToCircle( wxPoint aCentre, int aRadius, int aLength );
/** /**
* Function checkLine * Function checkLine
* tests to see if one track is in contact with another track. * (helper function used in drc calculations to see if one track is in contact with another track).
* * Test if a line intersects a bounding box (a rectangle)
* Cette routine controle si la ligne (x1,y1 x2,y2) a une partie s'inscrivant * The rectangle is defined by m_xcliplo, m_ycliplo and m_xcliphi, m_ycliphi
* dans le cadre (xcliplo,ycliplo xcliphi,ycliphi) (variables globales, * return true if the line from aSegStart to aSegEnd is outside the bounding box
* locales a ce fichier)
*/ */
bool checkLine( int x1, int y1, int x2, int y2 ); bool checkLine( wxPoint aSegStart, wxPoint aSegEnd );
//-----</single tests>--------------------------------------------- //-----</single tests>---------------------------------------------
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment