Fix board outline issues.
1) Don't try and do board-edge clearance checking against a synthetic polygon constructed because we didn't find any edges. 2) Check pads against board edge. 3) Don't report vias as "Track too close to board edge".
This commit is contained in:
parent
ad6857f131
commit
d046f165de
|
@ -750,6 +750,7 @@ bool BuildBoardPolygonOutlines( BOARD* aBoard, SHAPE_POLY_SET& aOutlines,
|
||||||
wxString* aErrorText, unsigned int aTolerance, wxPoint* aErrorLocation )
|
wxString* aErrorText, unsigned int aTolerance, wxPoint* aErrorLocation )
|
||||||
{
|
{
|
||||||
PCB_TYPE_COLLECTOR items;
|
PCB_TYPE_COLLECTOR items;
|
||||||
|
bool success = false;
|
||||||
|
|
||||||
// Get all the DRAWSEGMENTS and module graphics into 'items',
|
// Get all the DRAWSEGMENTS and module graphics into 'items',
|
||||||
// then keep only those on layer == Edge_Cuts.
|
// then keep only those on layer == Edge_Cuts.
|
||||||
|
@ -765,15 +766,17 @@ bool BuildBoardPolygonOutlines( BOARD* aBoard, SHAPE_POLY_SET& aOutlines,
|
||||||
segList.push_back( static_cast< DRAWSEGMENT* >( items[ii] ) );
|
segList.push_back( static_cast< DRAWSEGMENT* >( items[ii] ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool success = ConvertOutlineToPolygon( segList, aOutlines, aErrorText, aTolerance, aErrorLocation );
|
if( segList.size() )
|
||||||
|
{
|
||||||
|
success = ConvertOutlineToPolygon( segList, aOutlines, aErrorText, aTolerance,
|
||||||
|
aErrorLocation );
|
||||||
|
}
|
||||||
|
|
||||||
if( !success || !aOutlines.OutlineCount() )
|
if( !success || !aOutlines.OutlineCount() )
|
||||||
{
|
{
|
||||||
// Creates a valid polygon outline is not possible.
|
// Couldn't create a valid polygon outline. Use the board edge cuts bounding box to
|
||||||
// So uses the board edge cuts bounding box to create a
|
// create a rectangular outline, or, failing that, the bounding box of the items on
|
||||||
// rectangular outline
|
// the board.
|
||||||
// When no edge cuts items, build a contour
|
|
||||||
// from global bounding box
|
|
||||||
|
|
||||||
EDA_RECT bbbox = aBoard->GetBoardEdgesBoundingBox();
|
EDA_RECT bbbox = aBoard->GetBoardEdgesBoundingBox();
|
||||||
|
|
||||||
|
|
|
@ -65,11 +65,11 @@ DRC::DRC() :
|
||||||
PCB_TOOL_BASE( "pcbnew.DRCTool" ),
|
PCB_TOOL_BASE( "pcbnew.DRCTool" ),
|
||||||
m_pcbEditorFrame( nullptr ),
|
m_pcbEditorFrame( nullptr ),
|
||||||
m_pcb( nullptr ),
|
m_pcb( nullptr ),
|
||||||
|
m_board_outline_valid( false ),
|
||||||
m_drcDialog( nullptr ),
|
m_drcDialog( nullptr ),
|
||||||
m_largestClearance( 0 )
|
m_largestClearance( 0 )
|
||||||
{
|
{
|
||||||
// establish initial values for everything:
|
// establish initial values for everything:
|
||||||
m_doPad2PadTest = true; // enable pad to pad clearance tests
|
|
||||||
m_doUnconnectedTest = true; // enable unconnected tests
|
m_doUnconnectedTest = true; // enable unconnected tests
|
||||||
m_doZonesTest = false; // disable zone to items clearance tests
|
m_doZonesTest = false; // disable zone to items clearance tests
|
||||||
m_doKeepoutTest = true; // enable keepout areas to items clearance tests
|
m_doKeepoutTest = true; // enable keepout areas to items clearance tests
|
||||||
|
@ -401,7 +401,10 @@ void DRC::RunTests( wxTextCtrl* aMessages )
|
||||||
|
|
||||||
m_largestClearance = bds.GetBiggestClearanceValue();
|
m_largestClearance = bds.GetBiggestClearanceValue();
|
||||||
|
|
||||||
if( !bds.Ignore( DRCE_INVALID_OUTLINE ) )
|
if( !bds.Ignore( DRCE_INVALID_OUTLINE )
|
||||||
|
|| !bds.Ignore( DRCE_TRACK_NEAR_EDGE )
|
||||||
|
|| !bds.Ignore( DRCE_VIA_NEAR_EDGE )
|
||||||
|
|| !bds.Ignore( DRCE_PAD_NEAR_EDGE ) )
|
||||||
{
|
{
|
||||||
if( aMessages )
|
if( aMessages )
|
||||||
{
|
{
|
||||||
|
@ -441,7 +444,9 @@ void DRC::RunTests( wxTextCtrl* aMessages )
|
||||||
}
|
}
|
||||||
|
|
||||||
// test pad to pad clearances, nothing to do with tracks, vias or zones.
|
// test pad to pad clearances, nothing to do with tracks, vias or zones.
|
||||||
if( m_doPad2PadTest )
|
if( !bds.Ignore( DRCE_PAD_NEAR_EDGE )
|
||||||
|
|| !bds.Ignore( DRCE_PAD_NEAR_PAD )
|
||||||
|
|| !bds.Ignore( DRCE_HOLE_NEAR_PAD ) )
|
||||||
{
|
{
|
||||||
if( aMessages )
|
if( aMessages )
|
||||||
{
|
{
|
||||||
|
@ -449,7 +454,7 @@ void DRC::RunTests( wxTextCtrl* aMessages )
|
||||||
wxSafeYield();
|
wxSafeYield();
|
||||||
}
|
}
|
||||||
|
|
||||||
testPad2Pad( commit );
|
testPadClearances( commit );
|
||||||
}
|
}
|
||||||
|
|
||||||
// test drilled holes
|
// test drilled holes
|
||||||
|
@ -657,16 +662,17 @@ void DRC::updatePointers()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DRC::testPad2Pad( BOARD_COMMIT& aCommit )
|
void DRC::testPadClearances( BOARD_COMMIT& aCommit )
|
||||||
{
|
{
|
||||||
std::vector<D_PAD*> sortedPads;
|
BOARD_DESIGN_SETTINGS& bds = m_pcb->GetDesignSettings();
|
||||||
|
std::vector<D_PAD*> sortedPads;
|
||||||
|
|
||||||
m_pcb->GetSortedPadListByXthenYCoord( sortedPads );
|
m_pcb->GetSortedPadListByXthenYCoord( sortedPads );
|
||||||
|
|
||||||
if( sortedPads.empty() )
|
if( sortedPads.empty() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// find the max size of the pads (used to stop the test)
|
// find the max size of the pads (used to stop the pad-to-pad tests)
|
||||||
int max_size = 0;
|
int max_size = 0;
|
||||||
|
|
||||||
for( D_PAD* pad : sortedPads )
|
for( D_PAD* pad : sortedPads )
|
||||||
|
@ -688,9 +694,50 @@ void DRC::testPad2Pad( BOARD_COMMIT& aCommit )
|
||||||
// Test the pads
|
// Test the pads
|
||||||
for( auto& pad : sortedPads )
|
for( auto& pad : sortedPads )
|
||||||
{
|
{
|
||||||
int x_limit = pad->GetPosition().x + pad->GetBoundingRadius() + max_size;
|
if( !bds.Ignore( DRCE_PAD_NEAR_EDGE ) && m_board_outline_valid )
|
||||||
|
{
|
||||||
|
static DRAWSEGMENT dummyEdge;
|
||||||
|
dummyEdge.SetLayer( Edge_Cuts );
|
||||||
|
|
||||||
doPadToPadsDrc( aCommit, pad, &pad, listEnd, x_limit );
|
int minClearance = pad->GetClearance( &dummyEdge, &m_clearanceSource );
|
||||||
|
|
||||||
|
if( bds.m_CopperEdgeClearance > minClearance )
|
||||||
|
{
|
||||||
|
minClearance = bds.m_CopperEdgeClearance;
|
||||||
|
m_clearanceSource = _( "board edge" );
|
||||||
|
}
|
||||||
|
|
||||||
|
for( auto it = m_board_outlines.IterateSegmentsWithHoles(); it; it++ )
|
||||||
|
{
|
||||||
|
int actual;
|
||||||
|
|
||||||
|
if( !checkClearanceSegmToPad( *it, 0, pad, minClearance, &actual ) )
|
||||||
|
{
|
||||||
|
actual = std::max( 0, actual );
|
||||||
|
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_PAD_NEAR_EDGE );
|
||||||
|
|
||||||
|
m_msg.Printf( drcItem->GetErrorText() + _( " (%s %s; actual %s)" ),
|
||||||
|
m_clearanceSource,
|
||||||
|
MessageTextFromValue( userUnits(), minClearance, true ),
|
||||||
|
MessageTextFromValue( userUnits(), actual, true ) );
|
||||||
|
|
||||||
|
drcItem->SetErrorMessage( m_msg );
|
||||||
|
drcItem->SetItems( pad );
|
||||||
|
|
||||||
|
MARKER_PCB* marker = new MARKER_PCB( drcItem, pad->GetPosition() );
|
||||||
|
addMarkerToPcb( aCommit, marker );
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !bds.Ignore( DRCE_PAD_NEAR_PAD ) || !bds.Ignore( DRCE_HOLE_NEAR_PAD ) )
|
||||||
|
{
|
||||||
|
int x_limit = pad->GetPosition().x + pad->GetBoundingRadius() + max_size;
|
||||||
|
|
||||||
|
doPadToPadsDrc( aCommit, pad, &pad, listEnd, x_limit );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1070,8 +1117,13 @@ void DRC::testOutline( BOARD_COMMIT& aCommit )
|
||||||
wxPoint error_loc( m_pcb->GetBoardEdgesBoundingBox().GetPosition() );
|
wxPoint error_loc( m_pcb->GetBoardEdgesBoundingBox().GetPosition() );
|
||||||
|
|
||||||
m_board_outlines.RemoveAllContours();
|
m_board_outlines.RemoveAllContours();
|
||||||
|
m_board_outline_valid = false;
|
||||||
|
|
||||||
if( !m_pcb->GetBoardPolygonOutlines( m_board_outlines, nullptr, &error_loc ) )
|
if( m_pcb->GetBoardPolygonOutlines( m_board_outlines, nullptr, &error_loc ) )
|
||||||
|
{
|
||||||
|
m_board_outline_valid = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_INVALID_OUTLINE );
|
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_INVALID_OUTLINE );
|
||||||
|
|
||||||
|
|
|
@ -52,6 +52,8 @@ enum PCB_DRC_CODE {
|
||||||
DRCE_TRACK_SEGMENTS_TOO_CLOSE, ///< 2 parallel track segments too close: segm ends between segref ends
|
DRCE_TRACK_SEGMENTS_TOO_CLOSE, ///< 2 parallel track segments too close: segm ends between segref ends
|
||||||
DRCE_TRACKS_CROSSING, ///< tracks are crossing
|
DRCE_TRACKS_CROSSING, ///< tracks are crossing
|
||||||
DRCE_TRACK_NEAR_EDGE, ///< track too close to board edge
|
DRCE_TRACK_NEAR_EDGE, ///< track too close to board edge
|
||||||
|
DRCE_VIA_NEAR_EDGE, ///< via too close to board edge
|
||||||
|
DRCE_PAD_NEAR_EDGE, ///< pad too close to board edge
|
||||||
DRCE_PAD_NEAR_PAD, ///< pad too close to pad
|
DRCE_PAD_NEAR_PAD, ///< pad too close to pad
|
||||||
DRCE_PAD_NEAR_COPPER, ///< pad and copper graphic collide or are too close
|
DRCE_PAD_NEAR_COPPER, ///< pad and copper graphic collide or are too close
|
||||||
DRCE_ZONES_INTERSECT, ///< copper area outlines intersect
|
DRCE_ZONES_INTERSECT, ///< copper area outlines intersect
|
||||||
|
@ -163,6 +165,7 @@ private:
|
||||||
PCB_EDIT_FRAME* m_pcbEditorFrame; // The pcb frame editor which owns the board
|
PCB_EDIT_FRAME* m_pcbEditorFrame; // The pcb frame editor which owns the board
|
||||||
BOARD* m_pcb;
|
BOARD* m_pcb;
|
||||||
SHAPE_POLY_SET m_board_outlines; // The board outline including cutouts
|
SHAPE_POLY_SET m_board_outlines; // The board outline including cutouts
|
||||||
|
bool m_board_outline_valid;
|
||||||
DIALOG_DRC* m_drcDialog;
|
DIALOG_DRC* m_drcDialog;
|
||||||
|
|
||||||
std::vector<DRC_ITEM*> m_unconnected; // list of unconnected pads
|
std::vector<DRC_ITEM*> m_unconnected; // list of unconnected pads
|
||||||
|
@ -214,7 +217,7 @@ private:
|
||||||
*/
|
*/
|
||||||
void testTracks( BOARD_COMMIT& aCommit, wxWindow * aActiveWindow, bool aShowProgressBar );
|
void testTracks( BOARD_COMMIT& aCommit, wxWindow * aActiveWindow, bool aShowProgressBar );
|
||||||
|
|
||||||
void testPad2Pad( BOARD_COMMIT& aCommit );
|
void testPadClearances( BOARD_COMMIT& aCommit );
|
||||||
|
|
||||||
void testUnconnected();
|
void testUnconnected();
|
||||||
|
|
||||||
|
|
|
@ -604,6 +604,7 @@ void DRC::doTrackDrc( BOARD_COMMIT& aCommit, TRACK* aRefSeg, TRACKS::iterator aS
|
||||||
/***********************************************/
|
/***********************************************/
|
||||||
/* Phase 4: test DRC with to board edge */
|
/* Phase 4: test DRC with to board edge */
|
||||||
/***********************************************/
|
/***********************************************/
|
||||||
|
if( m_board_outline_valid )
|
||||||
{
|
{
|
||||||
static DRAWSEGMENT dummyEdge;
|
static DRAWSEGMENT dummyEdge;
|
||||||
dummyEdge.SetLayer( Edge_Cuts );
|
dummyEdge.SetLayer( Edge_Cuts );
|
||||||
|
@ -651,7 +652,9 @@ void DRC::doTrackDrc( BOARD_COMMIT& aCommit, TRACK* aRefSeg, TRACKS::iterator aS
|
||||||
BOARD::IterateForward<BOARD_ITEM*>( m_pcb->Drawings(), inspector, nullptr, types );
|
BOARD::IterateForward<BOARD_ITEM*>( m_pcb->Drawings(), inspector, nullptr, types );
|
||||||
|
|
||||||
int actual = std::max( 0.0, sqrt( center2center_squared ) - halfWidth );
|
int actual = std::max( 0.0, sqrt( center2center_squared ) - halfWidth );
|
||||||
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TRACK_NEAR_EDGE );
|
int errorCode = ( aRefSeg->Type() == PCB_VIA_T ) ? DRCE_VIA_NEAR_EDGE
|
||||||
|
: DRCE_TRACK_NEAR_EDGE;
|
||||||
|
DRC_ITEM* drcItem = new DRC_ITEM( errorCode );
|
||||||
|
|
||||||
m_msg.Printf( drcItem->GetErrorText() + _( " (%s clearance %s; actual %s)" ),
|
m_msg.Printf( drcItem->GetErrorText() + _( " (%s clearance %s; actual %s)" ),
|
||||||
m_clearanceSource,
|
m_clearanceSource,
|
||||||
|
|
|
@ -92,6 +92,8 @@ wxString DRC_ITEM::GetErrorText( int aCode, bool aTranslate ) const
|
||||||
case DRCE_TOO_SMALL_MICROVIA_DRILL: msg = _HKI( "Micro via drill too small" ); break;
|
case DRCE_TOO_SMALL_MICROVIA_DRILL: msg = _HKI( "Micro via drill too small" ); break;
|
||||||
case DRCE_DRILLED_HOLES_TOO_CLOSE: msg = _HKI( "Drilled holes too close together" ); break;
|
case DRCE_DRILLED_HOLES_TOO_CLOSE: msg = _HKI( "Drilled holes too close together" ); break;
|
||||||
case DRCE_TRACK_NEAR_EDGE: msg = _HKI( "Track too close to board edge" ); break;
|
case DRCE_TRACK_NEAR_EDGE: msg = _HKI( "Track too close to board edge" ); break;
|
||||||
|
case DRCE_VIA_NEAR_EDGE: msg = _HKI( "Via too close to board edge" ); break;
|
||||||
|
case DRCE_PAD_NEAR_EDGE: msg = _HKI( "Pad too close to board edge" ); break;
|
||||||
case DRCE_INVALID_OUTLINE: msg = _HKI( "Board has malformed outline" ); break;
|
case DRCE_INVALID_OUTLINE: msg = _HKI( "Board has malformed outline" ); break;
|
||||||
|
|
||||||
case DRCE_NETCLASS_TRACKWIDTH: msg = _HKI( "NetClass Track Width too small" ); break;
|
case DRCE_NETCLASS_TRACKWIDTH: msg = _HKI( "NetClass Track Width too small" ); break;
|
||||||
|
|
Loading…
Reference in New Issue