Teach router about different keepout rules.
Fixes https://gitlab.com/kicad/code/kicad/issues/9786
This commit is contained in:
parent
698a668af7
commit
9547c72e73
|
@ -134,6 +134,8 @@ public:
|
|||
|
||||
BOARD_ITEM_CONTAINER* GetParent() const { return (BOARD_ITEM_CONTAINER*) m_parent; }
|
||||
|
||||
BOARD_ITEM_CONTAINER* GetParentFootprint() const;
|
||||
|
||||
/**
|
||||
* Return the primary layer this item is on.
|
||||
*/
|
||||
|
|
|
@ -176,6 +176,17 @@ std::shared_ptr<SHAPE> BOARD_ITEM::GetEffectiveShape( PCB_LAYER_ID aLayer ) cons
|
|||
}
|
||||
|
||||
|
||||
BOARD_ITEM_CONTAINER* BOARD_ITEM::GetParentFootprint() const
|
||||
{
|
||||
BOARD_ITEM_CONTAINER* ancestor = GetParent();
|
||||
|
||||
while( ancestor && ancestor->Type() == PCB_GROUP_T )
|
||||
ancestor = ancestor->GetParent();
|
||||
|
||||
return ( ancestor && ancestor->Type() == PCB_FOOTPRINT_T ) ? ancestor : nullptr;
|
||||
}
|
||||
|
||||
|
||||
void BOARD_ITEM::Rotate( const wxPoint& aRotCentre, double aAngle )
|
||||
{
|
||||
wxMessageBox( wxT( "virtual BOARD_ITEM::Rotate used, should not occur" ), GetClass() );
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <zone.h>
|
||||
#include "pns_node.h"
|
||||
#include "pns_item.h"
|
||||
#include "pns_line.h"
|
||||
|
@ -54,6 +55,39 @@ bool ITEM::collideSimple( const ITEM* aOther, const NODE* aNode, bool aDifferent
|
|||
if( !m_layers.Overlaps( aOther->m_layers ) )
|
||||
return false;
|
||||
|
||||
auto checkKeepout =
|
||||
[]( const ZONE* aKeepout, const BOARD_ITEM* aOther )
|
||||
{
|
||||
constexpr KICAD_T TRACK_TYPES[] = { PCB_ARC_T, PCB_TRACE_T, EOT };
|
||||
|
||||
if( aKeepout->GetDoNotAllowTracks() && aOther->IsType( TRACK_TYPES ) )
|
||||
return true;
|
||||
|
||||
if( aKeepout->GetDoNotAllowVias() && aOther->Type() == PCB_VIA_T )
|
||||
return true;
|
||||
|
||||
if( aKeepout->GetDoNotAllowPads() && aOther->Type() == PCB_PAD_T )
|
||||
return true;
|
||||
|
||||
// Incomplete test, but better than nothing:
|
||||
if( aKeepout->GetDoNotAllowFootprints() && aOther->Type() == PCB_PAD_T )
|
||||
{
|
||||
return !aKeepout->GetParentFootprint()
|
||||
|| aKeepout->GetParentFootprint() != aOther->GetParentFootprint();
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
const ZONE* zoneA = dynamic_cast<ZONE*>( Parent() );
|
||||
const ZONE* zoneB = dynamic_cast<ZONE*>( aOther->Parent() );
|
||||
|
||||
if( zoneA && aOther->Parent() && !checkKeepout( zoneA, aOther->Parent() ) )
|
||||
return false;
|
||||
|
||||
if( zoneB && Parent() && !checkKeepout( zoneB, Parent() ) )
|
||||
return false;
|
||||
|
||||
if( holeA || holeB )
|
||||
{
|
||||
int holeClearance = aNode->GetHoleClearance( this, aOther );
|
||||
|
|
Loading…
Reference in New Issue