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:
parent
0d57f90982
commit
af2219ba7f
|
@ -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() {};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue