altium: add (emulated) support for polygons

This commit is contained in:
Thomas Pointhuber 2020-10-10 16:22:53 +02:00 committed by Jon Evans
parent b4b8e31177
commit 56a60ffbed
4 changed files with 173 additions and 33 deletions

View File

@ -44,6 +44,16 @@ constexpr int Altium2KiCadUnit( const int val, const int frac )
}
int PropertiesReadKiCadUnitFrac(
const std::map<wxString, wxString>& aProperties, const wxString& aKey )
{
// a unit is stored using two fields, denoting the size in mils and a fraction size
int key = ALTIUM_PARSER::PropertiesReadInt( aProperties, aKey, 0 );
int keyFrac = ALTIUM_PARSER::PropertiesReadInt( aProperties, aKey + "_FRAC", 0 );
return Altium2KiCadUnit( key, keyFrac );
}
ASCH_COMPONENT::ASCH_COMPONENT( const std::map<wxString, wxString>& aProperties )
{
wxASSERT( PropertiesReadRecord( aProperties ) == ALTIUM_SCH_RECORD::COMPONENT );
@ -68,7 +78,8 @@ ASCH_PIN::ASCH_PIN( const std::map<wxString, wxString>& aProperties )
ownerindex =
ALTIUM_PARSER::PropertiesReadInt( aProperties, "OWNERINDEX", ALTIUM_COMPONENT_NONE );
ownerpartid = ALTIUM_PARSER::PropertiesReadInt( aProperties, "OWNERPARTID", 0 );
ownerpartid =
ALTIUM_PARSER::PropertiesReadInt( aProperties, "OWNERPARTID", ALTIUM_COMPONENT_NONE );
name = ALTIUM_PARSER::PropertiesReadString( aProperties, "NAME", "" );
text = ALTIUM_PARSER::PropertiesReadString( aProperties, "TEXT", "" );
@ -114,13 +125,40 @@ ASCH_PIN::ASCH_PIN( const std::map<wxString, wxString>& aProperties )
}
ASCH_POLYGON::ASCH_POLYGON( const std::map<wxString, wxString>& aProperties )
{
wxASSERT( PropertiesReadRecord( aProperties ) == ALTIUM_SCH_RECORD::POLYGON );
ownerindex =
ALTIUM_PARSER::PropertiesReadInt( aProperties, "OWNERINDEX", ALTIUM_COMPONENT_NONE );
ownerpartid =
ALTIUM_PARSER::PropertiesReadInt( aProperties, "OWNERPARTID", ALTIUM_COMPONENT_NONE );
int locationCount = ALTIUM_PARSER::PropertiesReadInt( aProperties, "LOCATIONCOUNT", 0 );
for( int i = 1; i <= locationCount; i++ )
{
const wxString si = std::to_string( i );
int x = ALTIUM_PARSER::PropertiesReadInt( aProperties, "X" + si, 0 );
int xfrac = ALTIUM_PARSER::PropertiesReadInt( aProperties, "X" + si + "_FRAC", 0 );
int y = ALTIUM_PARSER::PropertiesReadInt( aProperties, "Y" + si, 0 );
int yfrac = ALTIUM_PARSER::PropertiesReadInt( aProperties, "Y" + si + "_FRAC", 0 );
points.emplace_back( Altium2KiCadUnit( x, xfrac ), -Altium2KiCadUnit( y, yfrac ) );
}
lineWidth = PropertiesReadKiCadUnitFrac( aProperties, "LINEWIDTH" );
isSolid = ALTIUM_PARSER::PropertiesReadBool( aProperties, "ISSOLID", false );
}
ASCH_RECTANGLE::ASCH_RECTANGLE( const std::map<wxString, wxString>& aProperties )
{
wxASSERT( PropertiesReadRecord( aProperties ) == ALTIUM_SCH_RECORD::RECTANGLE );
ownerindex =
ALTIUM_PARSER::PropertiesReadInt( aProperties, "OWNERINDEX", ALTIUM_COMPONENT_NONE );
ownerpartid = ALTIUM_PARSER::PropertiesReadInt( aProperties, "OWNERPARTID", 0 );
ownerpartid =
ALTIUM_PARSER::PropertiesReadInt( aProperties, "OWNERPARTID", ALTIUM_COMPONENT_NONE );
int x = ALTIUM_PARSER::PropertiesReadInt( aProperties, "LOCATION.X", 0 );
int xfrac = ALTIUM_PARSER::PropertiesReadInt( aProperties, "LOCATION.X_FRAC", 0 );
@ -134,7 +172,7 @@ ASCH_RECTANGLE::ASCH_RECTANGLE( const std::map<wxString, wxString>& aProperties
yfrac = ALTIUM_PARSER::PropertiesReadInt( aProperties, "CORNER.Y_FRAC", 0 );
topRight = wxPoint( Altium2KiCadUnit( x, xfrac ), -Altium2KiCadUnit( y, yfrac ) );
lineWidth = ALTIUM_PARSER::PropertiesReadInt( aProperties, "LINEWIDTH", 0 );
lineWidth = PropertiesReadKiCadUnitFrac( aProperties, "LINEWIDTH" );
isSolid = ALTIUM_PARSER::PropertiesReadBool( aProperties, "ISSOLID", false );
isTransparent = ALTIUM_PARSER::PropertiesReadBool( aProperties, "TRANSPARENT", false );
}
@ -160,12 +198,11 @@ ASCH_BUS::ASCH_BUS( const std::map<wxString, wxString>& aProperties )
wxASSERT( PropertiesReadRecord( aProperties ) == ALTIUM_SCH_RECORD::BUS );
indexinsheet = ALTIUM_PARSER::PropertiesReadInt( aProperties, "INDEXINSHEET", 0 );
linewidth = ALTIUM_PARSER::PropertiesReadInt( aProperties, "LINEWIDTH", 0 );
int locationcount = ALTIUM_PARSER::PropertiesReadInt( aProperties, "LOCATIONCOUNT", 0 );
for( int i = 0; i < locationcount; i++ )
for( int i = 1; i <= locationcount; i++ )
{
const wxString si = std::to_string( i + 1 );
const wxString si = std::to_string( i );
int x = ALTIUM_PARSER::PropertiesReadInt( aProperties, "X" + si, 0 );
int xfrac = ALTIUM_PARSER::PropertiesReadInt( aProperties, "X" + si + "_FRAC", 0 );
@ -173,6 +210,8 @@ ASCH_BUS::ASCH_BUS( const std::map<wxString, wxString>& aProperties )
int yfrac = ALTIUM_PARSER::PropertiesReadInt( aProperties, "Y" + si + "_FRAC", 0 );
points.emplace_back( Altium2KiCadUnit( x, xfrac ), -Altium2KiCadUnit( y, yfrac ) );
}
lineWidth = PropertiesReadKiCadUnitFrac( aProperties, "LINEWIDTH" );
}
@ -189,12 +228,11 @@ ASCH_WIRE::ASCH_WIRE( const std::map<wxString, wxString>& aProperties )
}*/
indexinsheet = ALTIUM_PARSER::PropertiesReadInt( aProperties, "INDEXINSHEET", 0 );
linewidth = ALTIUM_PARSER::PropertiesReadInt( aProperties, "LINEWIDTH", 0 );
int locationcount = ALTIUM_PARSER::PropertiesReadInt( aProperties, "LOCATIONCOUNT", 0 );
for( int i = 0; i < locationcount; i++ )
for( int i = 1; i <= locationcount; i++ )
{
const wxString si = std::to_string( i + 1 );
const wxString si = std::to_string( i );
int x = ALTIUM_PARSER::PropertiesReadInt( aProperties, "X" + si, 0 );
int xfrac = ALTIUM_PARSER::PropertiesReadInt( aProperties, "X" + si + "_FRAC", 0 );
@ -202,6 +240,8 @@ ASCH_WIRE::ASCH_WIRE( const std::map<wxString, wxString>& aProperties )
int yfrac = ALTIUM_PARSER::PropertiesReadInt( aProperties, "Y" + si + "_FRAC", 0 );
points.emplace_back( Altium2KiCadUnit( x, xfrac ), -Altium2KiCadUnit( y, yfrac ) );
}
lineWidth = PropertiesReadKiCadUnitFrac( aProperties, "LINEWIDTH" );
}

