mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-04-11 14:20:10 +00:00
Fix compatibility with EasyEDA/LCEDA Pro v2.2.26
Fixes https://gitlab.com/kicad/code/kicad/-/issues/18620
This commit is contained in:
parent
660d26e572
commit
16d9fa7f25
common/io/easyedapro
pcbnew/pcb_io/easyedapro
@ -245,8 +245,17 @@ std::vector<nlohmann::json> EASYEDAPRO::ParseJsonLines( wxInputStream& aInput,
|
||||
{
|
||||
try
|
||||
{
|
||||
nlohmann::json js = nlohmann::json::parse( txt.ReadLine() );
|
||||
lines.emplace_back( js );
|
||||
wxString line = txt.ReadLine();
|
||||
|
||||
if( !line.IsEmpty() )
|
||||
{
|
||||
nlohmann::json js = nlohmann::json::parse( line );
|
||||
lines.emplace_back( js );
|
||||
}
|
||||
else
|
||||
{
|
||||
lines.emplace_back( nlohmann::json() );
|
||||
}
|
||||
}
|
||||
catch( nlohmann::json::exception& e )
|
||||
{
|
||||
@ -259,3 +268,42 @@ std::vector<nlohmann::json> EASYEDAPRO::ParseJsonLines( wxInputStream& aInput,
|
||||
|
||||
return lines;
|
||||
}
|
||||
|
||||
|
||||
std::vector<std::vector<nlohmann::json>>
|
||||
EASYEDAPRO::ParseJsonLinesWithSeparation( wxInputStream& aInput, const wxString& aSource )
|
||||
{
|
||||
wxTextInputStream txt( aInput, wxS( " " ), wxConvUTF8 );
|
||||
|
||||
int currentLine = 1;
|
||||
|
||||
std::vector<std::vector<nlohmann::json>> lineBlocks;
|
||||
lineBlocks.emplace_back();
|
||||
|
||||
while( aInput.CanRead() )
|
||||
{
|
||||
try
|
||||
{
|
||||
wxString line = txt.ReadLine();
|
||||
|
||||
if( !line.IsEmpty() )
|
||||
{
|
||||
nlohmann::json js = nlohmann::json::parse( line );
|
||||
lineBlocks.back().emplace_back( js );
|
||||
}
|
||||
else
|
||||
{
|
||||
lineBlocks.emplace_back();
|
||||
}
|
||||
}
|
||||
catch( nlohmann::json::exception& e )
|
||||
{
|
||||
wxLogWarning( wxString::Format( _( "Cannot parse JSON line %d in '%s': %s" ),
|
||||
currentLine, aSource, e.what() ) );
|
||||
}
|
||||
|
||||
currentLine++;
|
||||
}
|
||||
|
||||
return lineBlocks;
|
||||
}
|
||||
|
@ -57,6 +57,12 @@ void IterateZipFiles(
|
||||
|
||||
std::vector<nlohmann::json> ParseJsonLines( wxInputStream& aInput, const wxString& aSource );
|
||||
|
||||
/**
|
||||
* Multiple document types (e.g. footprint and PCB) can be put into a single file, separated by empty line.
|
||||
*/
|
||||
std::vector<std::vector<nlohmann::json>> ParseJsonLinesWithSeparation( wxInputStream& aInput,
|
||||
const wxString& aSource );
|
||||
|
||||
} // namespace EASYEDAPRO
|
||||
|
||||
|
||||
|
@ -36,7 +36,9 @@ void EASYEDAPRO::from_json( const nlohmann::json& j, EASYEDAPRO::SCH_ATTR& d )
|
||||
d.id = j.at( 1 ).get<wxString>();
|
||||
d.parentId = j.at( 2 ).get<wxString>();
|
||||
d.key = j.at( 3 ).get<wxString>();
|
||||
d.value = j.at( 4 ).get<wxString>();
|
||||
|
||||
if( j.at( 4 ).is_string() )
|
||||
d.value = j.at( 4 ).get<wxString>();
|
||||
|
||||
if( j.at( 5 ).is_number() )
|
||||
d.keyVisible = j.at( 5 ).get<int>();
|
||||
|
@ -122,6 +122,7 @@ BOARD* PCB_IO_EASYEDAPRO::LoadBoard( const wxString& aFileName, BOARD* aAppendTo
|
||||
PCB_IO_EASYEDAPRO_PARSER parser( nullptr, nullptr );
|
||||
|
||||
wxFileName fname( aFileName );
|
||||
wxString fpLibName = EASYEDAPRO::ShortenLibName( fname.GetName() );
|
||||
|
||||
if( fname.GetExt() == wxS( "epro" ) || fname.GetExt() == wxS( "zip" ) )
|
||||
{
|
||||
@ -167,7 +168,71 @@ BOARD* PCB_IO_EASYEDAPRO::LoadBoard( const wxString& aFileName, BOARD* aAppendTo
|
||||
if( pcbUuid != pcbToLoad )
|
||||
EASY_IT_CONTINUE;
|
||||
|
||||
std::vector<nlohmann::json> lines = EASYEDAPRO::ParseJsonLines( zip, name );
|
||||
std::vector<nlohmann::json>* pcbLines = nullptr;
|
||||
|
||||
std::vector<std::vector<nlohmann::json>> lineBlocks =
|
||||
EASYEDAPRO::ParseJsonLinesWithSeparation( zip, name );
|
||||
|
||||
if( lineBlocks.empty() )
|
||||
EASY_IT_CONTINUE;
|
||||
|
||||
if( lineBlocks.size() > 1 )
|
||||
{
|
||||
for( std::vector<nlohmann::json>& block : lineBlocks )
|
||||
{
|
||||
wxString docType;
|
||||
nlohmann::json headData;
|
||||
|
||||
for( const nlohmann::json& line : block )
|
||||
{
|
||||
if( line.size() < 2 )
|
||||
continue;
|
||||
|
||||
if( !line.at( 0 ).is_string() )
|
||||
continue;
|
||||
|
||||
wxString lineType = line.at( 0 ).get<wxString>();
|
||||
|
||||
if( lineType == wxS( "DOCTYPE" ) )
|
||||
{
|
||||
if( !line.at( 1 ).is_string() )
|
||||
continue;
|
||||
|
||||
docType = line.at( 1 ).get<wxString>();
|
||||
}
|
||||
else if( lineType == wxS( "HEAD" ) )
|
||||
{
|
||||
if( !line.at( 1 ).is_object() )
|
||||
continue;
|
||||
|
||||
headData = line.at( 1 );
|
||||
}
|
||||
}
|
||||
|
||||
if( docType == wxS( "FOOTPRINT" ) )
|
||||
{
|
||||
wxString fpUuid = headData.at( "uuid" );
|
||||
wxString fpTitle = headData.at( "title" );
|
||||
|
||||
FOOTPRINT* footprint = parser.ParseFootprint( project, fpUuid, block );
|
||||
|
||||
if( !footprint )
|
||||
EASY_IT_CONTINUE;
|
||||
|
||||
LIB_ID fpID = EASYEDAPRO::ToKiCadLibID( fpLibName, fpTitle );
|
||||
footprint->SetFPID( fpID );
|
||||
|
||||
m_projectData->m_Footprints.emplace( fpUuid, footprint );
|
||||
}
|
||||
else if( docType == wxS( "PCB" ) )
|
||||
{
|
||||
pcbLines = █
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( pcbLines == nullptr )
|
||||
pcbLines = &lineBlocks[0];
|
||||
|
||||
wxString boardKey = pcbUuid + wxS( "_0" );
|
||||
wxScopedCharBuffer cb = boardKey.ToUTF8();
|
||||
@ -177,7 +242,7 @@ BOARD* PCB_IO_EASYEDAPRO::LoadBoard( const wxString& aFileName, BOARD* aAppendTo
|
||||
get_def( m_projectData->m_Poured, boardPouredKey );
|
||||
|
||||
parser.ParseBoard( m_board, project, m_projectData->m_Footprints,
|
||||
m_projectData->m_Blobs, boardPoured, lines,
|
||||
m_projectData->m_Blobs, boardPoured, *pcbLines,
|
||||
EASYEDAPRO::ShortenLibName( fname.GetName() ) );
|
||||
|
||||
EASY_IT_BREAK;
|
||||
|
@ -794,50 +794,53 @@ FOOTPRINT* PCB_IO_EASYEDAPRO_PARSER::ParseFootprint( const nlohmann::json&
|
||||
|
||||
nlohmann::json polyDataList = line.at( 7 );
|
||||
|
||||
if( !polyDataList.at( 0 ).is_array() )
|
||||
polyDataList = nlohmann::json::array( { polyDataList } );
|
||||
|
||||
std::vector<SHAPE_LINE_CHAIN> contours;
|
||||
for( nlohmann::json& polyData : polyDataList )
|
||||
if( !polyDataList.is_null() && !polyDataList.empty() )
|
||||
{
|
||||
SHAPE_LINE_CHAIN contour = ParseContour( polyData, false );
|
||||
contour.SetClosed( true );
|
||||
if( !polyDataList.at( 0 ).is_array() )
|
||||
polyDataList = nlohmann::json::array( { polyDataList } );
|
||||
|
||||
contours.push_back( contour );
|
||||
}
|
||||
std::vector<SHAPE_LINE_CHAIN> contours;
|
||||
for( nlohmann::json& polyData : polyDataList )
|
||||
{
|
||||
SHAPE_LINE_CHAIN contour = ParseContour( polyData, false );
|
||||
contour.SetClosed( true );
|
||||
|
||||
SHAPE_POLY_SET polySet;
|
||||
contours.push_back( contour );
|
||||
}
|
||||
|
||||
for( SHAPE_LINE_CHAIN& contour : contours )
|
||||
polySet.AddOutline( contour );
|
||||
SHAPE_POLY_SET polySet;
|
||||
|
||||
polySet.RebuildHolesFromContours();
|
||||
for( SHAPE_LINE_CHAIN& contour : contours )
|
||||
polySet.AddOutline( contour );
|
||||
|
||||
std::unique_ptr<PCB_GROUP> group;
|
||||
polySet.RebuildHolesFromContours();
|
||||
|
||||
if( polySet.OutlineCount() > 1 )
|
||||
group = std::make_unique<PCB_GROUP>( footprint );
|
||||
std::unique_ptr<PCB_GROUP> group;
|
||||
|
||||
BOX2I polyBBox = polySet.BBox();
|
||||
if( polySet.OutlineCount() > 1 )
|
||||
group = std::make_unique<PCB_GROUP>( footprint );
|
||||
|
||||
for( const SHAPE_POLY_SET::POLYGON& poly : polySet.CPolygons() )
|
||||
{
|
||||
std::unique_ptr<PCB_SHAPE> shape =
|
||||
std::make_unique<PCB_SHAPE>( footprint, SHAPE_T::POLY );
|
||||
BOX2I polyBBox = polySet.BBox();
|
||||
|
||||
shape->SetFilled( true );
|
||||
shape->SetPolyShape( poly );
|
||||
shape->SetLayer( klayer );
|
||||
shape->SetWidth( 0 );
|
||||
for( const SHAPE_POLY_SET::POLYGON& poly : polySet.CPolygons() )
|
||||
{
|
||||
std::unique_ptr<PCB_SHAPE> shape =
|
||||
std::make_unique<PCB_SHAPE>( footprint, SHAPE_T::POLY );
|
||||
|
||||
shape->SetFilled( true );
|
||||
shape->SetPolyShape( poly );
|
||||
shape->SetLayer( klayer );
|
||||
shape->SetWidth( 0 );
|
||||
|
||||
if( group )
|
||||
group->AddItem( shape.get() );
|
||||
|
||||
footprint->Add( shape.release(), ADD_MODE::APPEND );
|
||||
}
|
||||
|
||||
if( group )
|
||||
group->AddItem( shape.get() );
|
||||
|
||||
footprint->Add( shape.release(), ADD_MODE::APPEND );
|
||||
footprint->Add( group.release(), ADD_MODE::APPEND );
|
||||
}
|
||||
|
||||
if( group )
|
||||
footprint->Add( group.release(), ADD_MODE::APPEND );
|
||||
}
|
||||
else if( type == wxS( "ATTR" ) )
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user