From 8b45579ed0a759fa1d86d6c9695cb78338f10c1e Mon Sep 17 00:00:00 2001 From: Jon Evans Date: Thu, 7 Dec 2023 09:31:52 -0500 Subject: [PATCH] IPC-2581: Make sure components are deduplicated Fixes https://gitlab.com/kicad/code/kicad/-/issues/16287 --- pcbnew/plugins/ipc2581/ipc2581_plugin.cpp | 47 ++++++++++++++++++++--- pcbnew/plugins/ipc2581/ipc2581_plugin.h | 8 ++++ 2 files changed, 50 insertions(+), 5 deletions(-) diff --git a/pcbnew/plugins/ipc2581/ipc2581_plugin.cpp b/pcbnew/plugins/ipc2581/ipc2581_plugin.cpp index 422df2361e..f02ae45d39 100644 --- a/pcbnew/plugins/ipc2581/ipc2581_plugin.cpp +++ b/pcbnew/plugins/ipc2581/ipc2581_plugin.cpp @@ -212,6 +212,42 @@ wxString IPC2581_PLUGIN::pinName( const PAD* aPad ) const } +wxString IPC2581_PLUGIN::componentName( FOOTPRINT* aFootprint ) +{ + auto tryInsert = + [&]( const wxString& aName ) + { + if( m_footprint_refdes_dict.count( aName ) ) + { + if( m_footprint_refdes_dict.at( aName ) != aFootprint ) + return false; + } + else + { + m_footprint_refdes_dict.insert( { aName, aFootprint } ); + } + + return true; + }; + + if( m_footprint_refdes_reverse_dict.count( aFootprint ) ) + return m_footprint_refdes_reverse_dict.at( aFootprint ); + + wxString baseName = genString( aFootprint->GetReference(), "CMP" ); + wxString name = baseName; + int suffix = 1; + + while( !tryInsert( name ) ) + { + name = wxString::Format( "%s%d", name, suffix ); + } + + m_footprint_refdes_reverse_dict[aFootprint] = name; + + return name; +} + + wxString IPC2581_PLUGIN::floatVal( double aVal ) { wxString str = wxString::FromCDouble( aVal, m_sigfig ); @@ -1564,7 +1600,7 @@ void IPC2581_PLUGIN::addPad( wxXmlNode* aContentNode, const PAD* aPad, PCB_LAYER wxXmlNode* pinRefNode = appendNode( padNode, "PinRef" ); addAttribute( pinRefNode, "pin", pinName( aPad ) ); - addAttribute( pinRefNode, "componentRef", genString( fp->GetReference(), "CMP" ) ); + addAttribute( pinRefNode, "componentRef", componentName( fp ) ); } } @@ -2147,7 +2183,7 @@ void IPC2581_PLUGIN::generateComponents( wxXmlNode* aStepNode ) for( FOOTPRINT* fp : m_board->Footprints() ) { wxXmlNode* componentNode = new wxXmlNode( wxXML_ELEMENT_NODE, "Component" ); - addAttribute( componentNode, "refDes", genString( fp->GetReference(), "CMP" ) ); + addAttribute( componentNode, "refDes", componentName( fp ) ); wxXmlNode* pkg = addPackage( componentNode, fp ); if( pkg ) @@ -2530,7 +2566,8 @@ void IPC2581_PLUGIN::generateLayerSetNet( wxXmlNode* aLayerNode, PCB_LAYER_ID aL if( FOOTPRINT* fp = zone->GetParentFootprint() ) { wxXmlNode* tempSetNode = appendNode( aLayerNode, "Set" ); - addAttribute( tempSetNode, "componentRef", genString( fp->GetReference(), "CMP" ) ); + wxString refDes = componentName( zone->GetParentFootprint() ); + addAttribute( tempSetNode, "componentRef", refDes ); wxXmlNode* newFeatures = appendNode( tempSetNode, "Features" ); addLocationNode( newFeatures, 0.0, 0.0 ); zoneFeatureNode = appendNode( newFeatures, "UserSpecial" ); @@ -2554,7 +2591,7 @@ void IPC2581_PLUGIN::generateLayerSetNet( wxXmlNode* aLayerNode, PCB_LAYER_ID aL if( m_version > 'B' ) addAttribute( tempSetNode, "geometryUsage", "GRAPHIC" ); - addAttribute( tempSetNode, "componentRef", genString( fp->GetReference(), "CMP" ) ); + addAttribute( tempSetNode, "componentRef", componentName( fp ) ); wxXmlNode* tempFeature = appendNode( tempSetNode, "Features" ); addLocationNode( tempFeature, *shape ); @@ -2597,7 +2634,7 @@ void IPC2581_PLUGIN::generateLayerSetNet( wxXmlNode* aLayerNode, PCB_LAYER_ID aL addAttribute( tempSetNode, "geometryUsage", "TEXT" ); if( fp ) - addAttribute( tempSetNode, "componentRef", genString( fp->GetReference(), "CMP" ) ); + addAttribute( tempSetNode, "componentRef", componentName( fp ) ); wxXmlNode* nonStandardAttributeNode = appendNode( tempSetNode, "NonstandardAttribute" ); addAttribute( nonStandardAttributeNode, "name", "TEXT" ); diff --git a/pcbnew/plugins/ipc2581/ipc2581_plugin.h b/pcbnew/plugins/ipc2581/ipc2581_plugin.h index 7dfd8692f4..a58345398e 100644 --- a/pcbnew/plugins/ipc2581/ipc2581_plugin.h +++ b/pcbnew/plugins/ipc2581/ipc2581_plugin.h @@ -262,6 +262,8 @@ private: wxString pinName( const PAD* aPad ) const; + wxString componentName( FOOTPRINT* aFootprint ); + void addXY( wxXmlNode* aNode, const VECTOR2I& aVec, const char* aXName = nullptr, const char* aYName = nullptr ); @@ -318,6 +320,12 @@ private: std::map m_footprint_dict; //_##) + std::map + m_footprint_refdes_dict; // + m_footprint_refdes_reverse_dict; // m_OEMRef_dict; //