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;
|
wxString dummy, coupledNetName;
|
||||||
|
|
||||||
if( int polarity = matchDpSuffix( refName, coupledNetName, dummy ) )
|
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 )
|
if( polarity > 0 )
|
||||||
{
|
{
|
||||||
aNetP = aNet;
|
aNetP = aNet->GetNet();
|
||||||
aNetN = net->GetNet();
|
aNetN = net->GetNet();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
aNetP = net->GetNet();
|
aNetP = net->GetNet();
|
||||||
aNetN = aNet;
|
aNetN = aNet->GetNet();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -40,6 +40,7 @@ class ZONE_CONTAINER;
|
||||||
class MARKER_PCB;
|
class MARKER_PCB;
|
||||||
class NETCLASS;
|
class NETCLASS;
|
||||||
class NETLIST;
|
class NETLIST;
|
||||||
|
class NETINFO_ITEM;
|
||||||
class PROGRESS_REPORTER;
|
class PROGRESS_REPORTER;
|
||||||
class REPORTER;
|
class REPORTER;
|
||||||
|
|
||||||
|
@ -177,7 +178,7 @@ public:
|
||||||
|
|
||||||
DRC_TEST_PROVIDER* GetTestProvider( const wxString& name ) const;
|
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:
|
private:
|
||||||
void addRule( DRC_RULE* rule )
|
void addRule( DRC_RULE* rule )
|
||||||
|
|
|
@ -278,34 +278,36 @@ bool test::DRC_TEST_PROVIDER_DIFF_PAIR_COUPLING::Run()
|
||||||
[&]( BOARD_ITEM *item ) -> bool
|
[&]( BOARD_ITEM *item ) -> bool
|
||||||
{
|
{
|
||||||
DIFF_PAIR_KEY key;
|
DIFF_PAIR_KEY key;
|
||||||
auto citem = static_cast<BOARD_CONNECTED_ITEM*>( item );
|
BOARD_CONNECTED_ITEM* citem = static_cast<BOARD_CONNECTED_ITEM*>( item );
|
||||||
int refNet = citem->GetNetCode();
|
NETINFO_ITEM* refNet = citem->GetNet();
|
||||||
|
|
||||||
if( !DRC_ENGINE::IsNetADiffPair( m_board, refNet, key.netP, key.netN ) ) // not our business
|
if( refNet && DRC_ENGINE::IsNetADiffPair( m_board, refNet, key.netP, key.netN ) )
|
||||||
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++ )
|
|
||||||
{
|
{
|
||||||
auto constraint = m_drcEngine->EvalRulesForItems( constraintsToCheck[i], item, nullptr, item->GetLayer() );
|
drc_dbg( 10, "eval dp %p\n", item );
|
||||||
|
|
||||||
if( constraint.IsNull() )
|
const DRC_CONSTRAINT_TYPE_T constraintsToCheck[] = {
|
||||||
continue;
|
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 )
|
drc_dbg( 10, "cns %d item %p\n", constraintsToCheck[i], item );
|
||||||
dpRuleMatches[key].itemsN.insert( citem );
|
|
||||||
else
|
key.parentRule = constraint.GetParentRule();
|
||||||
dpRuleMatches[key].itemsP.insert( citem );
|
|
||||||
|
if( refNet->GetNet() == key.netN )
|
||||||
|
dpRuleMatches[key].itemsN.insert( citem );
|
||||||
|
else
|
||||||
|
dpRuleMatches[key].itemsP.insert( citem );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -335,12 +335,12 @@ static void isDiffPair( LIBEVAL::CONTEXT* aCtx, void* self )
|
||||||
result->Set( 0.0 );
|
result->Set( 0.0 );
|
||||||
aCtx->Push( result );
|
aCtx->Push( result );
|
||||||
|
|
||||||
if( item->IsConnected() )
|
if( item && item->IsConnected() )
|
||||||
{
|
{
|
||||||
int net = static_cast<BOARD_CONNECTED_ITEM*>( item )->GetNetCode();
|
NETINFO_ITEM* netinfo = static_cast<BOARD_CONNECTED_ITEM*>( item )->GetNet();
|
||||||
int net_p, net_n;
|
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 );
|
result->Set( 1.0 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -374,22 +374,39 @@ int PCB_EDITOR_CONTROL::RepairBoard( const TOOL_EVENT& aEvent )
|
||||||
wxString details;
|
wxString details;
|
||||||
|
|
||||||
/*******************************
|
/*******************************
|
||||||
* Repair duplicate IDs
|
* Repair duplicate IDs and missing nets
|
||||||
*/
|
*/
|
||||||
|
|
||||||
std::set<KIID> ids;
|
std::set<KIID> ids;
|
||||||
int duplicates = 0;
|
int duplicates = 0;
|
||||||
|
|
||||||
auto processItem = [&]( EDA_ITEM* aItem )
|
auto processItem =
|
||||||
{
|
[&]( EDA_ITEM* aItem )
|
||||||
if( ids.count( aItem->m_Uuid ) )
|
{
|
||||||
{
|
if( ids.count( aItem->m_Uuid ) )
|
||||||
duplicates++;
|
{
|
||||||
const_cast<KIID&>( aItem->m_Uuid ) = KIID();
|
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
|
// Module IDs are the most important, so give them the first crack at "owning" a particular
|
||||||
// KIID.
|
// KIID.
|
||||||
|
@ -421,6 +438,9 @@ int PCB_EDITOR_CONTROL::RepairBoard( const TOOL_EVENT& aEvent )
|
||||||
|
|
||||||
for( ZONE_CONTAINER* zone : module->Zones() )
|
for( ZONE_CONTAINER* zone : module->Zones() )
|
||||||
processItem( zone );
|
processItem( zone );
|
||||||
|
|
||||||
|
for( PCB_GROUP* group : module->Groups() )
|
||||||
|
processItem( group );
|
||||||
}
|
}
|
||||||
|
|
||||||
for( BOARD_ITEM* drawing : board()->Drawings() )
|
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() )
|
for( MARKER_PCB* marker : board()->Markers() )
|
||||||
processItem( marker );
|
processItem( marker );
|
||||||
|
|
||||||
|
for( PCB_GROUP* group : board()->Groups() )
|
||||||
|
processItem( group );
|
||||||
|
|
||||||
if( duplicates )
|
if( duplicates )
|
||||||
{
|
{
|
||||||
errors += duplicates;
|
errors += duplicates;
|
||||||
|
|
Loading…
Reference in New Issue