DRC RTree fixes.

1) Don't collide against hidden text
2) Don't collide in both directions (a:b & b:a)
This commit is contained in:
Jeff Young 2020-11-14 16:59:34 +00:00
parent 8bae52d1c3
commit 2eb71447e4
1 changed files with 24 additions and 14 deletions

View File

@ -107,12 +107,15 @@ public:
const int mmin[2] = { bbox.GetX(), bbox.GetY() }; const int mmin[2] = { bbox.GetX(), bbox.GetY() };
const int mmax[2] = { bbox.GetRight(), bbox.GetBottom() }; const int mmax[2] = { bbox.GetRight(), bbox.GetBottom() };
m_tree[layer]->Insert( mmin, mmax, m_tree[layer]->Insert( mmin, mmax, new ITEM_WITH_SHAPE( aItem, subshape,
new ITEM_WITH_SHAPE( aItem, subshape, shape ) ); shape ) );
m_count++; m_count++;
} }
}; };
if( aItem->Type() == PCB_FP_TEXT_T && !dynamic_cast<FP_TEXT*>( aItem )->IsVisible() )
return;
if( aLayer != UNDEFINED_LAYER ) if( aLayer != UNDEFINED_LAYER )
{ {
addLayer( (PCB_LAYER_ID) aLayer ); addLayer( (PCB_LAYER_ID) aLayer );
@ -293,36 +296,36 @@ public:
}; };
int QueryCollidingPairs( DRC_RTREE* aRefTree, int QueryCollidingPairs( DRC_RTREE* aRefTree,
std::vector<LAYER_PAIR> aLayers, std::vector<LAYER_PAIR> aLayerPairs,
std::function<bool( const LAYER_PAIR&, std::function<bool( const LAYER_PAIR&,
ITEM_WITH_SHAPE*, ITEM_WITH_SHAPE*, ITEM_WITH_SHAPE*, ITEM_WITH_SHAPE*,
bool* aCollision )> aVisitor, bool* aCollision )> aVisitor,
int aMaxClearance, int aMaxClearance,
std::function<bool(int, int )> aProgressReporter ) const std::function<bool(int, int )> aProgressReporter ) const
{ {
std::vector< PAIR_INFO > pairsToVisit; std::vector<PAIR_INFO> pairsToVisit;
for( LAYER_PAIR& refLayerIter : aLayers ) for( LAYER_PAIR& layerPair : aLayerPairs )
{ {
const PCB_LAYER_ID refLayer = refLayerIter.first; const PCB_LAYER_ID refLayer = layerPair.first;
const PCB_LAYER_ID targetLayer = refLayerIter.second; const PCB_LAYER_ID targetLayer = layerPair.second;
for( ITEM_WITH_SHAPE* refItem : aRefTree->OnLayer( refLayer ) ) for( ITEM_WITH_SHAPE* refItem : aRefTree->OnLayer( refLayer ) )
{ {
BOX2I box = refItem->shape->BBox(); BOX2I box = refItem->shape->BBox();
box.Inflate( aMaxClearance ); box.Inflate( aMaxClearance );
int min[2] = { box.GetX(), box.GetY() }; int min[2] = { box.GetX(), box.GetY() };
int max[2] = { box.GetRight(), box.GetBottom() }; int max[2] = { box.GetRight(), box.GetBottom() };
auto visit = auto visit =
[&]( ITEM_WITH_SHAPE* aItemToTest ) -> bool [&]( ITEM_WITH_SHAPE* aItemToTest ) -> bool
{ {
// don't collide items against themselves // don't collide items against themselves
if( refLayer == targetLayer && aItemToTest->parent == refItem->parent ) if( aItemToTest->parent == refItem->parent )
return true; return true;
pairsToVisit.emplace_back( refLayerIter, refItem, aItemToTest ); pairsToVisit.emplace_back( layerPair, refItem, aItemToTest );
return true; return true;
}; };
@ -338,13 +341,20 @@ public:
int progress = 0; int progress = 0;
int count = pairsToVisit.size(); int count = pairsToVisit.size();
for( PAIR_INFO& pair : pairsToVisit ) for( const PAIR_INFO& pair : pairsToVisit )
{ {
if( !aProgressReporter( progress++, count ) ) if( !aProgressReporter( progress++, count ) )
break; break;
BOARD_ITEM* a = pair.refItem->parent;
BOARD_ITEM* b = pair.testItem->parent;
// store canonical order so we don't collide in both directions (a:b and b:a)
if( static_cast<void*>( a ) > static_cast<void*>( b ) )
std::swap( a, b );
// don't report multiple collisions for compound or triangulated shapes // don't report multiple collisions for compound or triangulated shapes
if( collidingCompounds.count( { pair.refItem->parent, pair.testItem->parent } ) ) if( collidingCompounds.count( { a, b } ) )
continue; continue;
bool collisionDetected = false; bool collisionDetected = false;
@ -353,7 +363,7 @@ public:
break; break;
if( collisionDetected ) if( collisionDetected )
collidingCompounds[ { pair.refItem->parent, pair.testItem->parent } ] = 1; collidingCompounds[ { a, b } ] = 1;
} }
return 0; return 0;