Fetch a better location for keepout area collsions.

Fixes https://gitlab.com/kicad/code/kicad/issues/13220
This commit is contained in:
Jeff Young 2022-12-21 18:20:04 +00:00
parent e8f755c665
commit e28f6ecc00
5 changed files with 38 additions and 10 deletions

View File

@ -101,13 +101,17 @@ KIID::KIID()
} }
KIID::KIID( int null ) : m_uuid( nilGenerator() ), m_cached_timestamp( 0 ) KIID::KIID( int null ) :
m_uuid( nilGenerator() ),
m_cached_timestamp( 0 )
{ {
wxASSERT( null == 0 ); wxASSERT( null == 0 );
} }
KIID::KIID( const std::string& aString ) : m_uuid(), m_cached_timestamp( 0 ) KIID::KIID( const std::string& aString ) :
m_uuid(),
m_cached_timestamp( 0 )
{ {
if( aString.length() == 8 if( aString.length() == 8
&& std::all_of( aString.begin(), aString.end(), && std::all_of( aString.begin(), aString.end(),
@ -160,12 +164,14 @@ KIID::KIID( const std::string& aString ) : m_uuid(), m_cached_timestamp( 0 )
} }
KIID::KIID( const char* aString ) : KIID( std::string( aString ) ) KIID::KIID( const char* aString ) :
KIID( std::string( aString ) )
{ {
} }
KIID::KIID( const wxString& aString ) : KIID( std::string( aString.ToUTF8() ) ) KIID::KIID( const wxString& aString ) :
KIID( std::string( aString.ToUTF8() ) )
{ {
} }

View File

@ -423,7 +423,9 @@ void DRC_ENGINE::loadImplicitRules()
else else
rule = createImplicitRule( wxString::Format( _( "keepout area '%s'" ), name ) ); rule = createImplicitRule( wxString::Format( _( "keepout area '%s'" ), name ) );
rule->m_Condition = new DRC_RULE_CONDITION( wxString::Format( wxT( "A.insideArea('%s')" ), rule->m_ImplicitItemId = zone->m_Uuid;
rule->m_Condition = new DRC_RULE_CONDITION( wxString::Format( wxT( "A.intersectsArea('%s')" ),
zone->m_Uuid.AsString() ) ); zone->m_Uuid.AsString() ) );
rule->m_LayerCondition = zone->GetLayerSet(); rule->m_LayerCondition = zone->GetLayerSet();

View File

@ -31,6 +31,7 @@
DRC_RULE::DRC_RULE() : DRC_RULE::DRC_RULE() :
m_Unary( false ), m_Unary( false ),
m_Implicit( false ), m_Implicit( false ),
m_ImplicitItemId( 0 ),
m_LayerCondition( LSET::AllLayersMask() ), m_LayerCondition( LSET::AllLayersMask() ),
m_Condition( nullptr ), m_Condition( nullptr ),
m_Severity( RPT_SEVERITY_UNDEFINED ) m_Severity( RPT_SEVERITY_UNDEFINED )
@ -41,6 +42,7 @@ DRC_RULE::DRC_RULE() :
DRC_RULE::DRC_RULE( const wxString& aName ) : DRC_RULE::DRC_RULE( const wxString& aName ) :
m_Unary( false ), m_Unary( false ),
m_Implicit( false ), m_Implicit( false ),
m_ImplicitItemId( 0 ),
m_Name( aName ), m_Name( aName ),
m_LayerCondition( LSET::AllLayersMask() ), m_LayerCondition( LSET::AllLayersMask() ),
m_Condition( nullptr ), m_Condition( nullptr ),

View File

@ -24,6 +24,7 @@
#ifndef DRC_RULE_PROTO_H #ifndef DRC_RULE_PROTO_H
#define DRC_RULE_PROTO_H #define DRC_RULE_PROTO_H
#include <kiid.h>
#include <core/typeinfo.h> #include <core/typeinfo.h>
#include <optional> #include <optional>
#include <core/minoptmax.h> #include <core/minoptmax.h>
@ -107,6 +108,7 @@ public:
public: public:
bool m_Unary; bool m_Unary;
bool m_Implicit; bool m_Implicit;
KIID m_ImplicitItemId;
wxString m_Name; wxString m_Name;
wxString m_LayerSource; wxString m_LayerSource;
LSET m_LayerCondition; LSET m_LayerCondition;

View File

@ -214,20 +214,36 @@ bool DRC_TEST_PROVIDER_DISALLOW::Run()
if( constraint.m_DisallowFlags && constraint.GetSeverity() != RPT_SEVERITY_IGNORE ) if( constraint.m_DisallowFlags && constraint.GetSeverity() != RPT_SEVERITY_IGNORE )
{ {
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_ALLOWED_ITEMS ); std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_ALLOWED_ITEMS );
DRC_RULE* rule = constraint.GetParentRule();
VECTOR2I pos = item->GetPosition();
PCB_LAYER_ID layer = UNDEFINED_LAYER;
wxString msg; wxString msg;
msg.Printf( drcItem->GetErrorText() + wxS( " (%s)" ), constraint.GetName() ); msg.Printf( drcItem->GetErrorText() + wxS( " (%s)" ), constraint.GetName() );
drcItem->SetErrorMessage( msg ); drcItem->SetErrorMessage( msg );
drcItem->SetItems( item ); drcItem->SetItems( item );
drcItem->SetViolatingRule( constraint.GetParentRule() ); drcItem->SetViolatingRule( rule );
PCB_LAYER_ID layer = UNDEFINED_LAYER;
if( item->GetLayerSet().count() ) if( item->GetLayerSet().count() )
layer = item->GetLayerSet().Seq().front(); layer = item->GetLayerSet().Seq().front();
reportViolation( drcItem, item->GetPosition(), layer ); if( rule->m_Implicit )
{
// Provide a better location for keepout area collisions.
BOARD_ITEM* ruleItem = board->GetItem( rule->m_ImplicitItemId );
if( ZONE* keepout = dynamic_cast<ZONE*>( ruleItem ) )
{
std::shared_ptr<SHAPE> shape = item->GetEffectiveShape( layer );
int dummyActual;
keepout->Outline()->Collide( shape.get(), board->m_DRCMaxClearance,
&dummyActual, &pos );
}
}
reportViolation( drcItem, pos, layer );
} }
}; };