View File

@ -194,6 +194,20 @@ struct ASCH_PIN
};
struct ASCH_POLYGON
{
int ownerindex;
int ownerpartid;
std::vector<wxPoint> points;
int lineWidth;
bool isSolid;
explicit ASCH_POLYGON( const std::map<wxString, wxString>& aProperties );
};
struct ASCH_RECTANGLE
{
int ownerindex;
@ -223,7 +237,7 @@ struct ASCH_NET_LABEL
struct ASCH_BUS
{
int indexinsheet;
int linewidth;
int lineWidth;
std::vector<wxPoint> points;
@ -234,7 +248,7 @@ struct ASCH_BUS
struct ASCH_WIRE
{
int indexinsheet;
int linewidth;
int lineWidth;
std::vector<wxPoint> points;

View File

@ -312,6 +312,7 @@ void SCH_ALTIUM_PLUGIN::Parse( const CFB::CompoundFileReader& aReader )
case ALTIUM_SCH_RECORD::POLYLINE:
break;
case ALTIUM_SCH_RECORD::POLYGON:
ParsePolygon( properties );
break;
case ALTIUM_SCH_RECORD::ELLIPSE:
break;
@ -587,38 +588,122 @@ void SCH_ALTIUM_PLUGIN::ParsePin( const std::map<wxString, wxString>& aPropertie
}
void SCH_ALTIUM_PLUGIN::ParsePolygon( const std::map<wxString, wxString>& aProperties )
{
ASCH_POLYGON elem( aProperties );
if( elem.ownerpartid == ALTIUM_COMPONENT_NONE )
{
// TODO: we cannot fill this polygon, only draw it for now
for( int i = 0; i < (int) elem.points.size() - 1; i++ )
{
SCH_LINE* line = new SCH_LINE( elem.points.at( i ), SCH_LAYER_ID::LAYER_NOTES );
line->SetEndPoint( elem.points.at( i + 1 ) );
line->SetFlags( IS_NEW );
m_currentSheet->GetScreen()->Append( line );
}
// close polygon
SCH_LINE* line = new SCH_LINE( elem.points.front(), SCH_LAYER_ID::LAYER_NOTES );
line->SetEndPoint( elem.points.back() );
line->SetFlags( IS_NEW );
m_currentSheet->GetScreen()->Append( line );
}
else
{
const auto& symbol = m_symbols.find( elem.ownerindex );
if( symbol == m_symbols.end() )
{
// TODO: e.g. can depend on Template (RECORD=39
wxLogWarning( wxString::Format(
"Rectangle tries to access symbol with ownerindex %d which does not exist",
elem.ownerindex ) );
return;
}
const auto& component = m_components.at( symbol->first );
LIB_POLYLINE* line = new LIB_POLYLINE( symbol->second );
symbol->second->AddDrawItem( line );
// TODO: we cannot fill this polygon, only draw it for now?
for( wxPoint& point : elem.points )
{
line->AddPoint( GetRelativePosition( point, component ) );
}
line->SetWidth( elem.lineWidth );
if( elem.isSolid )
{
line->SetFillMode( FILL_TYPE::FILLED_SHAPE );
}
}
}
void SCH_ALTIUM_PLUGIN::ParseRectangle( const std::map<wxString, wxString>& aProperties )
{
ASCH_RECTANGLE elem( aProperties );
const auto& symbol = m_symbols.find( elem.ownerindex );
if( symbol == m_symbols.end() )
if( elem.ownerpartid == ALTIUM_COMPONENT_NONE )
{
// TODO: e.g. can depend on Template (RECORD=39
wxLogWarning( wxString::Format(
"Pin tries to access symbol with ownerindex %d which does not exist",
elem.ownerindex ) );
return;
}
const wxPoint topLeft = { elem.bottomLeft.x, elem.topRight.y };
const wxPoint bottomRight = { elem.topRight.x, elem.bottomLeft.y };
const auto& component = m_components.at( symbol->first );
// TODO: we cannot fill this rectangle, only draw it for now
SCH_LINE* lineTop = new SCH_LINE( elem.topRight, SCH_LAYER_ID::LAYER_NOTES );
lineTop->SetEndPoint( topLeft );
lineTop->SetFlags( IS_NEW );
m_currentSheet->GetScreen()->Append( lineTop );
LIB_RECTANGLE* rect = new LIB_RECTANGLE( symbol->second );
symbol->second->AddDrawItem( rect );
rect->SetPosition( GetRelativePosition( elem.topRight, component ) );
rect->SetEnd( GetRelativePosition( elem.bottomLeft, component ) );
rect->SetWidth( elem.lineWidth );
if( elem.isTransparent )
{
rect->SetFillMode( FILL_TYPE::NO_FILL );
}
else if( elem.isSolid )
{
rect->SetFillMode( FILL_TYPE::FILLED_SHAPE );
SCH_LINE* lineBottom = new SCH_LINE( elem.bottomLeft, SCH_LAYER_ID::LAYER_NOTES );
lineBottom->SetEndPoint( bottomRight );
lineBottom->SetFlags( IS_NEW );
m_currentSheet->GetScreen()->Append( lineBottom );
SCH_LINE* lineRight = new SCH_LINE( elem.topRight, SCH_LAYER_ID::LAYER_NOTES );
lineRight->SetEndPoint( bottomRight );
lineRight->SetFlags( IS_NEW );
m_currentSheet->GetScreen()->Append( lineRight );
SCH_LINE* lineLeft = new SCH_LINE( elem.bottomLeft, SCH_LAYER_ID::LAYER_NOTES );
lineLeft->SetEndPoint( topLeft );
lineLeft->SetFlags( IS_NEW );
m_currentSheet->GetScreen()->Append( lineLeft );
}
else
{
rect->SetFillMode( FILL_TYPE::FILLED_WITH_BG_BODYCOLOR );
const auto& symbol = m_symbols.find( elem.ownerindex );
if( symbol == m_symbols.end() )
{
// TODO: e.g. can depend on Template (RECORD=39
wxLogWarning( wxString::Format(
"Rectangle tries to access symbol with ownerindex %d which does not exist",
elem.ownerindex ) );
return;
}
const auto& component = m_components.at( symbol->first );
LIB_RECTANGLE* rect = new LIB_RECTANGLE( symbol->second );
symbol->second->AddDrawItem( rect );
rect->SetPosition( GetRelativePosition( elem.topRight, component ) );
rect->SetEnd( GetRelativePosition( elem.bottomLeft, component ) );
rect->SetWidth( elem.lineWidth );
if( elem.isTransparent )
{
rect->SetFillMode( FILL_TYPE::NO_FILL );
}
else if( elem.isSolid )
{
rect->SetFillMode( FILL_TYPE::FILLED_SHAPE );
}
else
{
rect->SetFillMode( FILL_TYPE::FILLED_WITH_BG_BODYCOLOR );
}
}
}

View File

@ -100,6 +100,7 @@ public:
private:
void ParseComponent( int index, const std::map<wxString, wxString>& aProperties );
void ParsePin( const std::map<wxString, wxString>& aProperties );
void ParsePolygon( const std::map<wxString, wxString>& aProperties );
void ParseRectangle( const std::map<wxString, wxString>& aProperties );
void ParseNetLabel( const std::map<wxString, wxString>& aProperties );
void ParseBus( const std::map<wxString, wxString>& aProperties );