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 ) ASCH_COMPONENT::ASCH_COMPONENT( const std::map<wxString, wxString>& aProperties )
{ {
wxASSERT( PropertiesReadRecord( aProperties ) == ALTIUM_SCH_RECORD::COMPONENT ); wxASSERT( PropertiesReadRecord( aProperties ) == ALTIUM_SCH_RECORD::COMPONENT );
@ -68,7 +78,8 @@ ASCH_PIN::ASCH_PIN( const std::map<wxString, wxString>& aProperties )
ownerindex = ownerindex =
ALTIUM_PARSER::PropertiesReadInt( aProperties, "OWNERINDEX", ALTIUM_COMPONENT_NONE ); 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", "" ); name = ALTIUM_PARSER::PropertiesReadString( aProperties, "NAME", "" );
text = ALTIUM_PARSER::PropertiesReadString( aProperties, "TEXT", "" ); 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 ) ASCH_RECTANGLE::ASCH_RECTANGLE( const std::map<wxString, wxString>& aProperties )
{ {
wxASSERT( PropertiesReadRecord( aProperties ) == ALTIUM_SCH_RECORD::RECTANGLE ); wxASSERT( PropertiesReadRecord( aProperties ) == ALTIUM_SCH_RECORD::RECTANGLE );
ownerindex = ownerindex =
ALTIUM_PARSER::PropertiesReadInt( aProperties, "OWNERINDEX", ALTIUM_COMPONENT_NONE ); 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 x = ALTIUM_PARSER::PropertiesReadInt( aProperties, "LOCATION.X", 0 );
int xfrac = ALTIUM_PARSER::PropertiesReadInt( aProperties, "LOCATION.X_FRAC", 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 ); yfrac = ALTIUM_PARSER::PropertiesReadInt( aProperties, "CORNER.Y_FRAC", 0 );
topRight = wxPoint( Altium2KiCadUnit( x, xfrac ), -Altium2KiCadUnit( y, yfrac ) ); 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 ); isSolid = ALTIUM_PARSER::PropertiesReadBool( aProperties, "ISSOLID", false );
isTransparent = ALTIUM_PARSER::PropertiesReadBool( aProperties, "TRANSPARENT", 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 ); wxASSERT( PropertiesReadRecord( aProperties ) == ALTIUM_SCH_RECORD::BUS );
indexinsheet = ALTIUM_PARSER::PropertiesReadInt( aProperties, "INDEXINSHEET", 0 ); indexinsheet = ALTIUM_PARSER::PropertiesReadInt( aProperties, "INDEXINSHEET", 0 );
linewidth = ALTIUM_PARSER::PropertiesReadInt( aProperties, "LINEWIDTH", 0 );
int locationcount = ALTIUM_PARSER::PropertiesReadInt( aProperties, "LOCATIONCOUNT", 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 x = ALTIUM_PARSER::PropertiesReadInt( aProperties, "X" + si, 0 );
int xfrac = ALTIUM_PARSER::PropertiesReadInt( aProperties, "X" + si + "_FRAC", 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 ); int yfrac = ALTIUM_PARSER::PropertiesReadInt( aProperties, "Y" + si + "_FRAC", 0 );
points.emplace_back( Altium2KiCadUnit( x, xfrac ), -Altium2KiCadUnit( y, yfrac ) ); 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 ); indexinsheet = ALTIUM_PARSER::PropertiesReadInt( aProperties, "INDEXINSHEET", 0 );
linewidth = ALTIUM_PARSER::PropertiesReadInt( aProperties, "LINEWIDTH", 0 );
int locationcount = ALTIUM_PARSER::PropertiesReadInt( aProperties, "LOCATIONCOUNT", 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 x = ALTIUM_PARSER::PropertiesReadInt( aProperties, "X" + si, 0 );
int xfrac = ALTIUM_PARSER::PropertiesReadInt( aProperties, "X" + si + "_FRAC", 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 ); int yfrac = ALTIUM_PARSER::PropertiesReadInt( aProperties, "Y" + si + "_FRAC", 0 );
points.emplace_back( Altium2KiCadUnit( x, xfrac ), -Altium2KiCadUnit( y, yfrac ) ); 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 struct ASCH_RECTANGLE
{ {
int ownerindex; int ownerindex;
@ -223,7 +237,7 @@ struct ASCH_NET_LABEL
struct ASCH_BUS struct ASCH_BUS
{ {
int indexinsheet; int indexinsheet;
int linewidth; int lineWidth;
std::vector<wxPoint> points; std::vector<wxPoint> points;
@ -234,7 +248,7 @@ struct ASCH_BUS
struct ASCH_WIRE struct ASCH_WIRE
{ {
int indexinsheet; int indexinsheet;
int linewidth; int lineWidth;
std::vector<wxPoint> points; std::vector<wxPoint> points;

View File

@ -312,6 +312,7 @@ void SCH_ALTIUM_PLUGIN::Parse( const CFB::CompoundFileReader& aReader )
case ALTIUM_SCH_RECORD::POLYLINE: case ALTIUM_SCH_RECORD::POLYLINE:
break; break;
case ALTIUM_SCH_RECORD::POLYGON: case ALTIUM_SCH_RECORD::POLYGON:
ParsePolygon( properties );
break; break;
case ALTIUM_SCH_RECORD::ELLIPSE: case ALTIUM_SCH_RECORD::ELLIPSE:
break; 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 ) void SCH_ALTIUM_PLUGIN::ParseRectangle( const std::map<wxString, wxString>& aProperties )
{ {
ASCH_RECTANGLE elem( aProperties ); ASCH_RECTANGLE elem( aProperties );
const auto& symbol = m_symbols.find( elem.ownerindex ); if( elem.ownerpartid == ALTIUM_COMPONENT_NONE )
if( symbol == m_symbols.end() )
{ {
// TODO: e.g. can depend on Template (RECORD=39 const wxPoint topLeft = { elem.bottomLeft.x, elem.topRight.y };
wxLogWarning( wxString::Format( const wxPoint bottomRight = { elem.topRight.x, elem.bottomLeft.y };
"Pin tries to access symbol with ownerindex %d which does not exist",
elem.ownerindex ) );
return;
}
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 ); SCH_LINE* lineBottom = new SCH_LINE( elem.bottomLeft, SCH_LAYER_ID::LAYER_NOTES );
symbol->second->AddDrawItem( rect ); lineBottom->SetEndPoint( bottomRight );
rect->SetPosition( GetRelativePosition( elem.topRight, component ) ); lineBottom->SetFlags( IS_NEW );
rect->SetEnd( GetRelativePosition( elem.bottomLeft, component ) ); m_currentSheet->GetScreen()->Append( lineBottom );
rect->SetWidth( elem.lineWidth );
if( elem.isTransparent ) SCH_LINE* lineRight = new SCH_LINE( elem.topRight, SCH_LAYER_ID::LAYER_NOTES );
{ lineRight->SetEndPoint( bottomRight );
rect->SetFillMode( FILL_TYPE::NO_FILL ); lineRight->SetFlags( IS_NEW );
} m_currentSheet->GetScreen()->Append( lineRight );
else if( elem.isSolid )
{ SCH_LINE* lineLeft = new SCH_LINE( elem.bottomLeft, SCH_LAYER_ID::LAYER_NOTES );
rect->SetFillMode( FILL_TYPE::FILLED_SHAPE ); lineLeft->SetEndPoint( topLeft );
lineLeft->SetFlags( IS_NEW );
m_currentSheet->GetScreen()->Append( lineLeft );
} }
else 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: private:
void ParseComponent( int index, const std::map<wxString, wxString>& aProperties ); void ParseComponent( int index, const std::map<wxString, wxString>& aProperties );
void ParsePin( 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 ParseRectangle( const std::map<wxString, wxString>& aProperties );
void ParseNetLabel( const std::map<wxString, wxString>& aProperties ); void ParseNetLabel( const std::map<wxString, wxString>& aProperties );
void ParseBus( const std::map<wxString, wxString>& aProperties ); void ParseBus( const std::map<wxString, wxString>& aProperties );