Import SIGNAL_HARNESS as graphical polyline

This commit is contained in:
WhiteChairFromIkea 2022-08-09 14:39:13 +03:00 committed by Jeff Young
parent a3dc38cb32
commit b64f6ccc18
4 changed files with 152 additions and 11 deletions

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020 Thomas Pointhuber <thomas.pointhuber@gmx.at>
* Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -108,6 +108,18 @@ ASCH_STORAGE_FILE::ASCH_STORAGE_FILE( ALTIUM_PARSER& aReader )
}
ASCH_ADDITIONAL_FILE::ASCH_ADDITIONAL_FILE( ALTIUM_PARSER& aReader )
{
aReader.Skip( 5 );
filename = aReader.ReadWxString();
uint32_t dataSize = aReader.Read<uint32_t>();
data = aReader.ReadVector( dataSize );
if( aReader.HasParsingError() )
THROW_IO_ERROR( "Additional stream was not parsed correctly" );
}
ASCH_SYMBOL::ASCH_SYMBOL( const std::map<wxString, wxString>& aProps )
{
wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::COMPONENT );
@ -399,6 +411,28 @@ ASCH_LINE::ASCH_LINE( const std::map<wxString, wxString>& aProps )
}
ASCH_SIGNAL_HARNESS::ASCH_SIGNAL_HARNESS( const std::map<wxString, wxString>& aProps )
{
wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::SIGNAL_HARNESS );
ownerpartid = ReadOwnerPartId( aProps );
int locationCount = ALTIUM_PARSER::ReadInt( aProps, "LOCATIONCOUNT", 0 );
for( int i = 1; i <= locationCount; i++ )
{
const wxString si = std::to_string( i );
points.emplace_back( ReadKiCadUnitFrac( aProps, "X" + si ),
-ReadKiCadUnitFrac( aProps, "Y" + si ) );
}
indexinsheet = ALTIUM_PARSER::ReadInt( aProps, "INDEXINSHEET", 0 );
color = ALTIUM_PARSER::ReadInt( aProps, "COLOR", 0 );
lineWidth = ReadKiCadUnitFrac( aProps, "LINEWIDTH" );
}
ASCH_RECTANGLE::ASCH_RECTANGLE( const std::map<wxString, wxString>& aProps )
{
wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::RECTANGLE );

View File

