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 ;)
This commit is contained in:
Thomas Pointhuber 2020-10-09 16:23:07 +02:00 committed by Jon Evans
parent 114f9062f1
commit 53d90431ea
3 changed files with 171 additions and 13 deletions

View File

@ -74,14 +74,36 @@ ASCH_PIN::ASCH_PIN( const std::map<wxString, wxString>& 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<ASCH_PIN_SYMBOL_OUTEREDGE>( symbolOuterEdgeInt ) :
ASCH_PIN_SYMBOL_OUTEREDGE::UNKNOWN;
int symbolInnerEdgeInt = ALTIUM_PARSER::PropertiesReadInt( aProperties, "SYMBOL_INNEREDGE", 0 );
symbolInnerEdge = ( symbolInnerEdgeInt == 0 || symbolInnerEdgeInt == 3 ) ?
static_cast<ASCH_PIN_SYMBOL_INNEREDGE>( symbolInnerEdgeInt ) :
ASCH_PIN_SYMBOL_INNEREDGE::UNKNOWN;
int electricalInt = ALTIUM_PARSER::PropertiesReadInt( aProperties, "ELECTRICAL", 0 );
electrical = ( electricalInt >= 0 && electricalInt <= 7 ) ?
static_cast<ASCH_PIN_ELECTRICAL>( electricalInt ) :
ASCH_PIN_ELECTRICAL::UNKNOWN;
int pinconglomerate = ALTIUM_PARSER::PropertiesReadInt( aProperties, "PINCONGLOMERATE", 0 );
orientation = pinconglomerate & 0x03;
orientation = static_cast<ASCH_PIN_ORIENTATION>( 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 );
}

View File

@ -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<wxString, wxString>& aProperties );
};

View File

@ -47,21 +47,20 @@
#include <sch_text.h>
#include "altium_parser_sch.h"
#include <memory>
#include <compoundfilereader.h>
#include <memory>
#include <plugins/altium/altium_parser.h>
#include <sch_plugins/legacy/sch_legacy_plugin.h>
#include <wildcards_and_files_ext.h>
#include <wx/textfile.h>
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::map<wxString, wxSt
SCH_COMPONENT* component = new SCH_COMPONENT();
component->SetPosition( 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<wxString, wxString>& 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<wxString, wxString>& 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 )
{