Fix multiple filter calls that were producing false cache positives.

When processing a compound shape we'd decide the first of them didn't
collide and then put false into the cache.  The cache value would then
be used for all the other shapes in the compound shape, which very well
might actually collide.

Fixes https://gitlab.com/kicad/code/kicad/issues/8003
This commit is contained in:
Jeff Young 2021-03-23 21:03:59 +00:00
parent a94a481574
commit a94ce75c02
1 changed files with 26 additions and 9 deletions

View File

@ -199,6 +199,10 @@ public:
// means we have a hit)
std::unordered_set<BOARD_ITEM*> collidingCompounds;
// keep track of results of client filter so we don't ask more than once for compound
// shapes
std::map<BOARD_ITEM*, bool> filterResults;
EDA_RECT box = aRefItem->GetBoundingBox();
box.Inflate( aClearance );
@ -218,16 +222,29 @@ public:
if( collidingCompounds.find( aItem->parent ) != collidingCompounds.end() )
return true;
if( !aFilter || aFilter( aItem->parent ) )
{
if( refShape->Collide( aItem->shape, aClearance ) )
{
collidingCompounds.insert( aItem->parent );
count++;
bool filtered;
auto it = filterResults.find( aItem->parent );
if( aVisitor )
return aVisitor( aItem->parent );
}
if( it == filterResults.end() )
{
filtered = aFilter && !aFilter( aItem->parent );
filterResults[ aItem->parent ] = filtered;
}
else
{
filtered = it->second;
}
if( filtered )
return true;
if( refShape->Collide( aItem->shape, aClearance ) )
{
collidingCompounds.insert( aItem->parent );
count++;
if( aVisitor )
return aVisitor( aItem->parent );
}
return true;