@ -48,6 +48,13 @@ struct ASCH_STORAGE_FILE
explicit ASCH_STORAGE_FILE( ALTIUM_PARSER& aReader );
};
struct ASCH_ADDITIONAL_FILE
{
wxString filename;
std::vector<char> data;
explicit ASCH_ADDITIONAL_FILE( ALTIUM_PARSER& aReader );
};
enum class ALTIUM_SCH_RECORD
{
@ -95,7 +102,7 @@ enum class ALTIUM_SCH_RECORD
RECORD_215 = 215,
RECORD_216 = 216,
RECORD_217 = 217,
RECORD_218 = 218,
SIGNAL_HARNESS = 218,
RECORD_226 = 226,
};
@ -399,6 +406,24 @@ struct ASCH_LINE
};
struct ASCH_SIGNAL_HARNESS
{
int ownerpartid; // always -1, can be safely ignored I think
VECTOR2I point1;
VECTOR2I point2;
std::vector<VECTOR2I> points;
int color;
int indexinsheet;
int lineWidth;
explicit ASCH_SIGNAL_HARNESS( const std::map<wxString, wxString>& aProps );
};
struct ASCH_RECTANGLE : ASCH_SHAPE_INTERFACE
{
VECTOR2I bottomLeft;
@ -600,6 +625,7 @@ struct ASCH_SHEET_FONT
int size;
int rotation;
int areaColor;
bool italic;
bool bold;

View File

@ -296,6 +296,7 @@ void SCH_ALTIUM_PLUGIN::ParseAltiumSch( const wxString& aFileName )
{
ParseStorage( altiumSchFile ); // we need this before parsing the FileHeader
ParseFileHeader( altiumSchFile );
ParseAdditional( altiumSchFile ); // we need to parse "Additional" becaus sheet is set up during "FileHeader" parsing
}
catch( CFB::CFBException& exception )
{
@ -339,6 +340,64 @@ void SCH_ALTIUM_PLUGIN::ParseStorage( const ALTIUM_COMPOUND_FILE& aAltiumSchFile
}
}
void SCH_ALTIUM_PLUGIN::ParseAdditional( const ALTIUM_COMPOUND_FILE& aAltiumSchFile )
{
const CFB::COMPOUND_FILE_ENTRY* file = aAltiumSchFile.FindStream( { "Additional" } );
if( file == nullptr )
return;
ALTIUM_PARSER reader( aAltiumSchFile, file );
if( reader.GetRemainingBytes() <= 0 )
{
THROW_IO_ERROR( "Additional section does not contain any data" );
}
else
{
std::map<wxString, wxString> properties = reader.ReadProperties();
int recordId = ALTIUM_PARSER::ReadInt( properties, "RECORD", 0 );
ALTIUM_SCH_RECORD record = static_cast<ALTIUM_SCH_RECORD>( recordId );
if( record != ALTIUM_SCH_RECORD::HEADER )
THROW_IO_ERROR( "Header expected" );
}
for( int index = 0; reader.GetRemainingBytes() > 0; index++ )
{
std::map<wxString, wxString> properties = reader.ReadProperties();
int recordId = ALTIUM_PARSER::ReadInt( properties, "RECORD", 0 );
ALTIUM_SCH_RECORD record = static_cast<ALTIUM_SCH_RECORD>( recordId );
// see: https://github.com/vadmium/python-altium/blob/master/format.md
switch( record )
{
case ALTIUM_SCH_RECORD::RECORD_215:
break;
case ALTIUM_SCH_RECORD::RECORD_216:
break;
case ALTIUM_SCH_RECORD::RECORD_217:
break;
case ALTIUM_SCH_RECORD::SIGNAL_HARNESS:
ParseSignalHarness( properties );
break;
default:
m_reporter->Report( wxString::Format( _( "Unknown or unexpected record found inside \"Additional\" section, Record id: %d." ), recordId ),
RPT_SEVERITY_ERROR );
break;
}
}
if( reader.HasParsingError() )
THROW_IO_ERROR( "stream was not parsed correctly!" );
if( reader.GetRemainingBytes() != 0 )
THROW_IO_ERROR( "stream is not fully parsed" );
}
void SCH_ALTIUM_PLUGIN::ParseFileHeader( const ALTIUM_COMPOUND_FILE& aAltiumSchFile )
{
@ -496,18 +555,12 @@ void SCH_ALTIUM_PLUGIN::ParseFileHeader( const ALTIUM_COMPOUND_FILE& aAltiumSchF
case ALTIUM_SCH_RECORD::COMPILE_MASK:
m_reporter->Report( _( "Compile mask not currently supported." ), RPT_SEVERITY_ERROR );
break;
case ALTIUM_SCH_RECORD::RECORD_215:
break;
case ALTIUM_SCH_RECORD::RECORD_216:
break;
case ALTIUM_SCH_RECORD::RECORD_217:
break;
case ALTIUM_SCH_RECORD::RECORD_218:
break;
case ALTIUM_SCH_RECORD::RECORD_226:
break;
default:
m_reporter->Report( wxString::Format( _( "Unknown Record id: %d." ), recordId ),
m_reporter->Report( wxString::Format( _( "Unknown or unexpected record found inside "
"\"FileHeader\" section, Record id: %d." ),
recordId ),
RPT_SEVERITY_ERROR );
break;
}
@ -1405,6 +1458,31 @@ void SCH_ALTIUM_PLUGIN::ParseLine( const std::map<wxString, wxString>& aProperti
}
void SCH_ALTIUM_PLUGIN::ParseSignalHarness( const std::map<wxString, wxString>& aProperties )
{
ASCH_SIGNAL_HARNESS elem( aProperties );
if( elem.ownerpartid == ALTIUM_COMPONENT_NONE )
{
SCH_SHAPE* poly = new SCH_SHAPE( SHAPE_T::POLY );
for( VECTOR2I& point : elem.points )
poly->AddPoint( point + m_sheetOffset );
poly->SetStroke( STROKE_PARAMS( elem.lineWidth, PLOT_DASH_TYPE::SOLID,
GetColorFromInt( elem.color ) ) );
poly->SetFlags( IS_NEW );
m_currentSheet->GetScreen()->Append( poly );
}
else
{
// No clue if this situation can ever exist
m_reporter->Report( _( "Signal harness, belonging to the part is not currently supported." ), RPT_SEVERITY_ERROR );
}
}
void SCH_ALTIUM_PLUGIN::ParseRectangle( const std::map<wxString, wxString>& aProperties )
{
ASCH_RECTANGLE elem( aProperties );

View File

@ -103,6 +103,7 @@ public:
void ParseAltiumSch( const wxString& aFileName );
void ParseStorage( const ALTIUM_COMPOUND_FILE& aAltiumSchFile );
void ParseAdditional( const ALTIUM_COMPOUND_FILE& aAltiumSchFile );
void ParseFileHeader( const ALTIUM_COMPOUND_FILE& aAltiumSchFile );
private:
@ -120,6 +121,7 @@ private:
void ParseRoundRectangle( const std::map<wxString, wxString>& aProperties );
void ParseArc( const std::map<wxString, wxString>& aProperties );
void ParseLine( const std::map<wxString, wxString>& aProperties );
void ParseSignalHarness( const std::map<wxString, wxString>& aProperties );
void ParseRectangle( const std::map<wxString, wxString>& aProperties );
void ParseSheetSymbol( int aIndex, const std::map<wxString, wxString>& aProperties );
void ParseSheetEntry( const std::map<wxString, wxString>& aProperties );
@ -162,6 +164,7 @@ private:
std::map<wxString, LIB_SYMBOL*> m_powerSymbols;
std::vector<ASCH_STORAGE_FILE> m_altiumStorage;
std::vector<ASCH_ADDITIONAL_FILE> m_altiumAdditional;
std::map<int, ASCH_SYMBOL> m_altiumComponents;
std::map<int, int> m_altiumImplementationList;