Add keepout zones set to keepout footprints to footprint courtyard checker.
(This is for the move tool, not DRC. DRC uses more sophisticated keepout processing which is too slow for the move tool, and doesn't let us know which keepout area collided for collision highlighting.) Fixes https://gitlab.com/kicad/code/kicad/issues/12594
This commit is contained in:
parent
e9bcab07bc
commit
04fec5016b
|
@ -2162,7 +2162,7 @@ void PCB_PAINTER::draw( const FOOTPRINT* aFootprint, int aLayer )
|
|||
#endif
|
||||
}
|
||||
|
||||
if( aLayer == LAYER_CONFLICTS_SHADOW ) // happens only if locked
|
||||
if( aLayer == LAYER_CONFLICTS_SHADOW )
|
||||
{
|
||||
const SHAPE_POLY_SET& frontpoly = aFootprint->GetCourtyard( F_CrtYd );
|
||||
const SHAPE_POLY_SET& backpoly = aFootprint->GetCourtyard( B_CrtYd );
|
||||
|
@ -2251,6 +2251,18 @@ void PCB_PAINTER::draw( const PCB_GROUP* aGroup, int aLayer )
|
|||
|
||||
void PCB_PAINTER::draw( const ZONE* aZone, int aLayer )
|
||||
{
|
||||
if( aLayer == LAYER_CONFLICTS_SHADOW )
|
||||
{
|
||||
COLOR4D color = m_pcbSettings.GetColor( aZone, aLayer );
|
||||
|
||||
m_gal->SetIsFill( true );
|
||||
m_gal->SetIsStroke( false );
|
||||
m_gal->SetFillColor( color );
|
||||
|
||||
m_gal->DrawPolygon( aZone->Outline()->Outline( 0 ) );
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* aLayer will be the virtual zone layer (LAYER_ZONE_START, ... in GAL_LAYER_ID)
|
||||
* This is used for draw ordering in the GAL.
|
||||
|
|
|
@ -105,8 +105,8 @@ public:
|
|||
return wxT( "Tests footprints' courtyard clearance" );
|
||||
}
|
||||
|
||||
// The list of footprints having issues
|
||||
std::set<FOOTPRINT*> m_FpInConflict;
|
||||
// The list of items in collision
|
||||
std::set<BOARD_ITEM*> m_ItemsInConflict;
|
||||
|
||||
// The list of moved footprints
|
||||
std::vector<FOOTPRINT*> m_FpInMove;
|
||||
|
@ -163,8 +163,8 @@ void DRC_TEST_PROVIDER_COURTYARD_CLEARANCE_ON_MOVE::testCourtyardClearances()
|
|||
|
||||
if( frontA.Collide( &frontB, clearance, &actual, &pos ) )
|
||||
{
|
||||
m_FpInConflict.insert( fpA );
|
||||
m_FpInConflict.insert( fpB );
|
||||
m_ItemsInConflict.insert( fpA );
|
||||
m_ItemsInConflict.insert( fpB );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -176,11 +176,10 @@ void DRC_TEST_PROVIDER_COURTYARD_CLEARANCE_ON_MOVE::testCourtyardClearances()
|
|||
// constraint.GetValue().Min();
|
||||
clearance = 0;
|
||||
|
||||
|
||||
if( backA.Collide( &backB, clearance, &actual, &pos ) )
|
||||
{
|
||||
m_FpInConflict.insert( fpA );
|
||||
m_FpInConflict.insert( fpB );
|
||||
m_ItemsInConflict.insert( fpA );
|
||||
m_ItemsInConflict.insert( fpB );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -213,8 +212,8 @@ void DRC_TEST_PROVIDER_COURTYARD_CLEARANCE_ON_MOVE::testCourtyardClearances()
|
|||
{
|
||||
if( testPadAgainstCourtyards( padB, fpA ) )
|
||||
{
|
||||
m_FpInConflict.insert( fpA );
|
||||
m_FpInConflict.insert( fpB );
|
||||
m_ItemsInConflict.insert( fpA );
|
||||
m_ItemsInConflict.insert( fpB );
|
||||
skipNextCmp = true;
|
||||
break;
|
||||
}
|
||||
|
@ -231,8 +230,50 @@ void DRC_TEST_PROVIDER_COURTYARD_CLEARANCE_ON_MOVE::testCourtyardClearances()
|
|||
{
|
||||
if( testPadAgainstCourtyards( padA, fpB ) )
|
||||
{
|
||||
m_FpInConflict.insert( fpA );
|
||||
m_FpInConflict.insert( fpB );
|
||||
m_ItemsInConflict.insert( fpA );
|
||||
m_ItemsInConflict.insert( fpB );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for( ZONE* zone : m_board->Zones() )
|
||||
{
|
||||
if( !zone->GetIsRuleArea() || !zone->GetDoNotAllowFootprints() )
|
||||
continue;
|
||||
|
||||
bool disallowFront = ( zone->GetLayerSet() | LSET::FrontMask() ).any();
|
||||
bool disallowBack = ( zone->GetLayerSet() | LSET::BackMask() ).any();
|
||||
|
||||
for( FOOTPRINT* fp : m_FpInMove )
|
||||
{
|
||||
if( disallowFront )
|
||||
{
|
||||
const SHAPE_POLY_SET& frontCourtyard = fp->GetCourtyard( F_CrtYd );
|
||||
|
||||
if( !frontCourtyard.IsEmpty() )
|
||||
{
|
||||
if( zone->Outline()->Collide( &frontCourtyard.Outline( 0 ) ) )
|
||||
{
|
||||
m_ItemsInConflict.insert( fp );
|
||||
m_ItemsInConflict.insert( zone );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( disallowBack )
|
||||
{
|
||||
const SHAPE_POLY_SET& backCourtyard = fp->GetCourtyard( B_CrtYd );
|
||||
|
||||
if( !backCourtyard.IsEmpty() )
|
||||
{
|
||||
if( zone->Outline()->Collide( &backCourtyard.Outline( 0 ) ) )
|
||||
{
|
||||
m_ItemsInConflict.insert( fp );
|
||||
m_ItemsInConflict.insert( zone );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -257,7 +298,7 @@ void DRC_TEST_PROVIDER_COURTYARD_CLEARANCE_ON_MOVE::Init( BOARD* aBoard )
|
|||
|
||||
bool DRC_TEST_PROVIDER_COURTYARD_CLEARANCE_ON_MOVE::Run()
|
||||
{
|
||||
m_FpInConflict.clear();
|
||||
m_ItemsInConflict.clear();
|
||||
m_largestCourtyardClearance = 0;
|
||||
|
||||
DRC_CONSTRAINT constraint;
|
||||
|
@ -593,9 +634,9 @@ int EDIT_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, bool aPickReference )
|
|||
: wxT( "" ) );
|
||||
};
|
||||
|
||||
std::vector<BOARD_ITEM*> sel_items; // All the items operated on by the move below
|
||||
std::vector<BOARD_ITEM*> orig_items; // All the original items in the selection
|
||||
std::vector<FOOTPRINT*> lastFpInConflict; // last footprints with courtyard overlapping
|
||||
std::vector<BOARD_ITEM*> sel_items; // All the items operated on by the move below
|
||||
std::vector<BOARD_ITEM*> orig_items; // All the original items in the selection
|
||||
std::vector<BOARD_ITEM*> lastItemsInConflict; // last footprints with courtyard overlapping
|
||||
|
||||
for( EDA_ITEM* item : selection )
|
||||
{
|
||||
|
@ -758,25 +799,25 @@ int EDIT_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, bool aPickReference )
|
|||
// has changed
|
||||
|
||||
// Ensure the "old" conflicts are cleared
|
||||
for( FOOTPRINT* fp: lastFpInConflict )
|
||||
for( BOARD_ITEM* item: lastItemsInConflict )
|
||||
{
|
||||
fp->ClearFlags( COURTYARD_CONFLICT );
|
||||
m_toolMgr->GetView()->Update( fp );
|
||||
item->ClearFlags( COURTYARD_CONFLICT );
|
||||
m_toolMgr->GetView()->Update( item );
|
||||
need_redraw = true;
|
||||
}
|
||||
|
||||
lastFpInConflict.clear();
|
||||
lastItemsInConflict.clear();
|
||||
|
||||
for( FOOTPRINT* fp: drc_on_move.m_FpInConflict )
|
||||
for( BOARD_ITEM* item: drc_on_move.m_ItemsInConflict )
|
||||
{
|
||||
if( !fp->HasFlag( COURTYARD_CONFLICT ) )
|
||||
if( !item->HasFlag( COURTYARD_CONFLICT ) )
|
||||
{
|
||||
fp->SetFlags( COURTYARD_CONFLICT );
|
||||
m_toolMgr->GetView()->Update( fp );
|
||||
item->SetFlags( COURTYARD_CONFLICT );
|
||||
m_toolMgr->GetView()->Update( item );
|
||||
need_redraw = true;
|
||||
}
|
||||
|
||||
lastFpInConflict.push_back( fp );
|
||||
lastItemsInConflict.push_back( item );
|
||||
}
|
||||
|
||||
if( need_redraw )
|
||||
|
@ -976,10 +1017,10 @@ int EDIT_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, bool aPickReference )
|
|||
} while( ( evt = Wait() ) ); // Assignment (instead of equality test) is intentional
|
||||
|
||||
// Clear temporary COURTYARD_CONFLICT flag and ensure the conflict shadow is cleared
|
||||
for( FOOTPRINT* fp: lastFpInConflict )
|
||||
for( BOARD_ITEM* item: lastItemsInConflict )
|
||||
{
|
||||
m_toolMgr->GetView()->Update( fp );
|
||||
fp->ClearFlags( COURTYARD_CONFLICT );
|
||||
m_toolMgr->GetView()->Update( item );
|
||||
item->ClearFlags( COURTYARD_CONFLICT );
|
||||
}
|
||||
|
||||
controls->ForceCursorPosition( false );
|
||||
|
|
|
@ -221,6 +221,12 @@ bool ZONE::UnFill()
|
|||
}
|
||||
|
||||
|
||||
bool ZONE::IsConflicting() const
|
||||
{
|
||||
return HasFlag( COURTYARD_CONFLICT );
|
||||
}
|
||||
|
||||
|
||||
VECTOR2I ZONE::GetPosition() const
|
||||
{
|
||||
return GetCornerPosition( 0 );
|
||||
|
@ -289,6 +295,9 @@ void ZONE::ViewGetLayers( int aLayers[], int& aCount ) const
|
|||
aLayers[idx] = LAYER_ZONE_START + layers[idx];
|
||||
|
||||
aCount = layers.size();
|
||||
|
||||
if( IsConflicting() )
|
||||
aLayers[ aCount++ ] = LAYER_CONFLICTS_SHADOW;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -89,6 +89,12 @@ public:
|
|||
*/
|
||||
void InitDataFromSrcInCopyCtor( const ZONE& aZone );
|
||||
|
||||
/**
|
||||
* For rule areas which exclude footprints (and therefore participate in courtyard conflicts
|
||||
* during move).
|
||||
*/
|
||||
bool IsConflicting() const;
|
||||
|
||||
/**
|
||||
* @return a VECTOR2I, position of the first point of the outline
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue