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>
|
#include <algorithm>
|
||||||
|
|
||||||
class SHAPE_SEGMENT : public SHAPE {
|
class SHAPE_SEGMENT : public SHAPE
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
SHAPE_SEGMENT():
|
SHAPE_SEGMENT() :
|
||||||
SHAPE( SH_SEGMENT ), m_width( 0 ) {};
|
SHAPE( SH_SEGMENT ),
|
||||||
|
m_width( 0 )
|
||||||
|
{};
|
||||||
|
|
||||||
SHAPE_SEGMENT( const VECTOR2I& aA, const VECTOR2I& aB, int aWidth = 0 ):
|
SHAPE_SEGMENT( const VECTOR2I& aA, const VECTOR2I& aB, int aWidth = 0 ) :
|
||||||
SHAPE( SH_SEGMENT ), m_seg( aA, aB ), m_width( aWidth ) {};
|
SHAPE( SH_SEGMENT ),
|
||||||
|
m_seg( aA, aB ),
|
||||||
|
m_width( aWidth )
|
||||||
|
{};
|
||||||
|
|
||||||
SHAPE_SEGMENT( const SEG& aSeg, int aWidth = 0 ):
|
SHAPE_SEGMENT( const SEG& aSeg, int aWidth = 0 ) :
|
||||||
SHAPE( SH_SEGMENT ), m_seg( aSeg ), m_width( aWidth ) {};
|
SHAPE( SH_SEGMENT ),
|
||||||
|
m_seg( aSeg ),
|
||||||
|
m_width( aWidth )
|
||||||
|
{};
|
||||||
|
|
||||||
~SHAPE_SEGMENT() {};
|
~SHAPE_SEGMENT() {};
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,6 @@
|
||||||
#include <geometry/shape_segment.h>
|
#include <geometry/shape_segment.h>
|
||||||
#include <geometry/shape_null.h>
|
#include <geometry/shape_null.h>
|
||||||
|
|
||||||
#include <drc/drc_engine.h>
|
|
||||||
#include <drc/drc_rtree.h>
|
#include <drc/drc_rtree.h>
|
||||||
#include <drc/drc_item.h>
|
#include <drc/drc_item.h>
|
||||||
#include <drc/drc_rule.h>
|
#include <drc/drc_rule.h>
|
||||||
|
@ -105,11 +104,11 @@ private:
|
||||||
bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::Run()
|
bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::Run()
|
||||||
{
|
{
|
||||||
m_board = m_drcEngine->GetBoard();
|
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
|
else
|
||||||
{
|
{
|
||||||
|
@ -117,6 +116,11 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::Run()
|
||||||
return false;
|
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_drcEpsilon = m_board->GetDesignSettings().GetDRCEpsilon();
|
||||||
|
|
||||||
m_zones.clear();
|
m_zones.clear();
|
||||||
|
@ -260,15 +264,28 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testTrackAgainstItem( TRACK* track, SHA
|
||||||
PCB_LAYER_ID layer,
|
PCB_LAYER_ID layer,
|
||||||
BOARD_ITEM* other )
|
BOARD_ITEM* other )
|
||||||
{
|
{
|
||||||
if( m_drcEngine->IsErrorLimitExceeded( DRCE_CLEARANCE ) )
|
bool testClearance = !m_drcEngine->IsErrorLimitExceeded( DRCE_CLEARANCE );
|
||||||
return false;
|
bool testHoles = !m_drcEngine->IsErrorLimitExceeded( DRCE_HOLE_CLEARANCE );
|
||||||
|
DRC_CONSTRAINT constraint;
|
||||||
auto constraint = m_drcEngine->EvalRulesForItems( CLEARANCE_CONSTRAINT, track, other,
|
int clearance;
|
||||||
layer );
|
|
||||||
int minClearance = constraint.GetValue().Min();
|
|
||||||
int actual;
|
int actual;
|
||||||
VECTOR2I pos;
|
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 );
|
accountCheck( constraint );
|
||||||
|
|
||||||
// Special processing for track:track intersections
|
// 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 );
|
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 );
|
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_CLEARANCE );
|
||||||
|
|
||||||
m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
|
m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
|
||||||
constraint.GetName(),
|
constraint.GetName(),
|
||||||
MessageTextFromValue( userUnits(), minClearance ),
|
MessageTextFromValue( userUnits(), clearance ),
|
||||||
MessageTextFromValue( userUnits(), actual ) );
|
MessageTextFromValue( userUnits(), actual ) );
|
||||||
|
|
||||||
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
|
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() )
|
if( !m_drcEngine->GetReportAllTrackErrors() )
|
||||||
return false;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -364,8 +427,7 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testItemAgainstZones( BOARD_ITEM* aItem
|
||||||
}
|
}
|
||||||
|
|
||||||
if( zoneTree->QueryColliding( itemBBox, itemShape.get(), aLayer,
|
if( zoneTree->QueryColliding( itemBBox, itemShape.get(), aLayer,
|
||||||
clearance - m_drcEpsilon,
|
clearance - m_drcEpsilon, &actual, &pos ) )
|
||||||
&actual, &pos ) )
|
|
||||||
{
|
{
|
||||||
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_CLEARANCE );
|
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_CLEARANCE );
|
||||||
|
|
||||||
|
@ -408,16 +470,6 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testTrackClearances()
|
||||||
// Filter:
|
// Filter:
|
||||||
[&]( BOARD_ITEM* other ) -> bool
|
[&]( 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* a = track;
|
||||||
BOARD_ITEM* b = other;
|
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 )
|
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 pads are equivalent (ie: from the same footprint with the same pad number)...
|
||||||
if( pad->SameLogicalPadAs( otherPad ) )
|
if( pad->SameLogicalPadAs( otherPad ) )
|
||||||
|
@ -508,10 +560,7 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testPadAgainstItem( PAD* pad, SHAPE* pa
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( testHoles )
|
if( testHoles && pad->FlashLayer( layer ) && otherPad->GetDrillSize().x )
|
||||||
{
|
|
||||||
if( ( pad->FlashLayer( layer ) && otherPad->GetDrillSize().x )
|
|
||||||
|| ( pad->GetDrillSize().x && otherPad->FlashLayer( layer ) ) )
|
|
||||||
{
|
{
|
||||||
constraint = m_drcEngine->EvalRulesForItems( HOLE_CLEARANCE_CONSTRAINT, pad,
|
constraint = m_drcEngine->EvalRulesForItems( HOLE_CLEARANCE_CONSTRAINT, pad,
|
||||||
otherPad );
|
otherPad );
|
||||||
|
@ -519,7 +568,8 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testPadAgainstItem( PAD* pad, SHAPE* pa
|
||||||
|
|
||||||
accountCheck( constraint.GetParentRule() );
|
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 );
|
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 );
|
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
|
// Pads of the same (defined) net get a waiver on clearance tests
|
||||||
|
|
Loading…
Reference in New Issue