From 53d90431eaea2018d62169b98a9a81daf39a31b3 Mon Sep 17 00:00:00 2001 From: Thomas Pointhuber Date: Fri, 9 Oct 2020 16:23:07 +0200 Subject: [PATCH] altium: correctly parse pins TODO: for now, we assume the component is not rotated, simply because this would require me to write quite a bit of helper methods to handle all those different rotation cases ;) --- .../sch_plugins/altium/altium_parser_sch.cpp | 24 +++- .../sch_plugins/altium/altium_parser_sch.h | 52 ++++++++- .../sch_plugins/altium/sch_altium_plugin.cpp | 108 ++++++++++++++++-- 3 files changed, 171 insertions(+), 13 deletions(-) diff --git a/eeschema/sch_plugins/altium/altium_parser_sch.cpp b/eeschema/sch_plugins/altium/altium_parser_sch.cpp index 2045f10363..c7afd2f09f 100644 --- a/eeschema/sch_plugins/altium/altium_parser_sch.cpp +++ b/eeschema/sch_plugins/altium/altium_parser_sch.cpp @@ -74,14 +74,36 @@ ASCH_PIN::ASCH_PIN( const std::map& aProperties ) text = ALTIUM_PARSER::PropertiesReadString( aProperties, "TEXT", "" ); designator = ALTIUM_PARSER::PropertiesReadString( aProperties, "DESIGNATOR", "" ); + int symbolOuterEdgeInt = ALTIUM_PARSER::PropertiesReadInt( aProperties, "SYMBOL_OUTEREDGE", 0 ); + symbolOuterEdge = ( symbolOuterEdgeInt >= 0 && symbolOuterEdgeInt <= 1 ) ? + static_cast( symbolOuterEdgeInt ) : + ASCH_PIN_SYMBOL_OUTEREDGE::UNKNOWN; + + int symbolInnerEdgeInt = ALTIUM_PARSER::PropertiesReadInt( aProperties, "SYMBOL_INNEREDGE", 0 ); + symbolInnerEdge = ( symbolInnerEdgeInt == 0 || symbolInnerEdgeInt == 3 ) ? + static_cast( symbolInnerEdgeInt ) : + ASCH_PIN_SYMBOL_INNEREDGE::UNKNOWN; + + int electricalInt = ALTIUM_PARSER::PropertiesReadInt( aProperties, "ELECTRICAL", 0 ); + electrical = ( electricalInt >= 0 && electricalInt <= 7 ) ? + static_cast( electricalInt ) : + ASCH_PIN_ELECTRICAL::UNKNOWN; + int pinconglomerate = ALTIUM_PARSER::PropertiesReadInt( aProperties, "PINCONGLOMERATE", 0 ); - orientation = pinconglomerate & 0x03; + + orientation = static_cast( pinconglomerate & 0x03 ); + showPinName = ( pinconglomerate & 0x08 ) != 0; + showDesignator = ( pinconglomerate & 0x10 ) != 0; int x = ALTIUM_PARSER::PropertiesReadInt( aProperties, "LOCATION.X", 0 ); int xfrac = ALTIUM_PARSER::PropertiesReadInt( aProperties, "LOCATION.X_FRAC", 0 ); int y = ALTIUM_PARSER::PropertiesReadInt( aProperties, "LOCATION.Y", 0 ); int yfrac = ALTIUM_PARSER::PropertiesReadInt( aProperties, "LOCATION.Y_FRAC", 0 ); location = wxPoint( Altium2KiCadUnit( x, xfrac ), -Altium2KiCadUnit( y, yfrac ) ); + + int p = ALTIUM_PARSER::PropertiesReadInt( aProperties, "PINLENGTH", 0 ); + int pfrac = ALTIUM_PARSER::PropertiesReadInt( aProperties, "PINLENGTH_FRAC", 0 ); + pinlength = Altium2KiCadUnit( p, pfrac ); } diff --git a/eeschema/sch_plugins/altium/altium_parser_sch.h b/eeschema/sch_plugins/altium/altium_parser_sch.h index 71cc26fc1f..9ecf12a430 100644 --- a/eeschema/sch_plugins/altium/altium_parser_sch.h +++ b/eeschema/sch_plugins/altium/altium_parser_sch.h @@ -32,7 +32,6 @@ // this constant specifies a item which is not inside an component const int ALTIUM_COMPONENT_NONE = -1; - enum class ALTIUM_SCH_RECORD { HEADER = 0, @@ -94,6 +93,46 @@ struct ASCH_COMPONENT }; +enum class ASCH_PIN_SYMBOL_OUTEREDGE +{ + UNKNOWN = -1, + NO_SYMBOL = 0, + NEGATED = 1, +}; + + +enum class ASCH_PIN_SYMBOL_INNEREDGE +{ + UNKNOWN = -1, + NO_SYMBOL = 0, + CLOCK = 3, +}; + + +enum class ASCH_PIN_ELECTRICAL +{ + UNKNOWN = -1, + + INPUT = 0, + BIDI = 1, + OUTPUT = 2, + OPEN_COLLECTOR = 3, + PASSIVE = 4, + TRISTATE = 5, + OPEN_EMITTER = 6, + POWER = 7 +}; + + +enum class ASCH_PIN_ORIENTATION +{ + RIGHTWARDS = 0, + UPWARDS = 1, + LEFTWARDS = 2, + DOWNWARDS = 3 +}; + + struct ASCH_PIN { int ownerindex; @@ -103,8 +142,17 @@ struct ASCH_PIN wxString text; wxString designator; - int orientation; + ASCH_PIN_SYMBOL_OUTEREDGE symbolOuterEdge; + ASCH_PIN_SYMBOL_INNEREDGE symbolInnerEdge; + + ASCH_PIN_ELECTRICAL electrical; + ASCH_PIN_ORIENTATION orientation; + wxPoint location; + int pinlength; + + bool showPinName; + bool showDesignator; explicit ASCH_PIN( const std::map& aProperties ); }; diff --git a/eeschema/sch_plugins/altium/sch_altium_plugin.cpp b/eeschema/sch_plugins/altium/sch_altium_plugin.cpp index c8c6e88b8b..1e1f363b45 100644 --- a/eeschema/sch_plugins/altium/sch_altium_plugin.cpp +++ b/eeschema/sch_plugins/altium/sch_altium_plugin.cpp @@ -47,21 +47,20 @@ #include #include "altium_parser_sch.h" -#include #include +#include #include #include #include #include -const wxPoint calculateComponentPoint( const wxPoint& aPosition, const SCH_COMPONENT* aComponent ) +const wxPoint GetRelativePosition( const wxPoint& aPosition, const SCH_COMPONENT* aComponent ) { - const wxPoint newPos = aPosition - aComponent->GetPosition(); - return { newPos.x, -newPos.y }; + TRANSFORM t = aComponent->GetTransform().InverseTransform(); + return t.TransformCoordinate( aPosition - aComponent->GetPosition() ); } - SCH_ALTIUM_PLUGIN::SCH_ALTIUM_PLUGIN() { m_rootSheet = nullptr; @@ -445,7 +444,7 @@ void SCH_ALTIUM_PLUGIN::ParseComponent( int index, const std::mapSetPosition( elem.location ); - component->SetOrientation( elem.orientation ); + //component->SetOrientation( elem.orientation ); // TODO: keep it simple for now, and only set position component->SetLibId( libId ); //component->SetLibSymbol( kpart ); // this has to be done after parsing the LIB_PART! @@ -475,10 +474,99 @@ void SCH_ALTIUM_PLUGIN::ParsePin( const std::map& aPropertie LIB_PIN* pin = new LIB_PIN( symbol->second ); symbol->second->AddDrawItem( pin ); - pin->SetPosition( calculateComponentPoint( elem.location, component ) ); - pin->SetOrientation( elem.orientation ); pin->SetName( elem.name ); pin->SetNumber( elem.designator ); + pin->SetLength( elem.pinlength ); + + wxPoint pinLocation = elem.location; // the location given is not the connection point! + switch( elem.orientation ) + { + case ASCH_PIN_ORIENTATION::RIGHTWARDS: + pin->SetOrientation( DrawPinOrient::PIN_LEFT ); + pinLocation.x += elem.pinlength; + break; + case ASCH_PIN_ORIENTATION::UPWARDS: + pin->SetOrientation( DrawPinOrient::PIN_DOWN ); + pinLocation.y -= elem.pinlength; + break; + case ASCH_PIN_ORIENTATION::LEFTWARDS: + pin->SetOrientation( DrawPinOrient::PIN_RIGHT ); + pinLocation.x -= elem.pinlength; + break; + case ASCH_PIN_ORIENTATION::DOWNWARDS: + pin->SetOrientation( DrawPinOrient::PIN_UP ); + pinLocation.y += elem.pinlength; + break; + default: + wxLogWarning( "Pin has unexpected orientation" ); + break; + } + + pin->SetPosition( GetRelativePosition( pinLocation, component ) ); + + switch( elem.electrical ) + { + case ASCH_PIN_ELECTRICAL::INPUT: + pin->SetType( ELECTRICAL_PINTYPE::PT_INPUT ); + break; + case ASCH_PIN_ELECTRICAL::BIDI: + pin->SetType( ELECTRICAL_PINTYPE::PT_BIDI ); + break; + case ASCH_PIN_ELECTRICAL::OUTPUT: + pin->SetType( ELECTRICAL_PINTYPE::PT_OUTPUT ); + break; + case ASCH_PIN_ELECTRICAL::OPEN_COLLECTOR: + pin->SetType( ELECTRICAL_PINTYPE::PT_OPENCOLLECTOR ); + break; + case ASCH_PIN_ELECTRICAL::PASSIVE: + pin->SetType( ELECTRICAL_PINTYPE::PT_PASSIVE ); + break; + case ASCH_PIN_ELECTRICAL::TRISTATE: + pin->SetType( ELECTRICAL_PINTYPE::PT_TRISTATE ); + break; + case ASCH_PIN_ELECTRICAL::OPEN_EMITTER: + pin->SetType( ELECTRICAL_PINTYPE::PT_OPENEMITTER ); + break; + case ASCH_PIN_ELECTRICAL::POWER: + pin->SetType( ELECTRICAL_PINTYPE::PT_POWER_IN ); + break; + case ASCH_PIN_ELECTRICAL::UNKNOWN: + default: + pin->SetType( ELECTRICAL_PINTYPE::PT_UNSPECIFIED ); + wxLogWarning( "Pin has unexpected electrical type" ); + break; + } + + if( elem.symbolOuterEdge == ASCH_PIN_SYMBOL_OUTEREDGE::UNKNOWN ) + wxLogWarning( "Pin has unexpected outer edge type" ); + + if( elem.symbolInnerEdge == ASCH_PIN_SYMBOL_INNEREDGE::UNKNOWN ) + wxLogWarning( "Pin has unexpected inner edge type" ); + + if( elem.symbolOuterEdge == ASCH_PIN_SYMBOL_OUTEREDGE::NEGATED ) + { + switch( elem.symbolInnerEdge ) + { + case ASCH_PIN_SYMBOL_INNEREDGE::CLOCK: + pin->SetShape( GRAPHIC_PINSHAPE::INVERTED_CLOCK ); + break; + default: + pin->SetShape( GRAPHIC_PINSHAPE::INVERTED ); + break; + } + } + else + { + switch( elem.symbolInnerEdge ) + { + case ASCH_PIN_SYMBOL_INNEREDGE::CLOCK: + pin->SetShape( GRAPHIC_PINSHAPE::CLOCK ); + break; + default: + pin->SetShape( GRAPHIC_PINSHAPE::LINE ); // nothing to do + break; + } + } } @@ -500,8 +588,8 @@ void SCH_ALTIUM_PLUGIN::ParseRectangle( const std::map& aPro LIB_RECTANGLE* rect = new LIB_RECTANGLE( symbol->second ); symbol->second->AddDrawItem( rect ); - rect->SetPosition( calculateComponentPoint( elem.topRight, component ) ); - rect->SetEnd( calculateComponentPoint( elem.bottomLeft, component ) ); + rect->SetPosition( GetRelativePosition( elem.topRight, component ) ); + rect->SetEnd( GetRelativePosition( elem.bottomLeft, component ) ); rect->SetWidth( elem.lineWidth ); if( elem.isTransparent ) {