Fix missing DRC via/track check
Depending on pointer ordering, the via/track clearance check might not
run as we were only checking when the first element was a track not via.
Re-written version of 0150655ed3
for v6
This commit is contained in:
parent
a35b89258a
commit
c45aa734b0
|
@ -268,6 +268,8 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testTrackAgainstItem( PCB_TRACK* track,
|
||||||
int actual;
|
int actual;
|
||||||
VECTOR2I pos;
|
VECTOR2I pos;
|
||||||
|
|
||||||
|
std::shared_ptr<SHAPE> otherShape = DRC_ENGINE::GetShape( other, layer );
|
||||||
|
|
||||||
if( other->Type() == PCB_PAD_T )
|
if( other->Type() == PCB_PAD_T )
|
||||||
{
|
{
|
||||||
PAD* pad = static_cast<PAD*>( other );
|
PAD* pad = static_cast<PAD*>( other );
|
||||||
|
@ -302,8 +304,6 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testTrackAgainstItem( PCB_TRACK* track,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<SHAPE> otherShape = DRC_ENGINE::GetShape( other, layer );
|
|
||||||
|
|
||||||
if( trackShape->Collide( otherShape.get(), clearance - 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 );
|
||||||
|
@ -325,52 +325,71 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testTrackAgainstItem( PCB_TRACK* track,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( testHoles && ( other->Type() == PCB_VIA_T || other->Type() == PCB_PAD_T ) )
|
if( testHoles )
|
||||||
{
|
{
|
||||||
std::unique_ptr<SHAPE_SEGMENT> holeShape;
|
std::array<BOARD_ITEM*, 2> a{ track, other };
|
||||||
|
std::array<BOARD_ITEM*, 2> b{ other, track };
|
||||||
|
std::array<SHAPE*, 2> a_shape{ trackShape, otherShape.get() };
|
||||||
|
|
||||||
if( other->Type() == PCB_VIA_T )
|
bool has_error = false;
|
||||||
|
|
||||||
|
for( size_t ii = 0; ii < 2 && !has_error; ++ii )
|
||||||
{
|
{
|
||||||
PCB_VIA* via = static_cast<PCB_VIA*>( other );
|
std::unique_ptr<SHAPE_SEGMENT> holeShape;
|
||||||
pos = via->GetPosition();
|
|
||||||
|
|
||||||
if( via->GetLayerSet().Contains( layer ) )
|
bool has_hole = b[ii]->Type() == PCB_VIA_T ||
|
||||||
holeShape.reset( new SHAPE_SEGMENT( pos, pos, via->GetDrill() ) );
|
( b[ii]->Type() == PCB_PAD_T && static_cast<PAD*>( b[ii] )->GetDrillSize().x );
|
||||||
}
|
|
||||||
else if( other->Type() == PCB_PAD_T )
|
|
||||||
{
|
|
||||||
PAD* pad = static_cast<PAD*>( other );
|
|
||||||
|
|
||||||
if( pad->GetDrillSize().x )
|
// We only test a track item here against an item with a hole.
|
||||||
holeShape.reset( new SHAPE_SEGMENT( *pad->GetEffectiveHoleShape() ) );
|
// If either case is not valid, simply move on
|
||||||
}
|
if( !( dynamic_cast<PCB_TRACK*>( a[ii] ) ) || !has_hole )
|
||||||
|
|
||||||
if( holeShape )
|
|
||||||
{
|
|
||||||
constraint = m_drcEngine->EvalRules( HOLE_CLEARANCE_CONSTRAINT, other, track, layer );
|
|
||||||
clearance = constraint.GetValue().Min();
|
|
||||||
|
|
||||||
if( clearance > 0 && trackShape->Collide( holeShape.get(),
|
|
||||||
std::max( 0, clearance - m_drcEpsilon ),
|
|
||||||
&actual, &pos ) )
|
|
||||||
{
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if( b[ii]->Type() == PCB_VIA_T )
|
||||||
|
{
|
||||||
|
PCB_VIA* via = static_cast<PCB_VIA*>( b[ii] );
|
||||||
|
pos = via->GetPosition();
|
||||||
|
|
||||||
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_HOLE_CLEARANCE );
|
if( via->GetLayerSet().Contains( layer ) )
|
||||||
wxString msg;
|
holeShape.reset( new SHAPE_SEGMENT( pos, pos, via->GetDrill() ) );
|
||||||
|
}
|
||||||
|
else if( b[ii]->Type() == PCB_PAD_T )
|
||||||
|
{
|
||||||
|
PAD* pad = static_cast<PAD*>( b[ii] );
|
||||||
|
|
||||||
msg.Printf( _( "(%s clearance %s; actual %s)" ),
|
if( pad->GetDrillSize().x )
|
||||||
constraint.GetName(),
|
holeShape.reset( new SHAPE_SEGMENT( *pad->GetEffectiveHoleShape() ) );
|
||||||
MessageTextFromValue( userUnits(), clearance ),
|
}
|
||||||
MessageTextFromValue( userUnits(), actual ) );
|
|
||||||
|
|
||||||
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + msg );
|
if( holeShape )
|
||||||
drce->SetItems( track, other );
|
{
|
||||||
drce->SetViolatingRule( constraint.GetParentRule() );
|
constraint = m_drcEngine->EvalRules( HOLE_CLEARANCE_CONSTRAINT, b[ii], a[ii], layer );
|
||||||
|
clearance = constraint.GetValue().Min();
|
||||||
|
|
||||||
reportViolation( drce, (wxPoint) pos );
|
if( clearance > 0 && a_shape[ii]->Collide( holeShape.get(),
|
||||||
|
std::max( 0, clearance - m_drcEpsilon ),
|
||||||
|
&actual, &pos ) )
|
||||||
|
{
|
||||||
|
|
||||||
if( !m_drcEngine->GetReportAllTrackErrors() )
|
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_HOLE_CLEARANCE );
|
||||||
return false;
|
wxString msg;
|
||||||
|
|
||||||
|
msg.Printf( _( "(%s clearance %s; actual %s)" ),
|
||||||
|
constraint.GetName(),
|
||||||
|
MessageTextFromValue( userUnits(), clearance ),
|
||||||
|
MessageTextFromValue( userUnits(), actual ) );
|
||||||
|
|
||||||
|
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + msg );
|
||||||
|
drce->SetItems( a[ii], b[ii] );
|
||||||
|
drce->SetViolatingRule( constraint.GetParentRule() );
|
||||||
|
|
||||||
|
reportViolation( drce, (wxPoint) pos );
|
||||||
|
has_error = true;
|
||||||
|
|
||||||
|
if( !m_drcEngine->GetReportAllTrackErrors() )
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue