Defensive code against missing nets.
Also adds net re-parenting code to Repair Board. Fixes https://gitlab.com/kicad/code/kicad/issues/5935
This commit is contained in:
parent
527d5f1290
commit
fdeb340d21
|
@ -837,9 +837,9 @@ static int matchDpSuffix( const wxString& aNetName, wxString& aComplementNet,
|
|||
}
|
||||
|
||||
|
||||
int DRC_ENGINE::IsNetADiffPair( BOARD* aBoard, int aNet, int& aNetP, int& aNetN )
|
||||
int DRC_ENGINE::IsNetADiffPair( BOARD* aBoard, NETINFO_ITEM* aNet, int& aNetP, int& aNetN )
|
||||
{
|
||||
wxString refName = aBoard->FindNet( aNet )->GetNetname();
|
||||
wxString refName = aNet->GetNetname();
|
||||
wxString dummy, coupledNetName;
|
||||
|
||||
if( int polarity = matchDpSuffix( refName, coupledNetName, dummy ) )
|
||||
|
@ -851,13 +851,13 @@ int DRC_ENGINE::IsNetADiffPair( BOARD* aBoard, int aNet, int& aNetP, int& aNetN
|
|||
|
||||
if( polarity > 0 )
|
||||
{
|
||||
aNetP = aNet;
|
||||
aNetP = aNet->GetNet();
|
||||
aNetN = net->GetNet();
|
||||
}
|
||||
else
|
||||
{
|
||||
aNetP = net->GetNet();
|
||||
aNetN = aNet;
|
||||
aNetN = aNet->GetNet();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
@ -40,6 +40,7 @@ class ZONE_CONTAINER;
|
|||
class MARKER_PCB;
|
||||
class NETCLASS;
|
||||
class NETLIST;
|
||||
class NETINFO_ITEM;
|
||||
class PROGRESS_REPORTER;
|
||||
class REPORTER;
|
||||
|
||||
|
@ -177,7 +178,7 @@ public:
|
|||
|
||||
DRC_TEST_PROVIDER* GetTestProvider( const wxString& name ) const;
|
||||
|
||||
static int IsNetADiffPair( BOARD* aBoard, int aNet, int& aNetP, int& aNetN );
|
||||
static int IsNetADiffPair( BOARD* aBoard, NETINFO_ITEM* aNet, int& aNetP, int& aNetN );
|
||||
|
||||
private:
|
||||
void addRule( DRC_RULE* rule )
|
||||
|
|
|
@ -278,34 +278,36 @@ bool test::DRC_TEST_PROVIDER_DIFF_PAIR_COUPLING::Run()
|
|||
[&]( BOARD_ITEM *item ) -> bool
|
||||
{
|
||||
DIFF_PAIR_KEY key;
|
||||
auto citem = static_cast<BOARD_CONNECTED_ITEM*>( item );
|
||||
int refNet = citem->GetNetCode();
|
||||
BOARD_CONNECTED_ITEM* citem = static_cast<BOARD_CONNECTED_ITEM*>( item );
|
||||
NETINFO_ITEM* refNet = citem->GetNet();
|
||||
|
||||
if( !DRC_ENGINE::IsNetADiffPair( m_board, refNet, key.netP, key.netN ) ) // not our business
|
||||
return true;
|
||||
|
||||
drc_dbg(10, "eval dp %p\n", item );
|
||||
|
||||
const DRC_CONSTRAINT_TYPE_T constraintsToCheck[] = {
|
||||
DRC_CONSTRAINT_TYPE_DIFF_PAIR_GAP,
|
||||
DRC_CONSTRAINT_TYPE_DIFF_PAIR_MAX_UNCOUPLED
|
||||
};
|
||||
|
||||
for( int i = 0; i < 2; i++ )
|
||||
if( refNet && DRC_ENGINE::IsNetADiffPair( m_board, refNet, key.netP, key.netN ) )
|
||||
{
|
||||
auto constraint = m_drcEngine->EvalRulesForItems( constraintsToCheck[i], item, nullptr, item->GetLayer() );
|
||||
drc_dbg( 10, "eval dp %p\n", item );
|
||||
|
||||
if( constraint.IsNull() )
|
||||
continue;
|
||||
const DRC_CONSTRAINT_TYPE_T constraintsToCheck[] = {
|
||||
DRC_CONSTRAINT_TYPE_DIFF_PAIR_GAP,
|
||||
DRC_CONSTRAINT_TYPE_DIFF_PAIR_MAX_UNCOUPLED
|
||||
};
|
||||
|
||||
drc_dbg(10, "cns %d item %p\n", constraintsToCheck[i], item );
|
||||
for( int i = 0; i < 2; i++ )
|
||||
{
|
||||
auto constraint = m_drcEngine->EvalRulesForItems( constraintsToCheck[i],
|
||||
item, nullptr,
|
||||
item->GetLayer() );
|
||||
|
||||
key.parentRule = constraint.GetParentRule();
|
||||
if( constraint.IsNull() )
|
||||
continue;
|
||||
|
||||
if( refNet == key.netN )
|
||||
dpRuleMatches[key].itemsN.insert( citem );
|
||||
else
|
||||
dpRuleMatches[key].itemsP.insert( citem );
|
||||
drc_dbg( 10, "cns %d item %p\n", constraintsToCheck[i], item );
|
||||
|
||||
key.parentRule = constraint.GetParentRule();
|
||||
|
||||
if( refNet->GetNet() == key.netN )
|
||||
dpRuleMatches[key].itemsN.insert( citem );
|
||||
else
|
||||
dpRuleMatches[key].itemsP.insert( citem );
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
@ -335,12 +335,12 @@ static void isDiffPair( LIBEVAL::CONTEXT* aCtx, void* self )
|
|||
result->Set( 0.0 );
|
||||
aCtx->Push( result );
|
||||
|
||||
if( item->IsConnected() )
|
||||
if( item && item->IsConnected() )
|
||||
{
|
||||
int net = static_cast<BOARD_CONNECTED_ITEM*>( item )->GetNetCode();
|
||||
int net_p, net_n;
|
||||
NETINFO_ITEM* netinfo = static_cast<BOARD_CONNECTED_ITEM*>( item )->GetNet();
|
||||
int dummy_p, dummy_n;
|
||||
|
||||
if( DRC_ENGINE::IsNetADiffPair( item->GetBoard(), net, net_p, net_n ) )
|
||||
if( netinfo && DRC_ENGINE::IsNetADiffPair( item->GetBoard(), netinfo, dummy_p, dummy_n ) )
|
||||
result->Set( 1.0 );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -374,22 +374,39 @@ int PCB_EDITOR_CONTROL::RepairBoard( const TOOL_EVENT& aEvent )
|
|||
wxString details;
|
||||
|
||||
/*******************************
|
||||
* Repair duplicate IDs
|
||||
* Repair duplicate IDs and missing nets
|
||||
*/
|
||||
|
||||
std::set<KIID> ids;
|
||||
int duplicates = 0;
|
||||
|
||||
auto processItem = [&]( EDA_ITEM* aItem )
|
||||
{
|
||||
if( ids.count( aItem->m_Uuid ) )
|
||||
{
|
||||
duplicates++;
|
||||
const_cast<KIID&>( aItem->m_Uuid ) = KIID();
|
||||
}
|
||||
auto processItem =
|
||||
[&]( EDA_ITEM* aItem )
|
||||
{
|
||||
if( ids.count( aItem->m_Uuid ) )
|
||||
{
|
||||
duplicates++;
|
||||
const_cast<KIID&>( aItem->m_Uuid ) = KIID();
|
||||
}
|
||||
|
||||
ids.insert( aItem->m_Uuid );
|
||||
};
|
||||
ids.insert( aItem->m_Uuid );
|
||||
|
||||
BOARD_CONNECTED_ITEM* cItem = dynamic_cast<BOARD_CONNECTED_ITEM*>( aItem );
|
||||
|
||||
if( cItem && cItem->GetNetCode() )
|
||||
{
|
||||
NETINFO_ITEM* netinfo = cItem->GetNet();
|
||||
|
||||
if( netinfo && !board()->FindNet( netinfo->GetNetname() ) )
|
||||
{
|
||||
board()->Add( netinfo );
|
||||
|
||||
details += wxString::Format( _( "Orphaned net %s re-parented.\n" ),
|
||||
netinfo->GetNetname() );
|
||||
errors++;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Module IDs are the most important, so give them the first crack at "owning" a particular
|
||||
// KIID.
|
||||
|
@ -421,6 +438,9 @@ int PCB_EDITOR_CONTROL::RepairBoard( const TOOL_EVENT& aEvent )
|
|||
|
||||
for( ZONE_CONTAINER* zone : module->Zones() )
|
||||
processItem( zone );
|
||||
|
||||
for( PCB_GROUP* group : module->Groups() )
|
||||
processItem( group );
|
||||
}
|
||||
|
||||
for( BOARD_ITEM* drawing : board()->Drawings() )
|
||||
|
@ -432,6 +452,9 @@ int PCB_EDITOR_CONTROL::RepairBoard( const TOOL_EVENT& aEvent )
|
|||
for( MARKER_PCB* marker : board()->Markers() )
|
||||
processItem( marker );
|
||||
|
||||
for( PCB_GROUP* group : board()->Groups() )
|
||||
processItem( group );
|
||||
|
||||
if( duplicates )
|
||||
{
|
||||
errors += duplicates;
|
||||
|
|
Loading…
Reference in New Issue