Finish implementation of hole clearance checking.

It appears we never did via hole testing, and pad hole testing didn't
appear to get much testing.
This commit is contained in:
Jeff Young 2020-12-25 22:13:47 +00:00
parent 0d57f90982
commit af2219ba7f
2 changed files with 159 additions and 76 deletions

View File

@ -32,17 +32,25 @@
#include <algorithm>
class SHAPE_SEGMENT : public SHAPE {
class SHAPE_SEGMENT : public SHAPE
{
public:
SHAPE_SEGMENT():
SHAPE( SH_SEGMENT ), m_width( 0 ) {};
SHAPE_SEGMENT() :
SHAPE( SH_SEGMENT ),
m_width( 0 )
{};
SHAPE_SEGMENT( const VECTOR2I& aA, const VECTOR2I& aB, int aWidth = 0 ):
SHAPE( SH_SEGMENT ), m_seg( aA, aB ), m_width( aWidth ) {};
SHAPE_SEGMENT( const VECTOR2I& aA, const VECTOR2I& aB, int aWidth = 0 ) :
SHAPE( SH_SEGMENT ),
m_seg( aA, aB ),
m_width( aWidth )
{};
SHAPE_SEGMENT( const SEG& aSeg, int aWidth = 0 ):
SHAPE( SH_SEGMENT ), m_seg( aSeg ), m_width( aWidth ) {};
SHAPE_SEGMENT( const SEG& aSeg, int aWidth = 0 ) :
SHAPE( SH_SEGMENT ),
m_seg( aSeg ),
m_width( aWidth )
{};
~SHAPE_SEGMENT() {};

View File

@ -33,7 +33,6 @@
#include <geometry/shape_segment.h>
#include <geometry/shape_null.h>
#include <drc/drc_engine.h>
#include <drc/drc_rtree.h>
#include <drc/drc_item.h>
#include <drc/drc_rule.h>
@ -105,11 +104,11 @@ private:
bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::Run()
{
m_board = m_drcEngine->GetBoard();
DRC_CONSTRAINT worstClearanceConstraint;
DRC_CONSTRAINT worstConstraint;
if( m_drcEngine->QueryWorstConstraint( CLEARANCE_CONSTRAINT, worstClearanceConstraint ) )
if( m_drcEngine->QueryWorstConstraint( CLEARANCE_CONSTRAINT, worstConstraint ) )
{
m_largestClearance = worstClearanceConstraint.GetValue().Min();
m_largestClearance = worstConstraint.GetValue().Min();
}
else
{
@ -117,6 +116,11 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::Run()
return false;
}
if( m_drcEngine->QueryWorstConstraint( HOLE_CLEARANCE_CONSTRAINT, worstConstraint ) )
{
m_largestClearance = std::max( m_largestClearance, worstConstraint.GetValue().Min() );
}
m_drcEpsilon = m_board->GetDesignSettings().GetDRCEpsilon();
m_zones.clear();
@ -260,15 +264,28 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testTrackAgainstItem( TRACK* track, SHA
PCB_LAYER_ID layer,
BOARD_ITEM* other )
{
if( m_drcEngine->IsErrorLimitExceeded( DRCE_CLEARANCE ) )
return false;
auto constraint = m_drcEngine->EvalRulesForItems( CLEARANCE_CONSTRAINT, track, other,
layer );
int minClearance = constraint.GetValue().Min();
bool testClearance = !m_drcEngine->IsErrorLimitExceeded( DRCE_CLEARANCE );
bool testHoles = !m_drcEngine->IsErrorLimitExceeded( DRCE_HOLE_CLEARANCE );
DRC_CONSTRAINT constraint;
int clearance;
int actual;
VECTOR2I pos;
// It would really be better to know what particular nets a nettie should allow, but for now
// it is what it is.
if( isNetTie( other ) )
testClearance = false;
BOARD_CONNECTED_ITEM* otherCItem = dynamic_cast<BOARD_CONNECTED_ITEM*>( other );
if( otherCItem && otherCItem->GetNetCode() == track->GetNetCode() )
testClearance = false;
if( testClearance )
{
constraint = m_drcEngine->EvalRulesForItems( CLEARANCE_CONSTRAINT, track, other, layer );
clearance = constraint.GetValue().Min();
accountCheck( constraint );
// Special processing for track:track intersections
@ -290,13 +307,13 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testTrackAgainstItem( TRACK* track, SHA
std::shared_ptr<SHAPE> otherShape = getShape( other, layer );
if( trackShape->Collide( otherShape.get(), minClearance - m_drcEpsilon, &actual, &pos ) )
if( trackShape->Collide( otherShape.get(), clearance - m_drcEpsilon, &actual, &pos ) )
{
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_CLEARANCE );
m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
constraint.GetName(),
MessageTextFromValue( userUnits(), minClearance ),
MessageTextFromValue( userUnits(), clearance ),
MessageTextFromValue( userUnits(), actual ) );
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
@ -308,6 +325,52 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testTrackAgainstItem( TRACK* track, SHA
if( !m_drcEngine->GetReportAllTrackErrors() )
return false;
}
}
if( testHoles && ( other->Type() == PCB_VIA_T || other->Type() == PCB_PAD_T ) )
{
std::unique_ptr<SHAPE_SEGMENT> holeShape;
if( other->Type() == PCB_VIA_T )
{
VIA* via = static_cast<VIA*>( other );
pos = via->GetPosition();
if( via->GetLayerSet().Contains( layer ) )
holeShape.reset( new SHAPE_SEGMENT( pos, pos, via->GetDrill() ) );
}
else if( other->Type() == PCB_PAD_T )
{
PAD* pad = static_cast<PAD*>( other );
if( pad->GetDrillSize().x )
holeShape.reset( new SHAPE_SEGMENT( *pad->GetEffectiveHoleShape() ) );
}
if( holeShape )
{
constraint = m_drcEngine->EvalRulesForItems( HOLE_CLEARANCE_CONSTRAINT, other, track );
clearance = constraint.GetValue().Min();
accountCheck( constraint.GetParentRule() );
if( trackShape->Collide( holeShape.get(), clearance - m_drcEpsilon, &actual, &pos ) )
{
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_HOLE_CLEARANCE );
m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
constraint.GetName(),
MessageTextFromValue( userUnits(), clearance ),
MessageTextFromValue( userUnits(), actual ) );
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
drce->SetItems( track, other );
drce->SetViolatingRule( constraint.GetParentRule() );
reportViolation( drce, (wxPoint) pos );
}
}
}
return true;
}
@ -364,8 +427,7 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testItemAgainstZones( BOARD_ITEM* aItem
}
if( zoneTree->QueryColliding( itemBBox, itemShape.get(), aLayer,
clearance - m_drcEpsilon,
&actual, &pos ) )
clearance - m_drcEpsilon, &actual, &pos ) )
{
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_CLEARANCE );
@ -408,16 +470,6 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testTrackClearances()
// Filter:
[&]( BOARD_ITEM* other ) -> bool
{
// It would really be better to know what particular nets a nettie
// should allow, but for now it is what it is.
if( isNetTie( other ) )
return false;
auto otherCItem = dynamic_cast<BOARD_CONNECTED_ITEM*>( other );
if( otherCItem && otherCItem->GetNetCode() == track->GetNetCode() )
return false;
BOARD_ITEM* a = track;
BOARD_ITEM* b = other;
@ -483,7 +535,7 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testPadAgainstItem( PAD* pad, SHAPE* pa
if( other->Type() == PCB_PAD_T )
{
auto otherPad = static_cast<PAD*>( other );
PAD* otherPad = static_cast<PAD*>( other );
// If pads are equivalent (ie: from the same footprint with the same pad number)...
if( pad->SameLogicalPadAs( otherPad ) )
@ -508,10 +560,7 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testPadAgainstItem( PAD* pad, SHAPE* pa
return true;
}
if( testHoles )
{
if( ( pad->FlashLayer( layer ) && otherPad->GetDrillSize().x )
|| ( pad->GetDrillSize().x && otherPad->FlashLayer( layer ) ) )
if( testHoles && pad->FlashLayer( layer ) && otherPad->GetDrillSize().x )
{
constraint = m_drcEngine->EvalRulesForItems( HOLE_CLEARANCE_CONSTRAINT, pad,
otherPad );
@ -519,7 +568,8 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testPadAgainstItem( PAD* pad, SHAPE* pa
accountCheck( constraint.GetParentRule() );
if( padShape->Collide( otherShape.get(), clearance - m_drcEpsilon, &actual, &pos ) )
if( padShape->Collide( otherPad->GetEffectiveHoleShape(), clearance - m_drcEpsilon,
&actual, &pos ) )
{
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_HOLE_CLEARANCE );
@ -535,6 +585,31 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testPadAgainstItem( PAD* pad, SHAPE* pa
reportViolation( drce, (wxPoint) pos );
}
}
if( testHoles && otherPad->FlashLayer( layer ) && pad->GetDrillSize().x )
{
constraint = m_drcEngine->EvalRulesForItems( HOLE_CLEARANCE_CONSTRAINT, pad,
otherPad );
clearance = constraint.GetValue().Min();
accountCheck( constraint.GetParentRule() );
if( otherShape->Collide( pad->GetEffectiveHoleShape(), clearance - m_drcEpsilon,
&actual, &pos ) )
{
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_HOLE_CLEARANCE );
m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
constraint.GetName(),
MessageTextFromValue( userUnits(), clearance ),
MessageTextFromValue( userUnits(), actual ) );
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
drce->SetItems( pad, other );
drce->SetViolatingRule( constraint.GetParentRule() );
reportViolation( drce, (wxPoint) pos );
}
}
// Pads of the same (defined) net get a waiver on clearance tests