mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-04-21 00:21:25 +00:00
Collide (and generate violations) based on a well-defined order...
... so that exclusion checking against previously-generated violations will work.
This commit is contained in:
parent
0b98706876
commit
2ae321084f
@ -92,8 +92,8 @@ private:
|
||||
* @param other item against which to test the track item
|
||||
* @return false if there is a clearance violation reported, true if there is none
|
||||
*/
|
||||
bool testSingleLayerItemAgainstItem( BOARD_CONNECTED_ITEM* item, SHAPE* itemShape,
|
||||
PCB_LAYER_ID layer, BOARD_ITEM* other );
|
||||
bool testSingleLayerItemAgainstItem( BOARD_ITEM* item, SHAPE* itemShape, PCB_LAYER_ID layer,
|
||||
BOARD_ITEM* other );
|
||||
|
||||
void testTrackClearances();
|
||||
|
||||
@ -198,7 +198,7 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::Run()
|
||||
}
|
||||
|
||||
|
||||
bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testSingleLayerItemAgainstItem( BOARD_CONNECTED_ITEM* item,
|
||||
bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testSingleLayerItemAgainstItem( BOARD_ITEM* item,
|
||||
SHAPE* itemShape,
|
||||
PCB_LAYER_ID layer,
|
||||
BOARD_ITEM* other )
|
||||
@ -211,12 +211,19 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testSingleLayerItemAgainstItem( BOARD_C
|
||||
int actual;
|
||||
VECTOR2I pos;
|
||||
bool has_error = false;
|
||||
int otherNet = 0;
|
||||
NETINFO_ITEM* net = nullptr;
|
||||
NETINFO_ITEM* otherNet = nullptr;
|
||||
|
||||
if( BOARD_CONNECTED_ITEM* connectedItem = dynamic_cast<BOARD_CONNECTED_ITEM*>( item ) )
|
||||
net = connectedItem->GetNet();
|
||||
|
||||
NETINFO_ITEM* trackNet = net;
|
||||
|
||||
if( BOARD_CONNECTED_ITEM* connectedItem = dynamic_cast<BOARD_CONNECTED_ITEM*>( other ) )
|
||||
otherNet = connectedItem->GetNetCode();
|
||||
otherNet = connectedItem->GetNet();
|
||||
|
||||
std::shared_ptr<SHAPE> otherShape = other->GetEffectiveShape( layer );
|
||||
std::shared_ptr<SHAPE> otherShapeStorage = other->GetEffectiveShape( layer );
|
||||
SHAPE* otherShape = otherShapeStorage.get();
|
||||
|
||||
if( other->Type() == PCB_PAD_T )
|
||||
{
|
||||
@ -234,6 +241,15 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testSingleLayerItemAgainstItem( BOARD_C
|
||||
|
||||
if( constraint.GetSeverity() != RPT_SEVERITY_IGNORE && clearance > 0 )
|
||||
{
|
||||
// Collide (and generate violations) based on a well-defined order so that exclusion
|
||||
// checking against previously-generated violations will work.
|
||||
if( item->m_Uuid > other->m_Uuid )
|
||||
{
|
||||
std::swap( item, other );
|
||||
std::swap( itemShape, otherShape );
|
||||
std::swap( net, otherNet );
|
||||
}
|
||||
|
||||
// Special processing for track:track intersections
|
||||
if( item->Type() == PCB_TRACE_T && other->Type() == PCB_TRACE_T )
|
||||
{
|
||||
@ -255,9 +271,9 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testSingleLayerItemAgainstItem( BOARD_C
|
||||
}
|
||||
}
|
||||
|
||||
if( itemShape->Collide( otherShape.get(), clearance - m_drcEpsilon, &actual, &pos ) )
|
||||
if( itemShape->Collide( otherShape, clearance - m_drcEpsilon, &actual, &pos ) )
|
||||
{
|
||||
if( m_drcEngine->IsNetTieExclusion( item->GetNetCode(), layer, pos, other ) )
|
||||
if( m_drcEngine->IsNetTieExclusion( trackNet->GetNetCode(), layer, pos, other ) )
|
||||
{
|
||||
// Collision occurred as track was entering a pad marked as a net-tie. We
|
||||
// allow these.
|
||||
@ -267,8 +283,7 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testSingleLayerItemAgainstItem( BOARD_C
|
||||
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_SHORTING_ITEMS );
|
||||
wxString msg;
|
||||
|
||||
msg.Printf( _( "(nets %s and %s)" ), item->GetNetname(),
|
||||
static_cast<BOARD_CONNECTED_ITEM*>( other )->GetNetname() );
|
||||
msg.Printf( _( "(nets %s and %s)" ), net->GetNetname(), otherNet->GetNetname() );
|
||||
|
||||
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + msg );
|
||||
drce->SetItems( item, other );
|
||||
@ -304,7 +319,7 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testSingleLayerItemAgainstItem( BOARD_C
|
||||
{
|
||||
std::array<BOARD_ITEM*, 2> a{ item, other };
|
||||
std::array<BOARD_ITEM*, 2> b{ other, item };
|
||||
std::array<SHAPE*, 2> a_shape{ itemShape, otherShape.get() };
|
||||
std::array<SHAPE*, 2> a_shape{ itemShape, otherShape };
|
||||
|
||||
for( size_t ii = 0; ii < 2; ++ii )
|
||||
{
|
||||
@ -316,6 +331,7 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testSingleLayerItemAgainstItem( BOARD_C
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if( b[ii]->Type() == PCB_VIA_T )
|
||||
{
|
||||
if( b[ii]->GetLayerSet().Contains( layer ) )
|
||||
|
@ -153,9 +153,22 @@ bool DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::testCourtyardClearances()
|
||||
const int progressDelta = 100;
|
||||
int ii = 0;
|
||||
|
||||
for( auto itA = m_board->Footprints().begin(); itA != m_board->Footprints().end(); itA++ )
|
||||
// Stable sorting gives stable violation generation (and stable comparisons to previously-
|
||||
// generated violations for exclusion checking).
|
||||
std::vector<FOOTPRINT*> footprints;
|
||||
|
||||
footprints.insert( footprints.begin(), m_board->Footprints().begin(),
|
||||
m_board->Footprints().end() );
|
||||
|
||||
std::sort( footprints.begin(), footprints.end(),
|
||||
[]( const FOOTPRINT* a, const FOOTPRINT* b )
|
||||
{
|
||||
return a->m_Uuid < b->m_Uuid;
|
||||
} );
|
||||
|
||||
for( auto itA = footprints.begin(); itA != footprints.end(); itA++ )
|
||||
{
|
||||
if( !reportProgress( ii++, m_board->Footprints().size(), progressDelta ) )
|
||||
if( !reportProgress( ii++, footprints.size(), progressDelta ) )
|
||||
return false; // DRC cancelled
|
||||
|
||||
// Ensure tests realted to courtyard constraints are not fully disabled:
|
||||
@ -186,7 +199,7 @@ bool DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::testCourtyardClearances()
|
||||
|
||||
BOX2I fpA_bbox = fpA->GetBoundingBox();
|
||||
|
||||
for( auto itB = itA + 1; itB != m_board->Footprints().end(); itB++ )
|
||||
for( auto itB = itA + 1; itB != footprints.end(); itB++ )
|
||||
{
|
||||
FOOTPRINT* fpB = *itB;
|
||||
const SHAPE_POLY_SET& frontB = fpB->GetCourtyard( F_CrtYd );
|
||||
|
@ -291,6 +291,11 @@ bool DRC_TEST_PROVIDER_HOLE_TO_HOLE::testHoleAgainstHole( BOARD_ITEM* aItem, SHA
|
||||
{
|
||||
if( reportCoLocation )
|
||||
{
|
||||
// Generate violations based on a well-defined order so that exclusion checking
|
||||
// against previously-generated violations will work.
|
||||
if( aItem->m_Uuid > aOther->m_Uuid )
|
||||
std::swap( aItem, aOther );
|
||||
|
||||
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_DRILLED_HOLES_COLOCATED );
|
||||
drce->SetItems( aItem, aOther );
|
||||
reportViolation( drce, aHole->GetCenter(), UNDEFINED_LAYER );
|
||||
@ -309,6 +314,11 @@ bool DRC_TEST_PROVIDER_HOLE_TO_HOLE::testHoleAgainstHole( BOARD_ITEM* aItem, SHA
|
||||
&& minClearance >= 0
|
||||
&& actual < minClearance )
|
||||
{
|
||||
// Generate violations based on a well-defined order so that exclusion checking
|
||||
// against previously-generated violations will work.
|
||||
if( aItem->m_Uuid > aOther->m_Uuid )
|
||||
std::swap( aItem, aOther );
|
||||
|
||||
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_DRILLED_HOLES_TOO_CLOSE );
|
||||
wxString msg = formatMsg( _( "(%s min %s; actual %s)" ),
|
||||
constraint.GetName(),
|
||||
|
@ -73,7 +73,7 @@ public:
|
||||
|
||||
private:
|
||||
int testItemAgainstItem( BOARD_ITEM* aItem, SHAPE* aItemShape, PCB_LAYER_ID aLayer,
|
||||
BOARD_ITEM* other );
|
||||
BOARD_ITEM* aOther );
|
||||
|
||||
void testItemAgainstZones( BOARD_ITEM* aItem, PCB_LAYER_ID aLayer );
|
||||
|
||||
@ -611,9 +611,9 @@ void DRC_TEST_PROVIDER_PHYSICAL_CLEARANCE::testZoneLayer( ZONE* aZone, PCB_LAYER
|
||||
|
||||
|
||||
int DRC_TEST_PROVIDER_PHYSICAL_CLEARANCE::testItemAgainstItem( BOARD_ITEM* aItem,
|
||||
SHAPE* aItemShape,
|
||||
PCB_LAYER_ID aLayer,
|
||||
BOARD_ITEM* other )
|
||||
SHAPE* aItemShape,
|
||||
PCB_LAYER_ID aLayer,
|
||||
BOARD_ITEM* aOther )
|
||||
{
|
||||
bool testClearance = !m_drcEngine->IsErrorLimitExceeded( DRCE_CLEARANCE );
|
||||
bool testHoles = !m_drcEngine->IsErrorLimitExceeded( DRCE_HOLE_CLEARANCE );
|
||||
@ -623,17 +623,26 @@ int DRC_TEST_PROVIDER_PHYSICAL_CLEARANCE::testItemAgainstItem( BOARD_ITEM* aItem
|
||||
int violations = 0;
|
||||
VECTOR2I pos;
|
||||
|
||||
std::shared_ptr<SHAPE> otherShape = other->GetEffectiveShape( aLayer );
|
||||
std::shared_ptr<SHAPE> otherShapeStorage = aOther->GetEffectiveShape( aLayer );
|
||||
SHAPE* otherShape = otherShapeStorage.get();
|
||||
|
||||
if( testClearance )
|
||||
{
|
||||
constraint = m_drcEngine->EvalRules( PHYSICAL_CLEARANCE_CONSTRAINT, aItem, other, aLayer );
|
||||
constraint = m_drcEngine->EvalRules( PHYSICAL_CLEARANCE_CONSTRAINT, aItem, aOther, aLayer );
|
||||
clearance = constraint.GetValue().Min();
|
||||
}
|
||||
|
||||
if( constraint.GetSeverity() != RPT_SEVERITY_IGNORE && clearance > 0 )
|
||||
{
|
||||
if( aItemShape->Collide( otherShape.get(), clearance, &actual, &pos ) )
|
||||
// Collide (and generate violations) based on a well-defined order so that exclusion
|
||||
// checking against previously-generated violations will work.
|
||||
if( aItem->m_Uuid > aOther->m_Uuid )
|
||||
{
|
||||
std::swap( aItem, aOther );
|
||||
std::swap( aItemShape, otherShape );
|
||||
}
|
||||
|
||||
if( aItemShape->Collide( otherShape, clearance, &actual, &pos ) )
|
||||
{
|
||||
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_CLEARANCE );
|
||||
wxString msg = formatMsg( _( "(%s clearance %s; actual %s)" ),
|
||||
@ -642,7 +651,7 @@ int DRC_TEST_PROVIDER_PHYSICAL_CLEARANCE::testItemAgainstItem( BOARD_ITEM* aItem
|
||||
actual );
|
||||
|
||||
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + msg );
|
||||
drce->SetItems( aItem, other );
|
||||
drce->SetItems( aItem, aOther );
|
||||
drce->SetViolatingRule( constraint.GetParentRule() );
|
||||
|
||||
reportViolation( drce, pos, aLayer );
|
||||
@ -679,9 +688,9 @@ int DRC_TEST_PROVIDER_PHYSICAL_CLEARANCE::testItemAgainstItem( BOARD_ITEM* aItem
|
||||
itemHoleShape = aItem->GetEffectiveHoleShape();
|
||||
}
|
||||
|
||||
if( other->Type() == PCB_VIA_T )
|
||||
if( aOther->Type() == PCB_VIA_T )
|
||||
{
|
||||
LSET layers = other->GetLayerSet();
|
||||
LSET layers = aOther->GetLayerSet();
|
||||
|
||||
if( layers.Contains( F_Cu ) )
|
||||
layers |= LSET::FrontBoardTechMask().set( F_CrtYd );
|
||||
@ -695,23 +704,23 @@ int DRC_TEST_PROVIDER_PHYSICAL_CLEARANCE::testItemAgainstItem( BOARD_ITEM* aItem
|
||||
wxCHECK_MSG( layers.Contains( aLayer ), violations,
|
||||
wxT( "Bug! Vias should only be checked for layers on which they exist" ) );
|
||||
|
||||
otherHoleShape = other->GetEffectiveHoleShape();
|
||||
otherHoleShape = aOther->GetEffectiveHoleShape();
|
||||
}
|
||||
else if( other->HasHole() )
|
||||
else if( aOther->HasHole() )
|
||||
{
|
||||
otherHoleShape = other->GetEffectiveHoleShape();
|
||||
otherHoleShape = aOther->GetEffectiveHoleShape();
|
||||
}
|
||||
|
||||
if( itemHoleShape || otherHoleShape )
|
||||
{
|
||||
constraint = m_drcEngine->EvalRules( PHYSICAL_HOLE_CLEARANCE_CONSTRAINT, other, aItem,
|
||||
constraint = m_drcEngine->EvalRules( PHYSICAL_HOLE_CLEARANCE_CONSTRAINT, aOther, aItem,
|
||||
aLayer );
|
||||
clearance = constraint.GetValue().Min();
|
||||
}
|
||||
|
||||
if( constraint.GetSeverity() != RPT_SEVERITY_IGNORE && clearance > 0 )
|
||||
{
|
||||
if( itemHoleShape && itemHoleShape->Collide( otherShape.get(), clearance, &actual, &pos ) )
|
||||
if( itemHoleShape && itemHoleShape->Collide( otherShape, clearance, &actual, &pos ) )
|
||||
{
|
||||
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_HOLE_CLEARANCE );
|
||||
wxString msg = formatMsg( _( "(%s clearance %s; actual %s)" ),
|
||||
@ -720,7 +729,7 @@ int DRC_TEST_PROVIDER_PHYSICAL_CLEARANCE::testItemAgainstItem( BOARD_ITEM* aItem
|
||||
actual );
|
||||
|
||||
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + msg );
|
||||
drce->SetItems( aItem, other );
|
||||
drce->SetItems( aItem, aOther );
|
||||
drce->SetViolatingRule( constraint.GetParentRule() );
|
||||
|
||||
reportViolation( drce, pos, aLayer );
|
||||
@ -736,7 +745,7 @@ int DRC_TEST_PROVIDER_PHYSICAL_CLEARANCE::testItemAgainstItem( BOARD_ITEM* aItem
|
||||
actual );
|
||||
|
||||
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + msg );
|
||||
drce->SetItems( aItem, other );
|
||||
drce->SetItems( aItem, aOther );
|
||||
drce->SetViolatingRule( constraint.GetParentRule() );
|
||||
|
||||
reportViolation( drce, pos, aLayer );
|
||||
|
@ -23,8 +23,6 @@
|
||||
|
||||
#include <common.h>
|
||||
#include <board.h>
|
||||
#include <footprint.h>
|
||||
#include <pcb_shape.h>
|
||||
#include <pcb_track.h>
|
||||
#include <geometry/shape_segment.h>
|
||||
#include <geometry/seg.h>
|
||||
@ -226,6 +224,17 @@ bool DRC_TEST_PROVIDER_SILK_CLEARANCE::Run()
|
||||
return true;
|
||||
}
|
||||
|
||||
// Collide (and generate violations) based on a well-defined order so that
|
||||
// exclusion checking against previously-generated violations will work.
|
||||
if( aLayers.first == aLayers.second )
|
||||
{
|
||||
if( refItem->m_Uuid > testItem->m_Uuid )
|
||||
{
|
||||
std::swap( refItem, testItem );
|
||||
std::swap( refShape, testShape );
|
||||
}
|
||||
}
|
||||
|
||||
if( refShape->Collide( testShape, minClearance, &actual, &pos ) )
|
||||
{
|
||||
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_OVERLAPPING_SILK );
|
||||
|
Loading…
Reference in New Issue
Block a user