From 52b5e4d0b38e3a95edd38963249ddb85316db4f6 Mon Sep 17 00:00:00 2001 From: Thomas Pointhuber Date: Mon, 26 Oct 2020 16:54:49 +0100 Subject: [PATCH] altium: initial code to parse ports. Includes a hack until we know which side to connect to. Fix: https://gitlab.com/kicad/code/kicad/-/issues/6056 --- .../sch_plugins/altium/altium_parser_sch.cpp | 21 +++++ .../sch_plugins/altium/altium_parser_sch.h | 39 +++++++++ .../sch_plugins/altium/sch_altium_plugin.cpp | 80 +++++++++++++++++++ .../sch_plugins/altium/sch_altium_plugin.h | 1 + 4 files changed, 141 insertions(+) diff --git a/eeschema/sch_plugins/altium/altium_parser_sch.cpp b/eeschema/sch_plugins/altium/altium_parser_sch.cpp index 33245e2e4b..5b4b10ae76 100644 --- a/eeschema/sch_plugins/altium/altium_parser_sch.cpp +++ b/eeschema/sch_plugins/altium/altium_parser_sch.cpp @@ -387,6 +387,27 @@ ASCH_POWER_PORT::ASCH_POWER_PORT( const std::map& aPropertie aProperties, "STYLE", 0, 10, ASCH_POWER_PORT_STYLE::CIRCLE ); } +ASCH_PORT::ASCH_PORT( const std::map& aProperties ) +{ + wxASSERT( PropertiesReadRecord( aProperties ) == ALTIUM_SCH_RECORD::PORT ); + + ownerpartid = + ALTIUM_PARSER::PropertiesReadInt( aProperties, "OWNERPARTID", ALTIUM_COMPONENT_NONE ); + + location = wxPoint( PropertiesReadKiCadUnitFrac( aProperties, "LOCATION.X" ), + -PropertiesReadKiCadUnitFrac( aProperties, "LOCATION.Y" ) ); + + name = ALTIUM_PARSER::PropertiesReadString( aProperties, "NAME", "" ); + + width = PropertiesReadKiCadUnitFrac( aProperties, "WIDTH" ); + height = PropertiesReadKiCadUnitFrac( aProperties, "HEIGHT" ); + + iotype = PropertiesReadEnum( + aProperties, "IOTYPE", 0, 3, ASCH_PORT_IOTYPE::UNSPECIFIED ); + style = PropertiesReadEnum( + aProperties, "STYLE", 0, 7, ASCH_PORT_STYLE::NONE_HORIZONTAL ); +} + ASCH_NO_ERC::ASCH_NO_ERC( const std::map& aProperties ) { diff --git a/eeschema/sch_plugins/altium/altium_parser_sch.h b/eeschema/sch_plugins/altium/altium_parser_sch.h index a65e30115d..57ce71c8df 100644 --- a/eeschema/sch_plugins/altium/altium_parser_sch.h +++ b/eeschema/sch_plugins/altium/altium_parser_sch.h @@ -406,6 +406,45 @@ struct ASCH_POWER_PORT }; +enum class ASCH_PORT_IOTYPE +{ + UNSPECIFIED = 0, + OUTPUT = 1, + INPUT = 2, + BIDI = 3, +}; + + +enum class ASCH_PORT_STYLE +{ + NONE_HORIZONTAL = 0, + LEFT = 1, + RIGHT = 2, + LEFT_RIGHT = 3, + NONE_VERTICAL = 4, + TOP = 5, + BOTTOM = 6, + TOP_BOTTOM = 7 +}; + + +struct ASCH_PORT +{ + int ownerpartid; + + wxString name; + + wxPoint location; + int width; + int height; + + ASCH_PORT_IOTYPE iotype; + ASCH_PORT_STYLE style; + + explicit ASCH_PORT( const std::map& aProperties ); +}; + + struct ASCH_NO_ERC { wxPoint location; diff --git a/eeschema/sch_plugins/altium/sch_altium_plugin.cpp b/eeschema/sch_plugins/altium/sch_altium_plugin.cpp index 18fc263ef0..f132313815 100644 --- a/eeschema/sch_plugins/altium/sch_altium_plugin.cpp +++ b/eeschema/sch_plugins/altium/sch_altium_plugin.cpp @@ -345,6 +345,7 @@ void SCH_ALTIUM_PLUGIN::Parse( const CFB::CompoundFileReader& aReader ) ParsePowerPort( properties ); break; case ALTIUM_SCH_RECORD::PORT: + ParsePort( properties ); break; case ALTIUM_SCH_RECORD::NO_ERC: ParseNoERC( properties ); @@ -1527,6 +1528,85 @@ void SCH_ALTIUM_PLUGIN::ParsePowerPort( const std::map& aPro } +void SCH_ALTIUM_PLUGIN::ParsePort( const std::map& aProperties ) +{ + ASCH_PORT elem( aProperties ); + + SCH_TEXT* const label = new SCH_GLOBALLABEL( elem.location + m_sheetOffset, elem.name ); + // TODO: detect correct label type depending on sheet settings, etc. + // label = new SCH_HIERLABEL( elem.location + m_sheetOffset, elem.name ); + + switch( elem.iotype ) + { + default: + case ASCH_PORT_IOTYPE::UNSPECIFIED: + label->SetShape( PINSHEETLABEL_SHAPE::PS_UNSPECIFIED ); + break; + case ASCH_PORT_IOTYPE::OUTPUT: + label->SetShape( PINSHEETLABEL_SHAPE::PS_OUTPUT ); + break; + case ASCH_PORT_IOTYPE::INPUT: + label->SetShape( PINSHEETLABEL_SHAPE::PS_INPUT ); + break; + case ASCH_PORT_IOTYPE::BIDI: + label->SetShape( PINSHEETLABEL_SHAPE::PS_BIDI ); + break; + } + + switch( elem.style ) + { + default: + case ASCH_PORT_STYLE::NONE_HORIZONTAL: + case ASCH_PORT_STYLE::LEFT: + case ASCH_PORT_STYLE::RIGHT: + case ASCH_PORT_STYLE::LEFT_RIGHT: + label->SetLabelSpinStyle( LABEL_SPIN_STYLE::RIGHT ); + break; + case ASCH_PORT_STYLE::NONE_VERTICAL: + case ASCH_PORT_STYLE::TOP: + case ASCH_PORT_STYLE::BOTTOM: + case ASCH_PORT_STYLE::TOP_BOTTOM: + label->SetLabelSpinStyle( LABEL_SPIN_STYLE::UP ); + break; + } + + label->SetFlags( IS_NEW ); + m_currentSheet->GetScreen()->Append( label ); + + // TODO: This is a hack until we know where we need to connect the label. + // The problem is that, apparently, Altium allows us to connect to the label from both sides + wxPoint start = elem.location + m_sheetOffset; + switch( elem.style ) + { + default: + case ASCH_PORT_STYLE::NONE_HORIZONTAL: + case ASCH_PORT_STYLE::LEFT: + case ASCH_PORT_STYLE::RIGHT: + case ASCH_PORT_STYLE::LEFT_RIGHT: + { + SCH_LINE* wire = new SCH_LINE( start, SCH_LAYER_ID::LAYER_WIRE ); + wire->SetEndPoint( { start.x + elem.width, start.y } ); + wire->SetLineWidth( Mils2iu( 2 ) ); + wire->SetFlags( IS_NEW ); + m_currentSheet->GetScreen()->Append( wire ); + break; + } + case ASCH_PORT_STYLE::NONE_VERTICAL: + case ASCH_PORT_STYLE::TOP: + case ASCH_PORT_STYLE::BOTTOM: + case ASCH_PORT_STYLE::TOP_BOTTOM: + { + SCH_LINE* wire = new SCH_LINE( start, SCH_LAYER_ID::LAYER_WIRE ); + wire->SetEndPoint( { start.x, start.y - elem.width } ); + wire->SetLineWidth( Mils2iu( 2 ) ); + wire->SetFlags( IS_NEW ); + m_currentSheet->GetScreen()->Append( wire ); + break; + } + } +} + + void SCH_ALTIUM_PLUGIN::ParseNoERC( const std::map& aProperties ) { ASCH_NO_ERC elem( aProperties ); diff --git a/eeschema/sch_plugins/altium/sch_altium_plugin.h b/eeschema/sch_plugins/altium/sch_altium_plugin.h index b67c0ef987..53de2d52b1 100644 --- a/eeschema/sch_plugins/altium/sch_altium_plugin.h +++ b/eeschema/sch_plugins/altium/sch_altium_plugin.h @@ -115,6 +115,7 @@ private: void ParseLine( const std::map& aProperties ); void ParseRectangle( const std::map& aProperties ); void ParsePowerPort( const std::map& aProperties ); + void ParsePort( const std::map& aProperties ); void ParseNoERC( const std::map& aProperties ); void ParseNetLabel( const std::map& aProperties ); void ParseBus( const std::map& aProperties );