Eagle SCH import: improved implicit connections resolution

Nets assigned by power pins are weak, meaning they are valid
as long as there is nothing else attached to such pins. This patch
checks whether there are other wires or pins attached to a power pin
before placing a global net label.

Fixes: lp:1755191
* https://bugs.launchpad.net/kicad/+bug/1755191
This commit is contained in:
Maciej Suminski 2018-04-12 18:10:22 +02:00
parent b766dbc7a4
commit 58c27398cb
5 changed files with 51 additions and 16 deletions

View File

@ -824,7 +824,6 @@ bool SCH_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType )
SCH_TYPE_COLLECTOR components;
auto& schLibTable = *Kiway().Prj().SchSymbolLibTable();
SCH_SCREENS allScreens;
for( SCH_SCREEN* screen = allScreens.GetFirst(); screen; screen = allScreens.GetNext() )
{
@ -846,8 +845,6 @@ bool SCH_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType )
}
// Add junction dots where necessary
cmp->Resolve( schLibTable );
cmp->UpdatePinCache();
cmp->GetConnectionPoints( pts );
for( auto i = pts.begin(); i != pts.end(); ++i )

View File

@ -1660,7 +1660,7 @@ bool SCH_COMPONENT::IsDangling() const
}
wxPoint SCH_COMPONENT::GetPinPhysicalPosition( LIB_PIN* Pin )
wxPoint SCH_COMPONENT::GetPinPhysicalPosition( const LIB_PIN* Pin ) const
{
wxCHECK_MSG( Pin != NULL && Pin->Type() == LIB_PIN_T, wxPoint( 0, 0 ),
wxT( "Cannot get physical position of pin." ) );

View File

@ -564,7 +564,7 @@ public:
*/
bool IsDangling() const override;
wxPoint GetPinPhysicalPosition( LIB_PIN* Pin );
wxPoint GetPinPhysicalPosition( const LIB_PIN* Pin ) const;
bool IsSelectStateChanged( const wxRect& aRect ) override;

View File

@ -787,13 +787,6 @@ void SCH_EAGLE_PLUGIN::loadSheet( wxXmlNode* aSheetNode, int aSheetIndex )
translation.x = translation.x - translation.x % 100;
translation.y = translation.y - translation.y % 100;
// Translate the items.
for( SCH_ITEM* item = m_currentSheet->GetScreen()->GetDrawItems(); item; item = item->Next() )
{
item->SetPosition( item->GetPosition() + translation );
item->ClearFlags();
}
// Add global net labels for the named power input pins in this sheet
for( SCH_ITEM* item = m_currentSheet->GetScreen()->GetDrawItems(); item; item = item->Next() )
{
@ -802,6 +795,15 @@ void SCH_EAGLE_PLUGIN::loadSheet( wxXmlNode* aSheetNode, int aSheetIndex )
addImplicitConnections( static_cast<SCH_COMPONENT*>( item ), m_currentSheet->GetScreen(), true );
}
m_connPoints.clear();
// Translate the items.
for( SCH_ITEM* item = m_currentSheet->GetScreen()->GetDrawItems(); item; item = item->Next() )
{
item->SetPosition( item->GetPosition() + translation );
item->ClearFlags();
}
}
@ -941,6 +943,9 @@ SCH_LINE* SCH_EAGLE_PLUGIN::loadWire( wxXmlNode* aWireNode )
wire->SetStartPoint( begin );
wire->SetEndPoint( end );
m_connPoints[begin].emplace( wire.get() );
m_connPoints[end].emplace( wire.get() );
return wire.release();
}
@ -1193,6 +1198,18 @@ void SCH_EAGLE_PLUGIN::loadInstance( wxXmlNode* aInstanceNode )
component->GetField( REFERENCE )->SetVisible( false );
}
// Save the pin positions
auto& schLibTable = *m_kiway->Prj().SchSymbolLibTable();
wxCHECK( component->Resolve( schLibTable ), /*void*/ );
component->UpdatePinCache();
std::vector<LIB_PIN*> pins;
component->GetPins( pins );
for( const auto& pin : pins )
m_connPoints[component->GetPinPhysicalPosition( pin )].emplace( pin );
component->ClearFlags();
screen->Append( component.release() );
@ -2469,11 +2486,24 @@ const SEG* SCH_EAGLE_PLUGIN::SEG_DESC::LabelAttached( const SCH_TEXT* aLabel ) c
}
// TODO could be used to place junctions, instead of IsJunctionNeeded() (see SCH_EDIT_FRAME::importFile())
bool SCH_EAGLE_PLUGIN::checkConnections( const SCH_COMPONENT* aComponent, const LIB_PIN* aPin ) const
{
wxPoint pinPosition = aComponent->GetPinPhysicalPosition( aPin );
auto pointIt = m_connPoints.find( pinPosition );
if( pointIt == m_connPoints.end() )
return false;
const auto& items = pointIt->second;
wxASSERT( items.find( aPin ) != items.end() );
return items.size() > 1;
}
void SCH_EAGLE_PLUGIN::addImplicitConnections( SCH_COMPONENT* aComponent,
SCH_SCREEN* aScreen, bool aUpdateSet )
{
auto& schLibTable = *m_kiway->Prj().SchSymbolLibTable();
wxCHECK( aComponent->Resolve( schLibTable ), /*void*/ );
aComponent->UpdatePinCache();
auto partRef = aComponent->GetPartRef().lock();
wxCHECK( partRef, /*void*/ );
@ -2494,7 +2524,10 @@ void SCH_EAGLE_PLUGIN::addImplicitConnections( SCH_COMPONENT* aComponent,
{
if( pin->GetType() == PIN_POWER_IN )
{
if( !unit || pin->GetUnit() == unit )
bool pinInUnit = !unit || pin->GetUnit() == unit; // pin belongs to the tested unit
// Create a global net label only if there are no other wires/pins attached
if( pinInUnit && !checkConnections( aComponent, pin ) )
{
// Create a net label to force the net name on the pin
SCH_GLOBALLABEL* netLabel = new SCH_GLOBALLABEL;
@ -2505,7 +2538,7 @@ void SCH_EAGLE_PLUGIN::addImplicitConnections( SCH_COMPONENT* aComponent,
aScreen->Append( netLabel );
}
else if( aUpdateSet )
else if( !pinInUnit && aUpdateSet )
{
// Found a pin creating implicit connection information in another unit.
// Such units will be instantiated if they do not appear in another sheet and

View File

@ -209,6 +209,11 @@ private:
///> Segments representing wires for intersection checking
std::vector<SEG_DESC> m_segments;
///> Positions of pins and wire endings mapped to its parent
std::map<wxPoint, std::set<const EDA_ITEM*>> m_connPoints;
///> Checks if there are other wires or pins at the position of the tested pin
bool checkConnections( const SCH_COMPONENT* aComponent, const LIB_PIN* aPin ) const;
// Structure describing missing units containing pins creating implicit connections
// (named power pins in Eagle).