CADSTAR PCB Archive Importer: Parse LIBRARY section + code refactoring
code refactoring: - Renamed CADSTAR_COMMON to CADSTAR_ARCHIVE_COMMON - Renamed CPA_FILE to CADSTAR_PCB_ARCHIVE_PARSER - Made CADSTAR_PCB_ARCHIVE_PARSER a derived class of CADSTAR_ARCHIVE_COMMON - Moved all structures in cadstar_pcb_archive_parser.h/.cpp to be defined inside CADSTAR_PCB_ARCHIVE_PARSER class
This commit is contained in:
parent
0ce95f2803
commit
4c2f38f1ad
|
@ -5,7 +5,7 @@ include_directories( . )
|
||||||
set( CADSTAR2PCBNEW_SRCS
|
set( CADSTAR2PCBNEW_SRCS
|
||||||
cadstar_pcb_archive_plugin.cpp
|
cadstar_pcb_archive_plugin.cpp
|
||||||
cadstar_pcb_archive_parser.cpp
|
cadstar_pcb_archive_parser.cpp
|
||||||
cadstar_common.cpp
|
cadstar_archive_common.cpp
|
||||||
cadstar_pcb.cpp
|
cadstar_pcb.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,403 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2020 Roberto Fernandez Bautista <@Qbort>
|
||||||
|
* Copyright (C) 2020 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 as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file cadstar_common.cpp
|
||||||
|
* @brief Helper functions and common defines
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <cadstar_archive_common.h>
|
||||||
|
|
||||||
|
|
||||||
|
void CADSTAR_ARCHIVE_COMMON::EVALUE::Parse( XNODE* aNode )
|
||||||
|
{
|
||||||
|
wxASSERT( aNode->GetName() == wxT( "E" ) );
|
||||||
|
|
||||||
|
if( ( !GetXmlAttributeIDString( aNode, 0 ).ToLong( &Base ) )
|
||||||
|
|| ( !GetXmlAttributeIDString( aNode, 1 ).ToLong( &Exponent ) ) )
|
||||||
|
THROW_PARSING_IO_ERROR( wxT( "Base and Exponent" ),
|
||||||
|
wxString::Format(
|
||||||
|
"%s->%s", aNode->GetParent()->GetName(), aNode->GetParent()->GetName() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CADSTAR_ARCHIVE_COMMON::POINT::Parse( XNODE* aNode )
|
||||||
|
{
|
||||||
|
wxASSERT( aNode->GetName() == wxT( "PT" ) );
|
||||||
|
|
||||||
|
X = GetXmlAttributeIDLong( aNode, 0 );
|
||||||
|
Y = GetXmlAttributeIDLong( aNode, 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool CADSTAR_ARCHIVE_COMMON::VERTEX::IsVertex( XNODE* aNode )
|
||||||
|
{
|
||||||
|
wxString aNodeName = aNode->GetName();
|
||||||
|
|
||||||
|
if( aNodeName == wxT( "PT" ) || aNodeName == wxT( "ACWARC" ) || aNodeName == wxT( "CWARC" )
|
||||||
|
|| aNodeName == wxT( "CWSEMI" ) || aNodeName == wxT( "ACWSEMI" ) )
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CADSTAR_ARCHIVE_COMMON::VERTEX::Parse( XNODE* aNode )
|
||||||
|
{
|
||||||
|
wxASSERT( IsVertex( aNode ) );
|
||||||
|
|
||||||
|
wxString aNodeName = aNode->GetName();
|
||||||
|
|
||||||
|
if( aNodeName == wxT( "PT" ) )
|
||||||
|
{
|
||||||
|
Type = VERTEX_TYPE::POINT;
|
||||||
|
Center.X = UNDEFINED_VALUE;
|
||||||
|
Center.Y = UNDEFINED_VALUE;
|
||||||
|
End.Parse( aNode );
|
||||||
|
}
|
||||||
|
else if( aNodeName == wxT( "ACWARC" ) || aNodeName == wxT( "CWARC" ) )
|
||||||
|
{
|
||||||
|
if( aNodeName == wxT( "ACWARC" ) )
|
||||||
|
Type = VERTEX_TYPE::ANTICLOCKWISE_ARC;
|
||||||
|
else
|
||||||
|
Type = VERTEX_TYPE::CLOCKWISE_ARC;
|
||||||
|
|
||||||
|
std::vector<POINT> pts = ParseAllChildPoints( aNode, true, 2 );
|
||||||
|
|
||||||
|
Center = pts[0];
|
||||||
|
End = pts[1];
|
||||||
|
}
|
||||||
|
else if( aNodeName == wxT( "ACWSEMI" ) || aNodeName == wxT( "CWSEMI" ) )
|
||||||
|
{
|
||||||
|
if( aNodeName == wxT( "ACWSEMI" ) )
|
||||||
|
Type = VERTEX_TYPE::ANTICLOCKWISE_SEMICIRCLE;
|
||||||
|
else
|
||||||
|
Type = VERTEX_TYPE::CLOCKWISE_SEMICIRCLE;
|
||||||
|
|
||||||
|
Center.X = UNDEFINED_VALUE;
|
||||||
|
Center.Y = UNDEFINED_VALUE;
|
||||||
|
|
||||||
|
std::vector<POINT> pts = ParseAllChildPoints( aNode, true, 1 );
|
||||||
|
|
||||||
|
End = pts[0];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wxASSERT_MSG( true, wxT( "Unknown VERTEX type" ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
double CADSTAR_ARCHIVE_COMMON::EVALUE::GetDouble()
|
||||||
|
{
|
||||||
|
return Base * std::pow( 10.0, Exponent );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CADSTAR_ARCHIVE_COMMON::InsertAttributeAtEnd( XNODE* aNode, wxString aValue )
|
||||||
|
{
|
||||||
|
wxString result, paramName = "attr0";
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
while( aNode->GetAttribute( paramName, &result ) )
|
||||||
|
{
|
||||||
|
paramName = wxT( "attr" );
|
||||||
|
paramName << i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
aNode->AddAttribute( paramName, aValue );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
XNODE* CADSTAR_ARCHIVE_COMMON::LoadArchiveFile(
|
||||||
|
const wxString& aFileName, const wxString& aFileTypeIdentifier )
|
||||||
|
{
|
||||||
|
KEYWORD emptyKeywords[1] = {};
|
||||||
|
XNODE * iNode = NULL, *cNode = NULL;
|
||||||
|
int tok;
|
||||||
|
bool cadstarFileCheckDone = false;
|
||||||
|
wxString str;
|
||||||
|
wxCSConv win1252( wxT( "windows-1252" ) );
|
||||||
|
wxMBConv* conv = &win1252; // Initial testing suggests file encoding to be Windows-1252
|
||||||
|
// More samples required.
|
||||||
|
FILE* fp = wxFopen( aFileName, wxT( "rt" ) );
|
||||||
|
|
||||||
|
if( !fp )
|
||||||
|
THROW_IO_ERROR( wxString::Format( _( "Cannot open file '%s'" ), aFileName ) );
|
||||||
|
|
||||||
|
DSNLEXER lexer( emptyKeywords, 0, fp, aFileName );
|
||||||
|
|
||||||
|
while( ( tok = lexer.NextTok() ) != DSN_EOF )
|
||||||
|
{
|
||||||
|
if( tok == DSN_RIGHT )
|
||||||
|
{
|
||||||
|
cNode = iNode;
|
||||||
|
if( cNode )
|
||||||
|
{
|
||||||
|
iNode = cNode->GetParent();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//too many closing brackets
|
||||||
|
THROW_IO_ERROR( _( "The selected file is not valid or might be corrupt!" ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( tok == DSN_LEFT )
|
||||||
|
{
|
||||||
|
tok = lexer.NextTok();
|
||||||
|
str = wxString( lexer.CurText(), *conv );
|
||||||
|
cNode = new XNODE( wxXML_ELEMENT_NODE, str );
|
||||||
|
|
||||||
|
if( iNode )
|
||||||
|
{
|
||||||
|
//we will add it as attribute as well as child node
|
||||||
|
InsertAttributeAtEnd( iNode, str );
|
||||||
|
iNode->AddChild( cNode );
|
||||||
|
}
|
||||||
|
else if( !cadstarFileCheckDone )
|
||||||
|
{
|
||||||
|
|
||||||
|
if( cNode->GetName() != aFileTypeIdentifier )
|
||||||
|
{
|
||||||
|
THROW_IO_ERROR( _( "The selected file is not valid or might be corrupt!" ) );
|
||||||
|
}
|
||||||
|
cadstarFileCheckDone = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
iNode = cNode;
|
||||||
|
}
|
||||||
|
else if( iNode )
|
||||||
|
{
|
||||||
|
str = wxString( lexer.CurText(), *conv );
|
||||||
|
//Insert even if string is empty
|
||||||
|
InsertAttributeAtEnd( iNode, str );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//not enough closing brackets
|
||||||
|
THROW_IO_ERROR( _( "The selected file is not valid or might be corrupt!" ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( iNode != NULL )
|
||||||
|
{
|
||||||
|
//not enough closing brackets
|
||||||
|
THROW_IO_ERROR( _( "The selected file is not valid or might be corrupt!" ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( cNode )
|
||||||
|
{
|
||||||
|
return cNode;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//no data?
|
||||||
|
THROW_IO_ERROR( _( "The selected file is not valid or might be corrupt!" ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxString CADSTAR_ARCHIVE_COMMON::GetXmlAttributeIDString( XNODE* aNode, unsigned int aID )
|
||||||
|
{
|
||||||
|
wxString attrName, retVal;
|
||||||
|
attrName = "attr";
|
||||||
|
attrName << aID;
|
||||||
|
|
||||||
|
if( !aNode->GetAttribute( attrName, &retVal ) )
|
||||||
|
THROW_MISSING_PARAMETER_IO_ERROR( std::to_string( aID ), aNode->GetName() );
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
long CADSTAR_ARCHIVE_COMMON::GetXmlAttributeIDLong( XNODE* aNode, unsigned int aID )
|
||||||
|
{
|
||||||
|
long retVal;
|
||||||
|
|
||||||
|
if( !GetXmlAttributeIDString( aNode, aID ).ToLong( &retVal ) )
|
||||||
|
THROW_PARSING_IO_ERROR( std::to_string( aID ), aNode->GetName() );
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CADSTAR_ARCHIVE_COMMON::CheckNoChildNodes( XNODE* aNode )
|
||||||
|
{
|
||||||
|
if( aNode->GetChildren() )
|
||||||
|
{
|
||||||
|
THROW_UNKNOWN_NODE_IO_ERROR( aNode->GetChildren()->GetName(), aNode->GetName() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CADSTAR_ARCHIVE_COMMON::CheckNoNextNodes( XNODE* aNode )
|
||||||
|
{
|
||||||
|
if( aNode->GetNext() )
|
||||||
|
{
|
||||||
|
THROW_UNKNOWN_NODE_IO_ERROR( aNode->GetNext()->GetName(), aNode->GetParent()->GetName() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CADSTAR_ARCHIVE_COMMON::ParseChildEValue( XNODE* aNode, EVALUE& aValueToParse )
|
||||||
|
{
|
||||||
|
if( aNode->GetChildren()->GetName() == wxT( "E" ) )
|
||||||
|
{
|
||||||
|
aValueToParse.Parse( aNode->GetChildren() );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
THROW_UNKNOWN_NODE_IO_ERROR( aNode->GetChildren()->GetName(), aNode->GetName() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<CADSTAR_ARCHIVE_COMMON::POINT> CADSTAR_ARCHIVE_COMMON::ParseAllChildPoints(
|
||||||
|
XNODE* aNode, bool aTestAllChildNodes, int aExpectedNumPoints )
|
||||||
|
{
|
||||||
|
std::vector<POINT> retVal;
|
||||||
|
|
||||||
|
XNODE* cNode = aNode->GetChildren();
|
||||||
|
|
||||||
|
for( ; cNode; cNode = cNode->GetNext() )
|
||||||
|
{
|
||||||
|
if( cNode->GetName() == wxT( "PT" ) )
|
||||||
|
{
|
||||||
|
POINT pt;
|
||||||
|
//TODO try.. catch + throw again with more detailed error information
|
||||||
|
pt.Parse( cNode );
|
||||||
|
retVal.push_back( pt );
|
||||||
|
}
|
||||||
|
else if( aTestAllChildNodes )
|
||||||
|
THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( aExpectedNumPoints != UNDEFINED_VALUE && retVal.size() != aExpectedNumPoints )
|
||||||
|
THROW_IO_ERROR( wxString::Format(
|
||||||
|
_( "Unexpected number of points in '%s'. Found %d but expected %d." ),
|
||||||
|
aNode->GetName(), retVal.size(), aExpectedNumPoints ) );
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::vector<CADSTAR_ARCHIVE_COMMON::VERTEX> CADSTAR_ARCHIVE_COMMON::ParseAllChildVertices(
|
||||||
|
XNODE* aNode, bool aTestAllChildNodes )
|
||||||
|
{
|
||||||
|
std::vector<VERTEX> retVal;
|
||||||
|
|
||||||
|
XNODE* cNode = aNode->GetChildren();
|
||||||
|
|
||||||
|
for( ; cNode; cNode = cNode->GetNext() )
|
||||||
|
{
|
||||||
|
if( VERTEX::IsVertex( cNode ) )
|
||||||
|
{
|
||||||
|
VERTEX vertex;
|
||||||
|
//TODO try.. catch + throw again with more detailed error information
|
||||||
|
vertex.Parse( cNode );
|
||||||
|
retVal.push_back( vertex );
|
||||||
|
}
|
||||||
|
else if( aTestAllChildNodes )
|
||||||
|
THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
|
||||||
|
}
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::vector<CADSTAR_ARCHIVE_COMMON::CUTOUT> CADSTAR_ARCHIVE_COMMON::ParseAllChildCutouts(
|
||||||
|
XNODE* aNode, bool aTestAllChildNodes )
|
||||||
|
{
|
||||||
|
std::vector<CUTOUT> retVal;
|
||||||
|
|
||||||
|
XNODE* cNode = aNode->GetChildren();
|
||||||
|
|
||||||
|
for( ; cNode; cNode = cNode->GetNext() )
|
||||||
|
{
|
||||||
|
if( cNode->GetName() == wxT( "CUTOUT" ) )
|
||||||
|
{
|
||||||
|
CUTOUT cutout;
|
||||||
|
//TODO try.. catch + throw again with more detailed error information
|
||||||
|
cutout.Parse( cNode );
|
||||||
|
retVal.push_back( cutout );
|
||||||
|
}
|
||||||
|
else if( aTestAllChildNodes )
|
||||||
|
THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
|
||||||
|
}
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CADSTAR_ARCHIVE_COMMON::CUTOUT::Parse( XNODE* aNode )
|
||||||
|
{
|
||||||
|
wxASSERT( aNode->GetName() == wxT( "CUTOUT" ) );
|
||||||
|
|
||||||
|
Vertices = ParseAllChildVertices( aNode, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool CADSTAR_ARCHIVE_COMMON::SHAPE::IsShape( XNODE* aNode )
|
||||||
|
{
|
||||||
|
wxString aNodeName = aNode->GetName();
|
||||||
|
|
||||||
|
if( aNodeName == wxT( "OPENSHAPE" ) || aNodeName == wxT( "OUTLINE" )
|
||||||
|
|| aNodeName == wxT( "SOLID" ) || aNodeName == wxT( "HATCHED" ) )
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CADSTAR_ARCHIVE_COMMON::SHAPE::Parse( XNODE* aNode )
|
||||||
|
{
|
||||||
|
wxASSERT( IsShape( aNode ) );
|
||||||
|
|
||||||
|
wxString aNodeName = aNode->GetName();
|
||||||
|
|
||||||
|
if( aNodeName == wxT( "OPENSHAPE" ) )
|
||||||
|
{
|
||||||
|
Type = SHAPE_TYPE::OPENSHAPE;
|
||||||
|
Vertices = ParseAllChildVertices( aNode, true );
|
||||||
|
Cutouts.clear();
|
||||||
|
HatchCodeID = wxEmptyString;
|
||||||
|
}
|
||||||
|
else if( aNodeName == wxT( "OUTLINE" ) )
|
||||||
|
{
|
||||||
|
Type = SHAPE_TYPE::OUTLINE;
|
||||||
|
Vertices = ParseAllChildVertices( aNode, false );
|
||||||
|
Cutouts = ParseAllChildCutouts( aNode, false );
|
||||||
|
HatchCodeID = wxEmptyString;
|
||||||
|
}
|
||||||
|
else if( aNodeName == wxT( "SOLID" ) )
|
||||||
|
{
|
||||||
|
Type = SHAPE_TYPE::SOLID;
|
||||||
|
Vertices = ParseAllChildVertices( aNode, false );
|
||||||
|
Cutouts = ParseAllChildCutouts( aNode, false );
|
||||||
|
HatchCodeID = wxEmptyString;
|
||||||
|
}
|
||||||
|
else if( aNodeName == wxT( "HATCHED" ) )
|
||||||
|
{
|
||||||
|
Type = SHAPE_TYPE::HATCHED;
|
||||||
|
Vertices = ParseAllChildVertices( aNode, false );
|
||||||
|
Cutouts = ParseAllChildCutouts( aNode, false );
|
||||||
|
HatchCodeID = GetXmlAttributeIDString( aNode, 0 );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
wxASSERT_MSG( true, wxT( "Unknown SHAPE type" ) );
|
||||||
|
}
|
|
@ -0,0 +1,251 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2020 Roberto Fernandez Bautista <@Qbort>
|
||||||
|
* Copyright (C) 2020 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 as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file cadstar_common.h
|
||||||
|
* @brief Helper functions and common defines
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CADSTAR_ARHIVE_COMMON_H_
|
||||||
|
#define CADSTAR_ARHIVE_COMMON_H_
|
||||||
|
|
||||||
|
#include <class_board.h>
|
||||||
|
#include <dsnlexer.h>
|
||||||
|
#include <macros.h>
|
||||||
|
#include <vector>
|
||||||
|
#include <wx/wx.h>
|
||||||
|
#include <wx/xml/xml.h>
|
||||||
|
#include <xnode.h>
|
||||||
|
|
||||||
|
// THROW_IO_ERROR definitions to ensure consident wording is used in the error messages
|
||||||
|
|
||||||
|
#define THROW_MISSING_NODE_IO_ERROR( nodename, location ) \
|
||||||
|
THROW_IO_ERROR( wxString::Format( _( "Missing node '%s' in '%s'" ), nodename, location ) )
|
||||||
|
|
||||||
|
#define THROW_UNKNOWN_NODE_IO_ERROR( nodename, location ) \
|
||||||
|
THROW_IO_ERROR( wxString::Format( _( "Unknown node '%s' in '%s'" ), nodename, location ) )
|
||||||
|
|
||||||
|
#define THROW_MISSING_PARAMETER_IO_ERROR( param, location ) \
|
||||||
|
THROW_IO_ERROR( wxString::Format( _( "Missing Parameter '%s' in '%s'" ), param, location ) )
|
||||||
|
|
||||||
|
#define THROW_UNKNOWN_PARAMETER_IO_ERROR( param, location ) \
|
||||||
|
THROW_IO_ERROR( wxString::Format( _( "Unknown Parameter '%s' in '%s'" ), param, location ) )
|
||||||
|
|
||||||
|
#define THROW_PARSING_IO_ERROR( param, location ) \
|
||||||
|
THROW_IO_ERROR( wxString::Format( _( "Unable to parse '%s' in '%s'" ), param, location ) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Helper functions and common structures for CADSTAR PCB and Schematic archive files.
|
||||||
|
*/
|
||||||
|
class CADSTAR_ARCHIVE_COMMON
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const long UNDEFINED_VALUE = -1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Represents a floating value in E notation
|
||||||
|
*/
|
||||||
|
struct EVALUE
|
||||||
|
{
|
||||||
|
long Base = 0;
|
||||||
|
long Exponent = 0;
|
||||||
|
|
||||||
|
void Parse( XNODE* aNode );
|
||||||
|
double GetDouble();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Represents a point in x,y coordinates
|
||||||
|
*/
|
||||||
|
struct POINT
|
||||||
|
{
|
||||||
|
long X = UNDEFINED_VALUE;
|
||||||
|
long Y = UNDEFINED_VALUE;
|
||||||
|
|
||||||
|
void Parse( XNODE* aNode );
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
enum class VERTEX_TYPE
|
||||||
|
{
|
||||||
|
POINT,
|
||||||
|
CLOCKWISE_ARC,
|
||||||
|
CLOCKWISE_SEMICIRCLE,
|
||||||
|
ANTICLOCKWISE_ARC,
|
||||||
|
ANTICLOCKWISE_SEMICIRCLE
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Represents a vertex in a shape. E.g. A circle is made by two semicircles with the same
|
||||||
|
* center point.
|
||||||
|
*/
|
||||||
|
struct VERTEX
|
||||||
|
{
|
||||||
|
VERTEX_TYPE Type;
|
||||||
|
POINT Center;
|
||||||
|
POINT End;
|
||||||
|
|
||||||
|
static bool IsVertex( XNODE* aNode );
|
||||||
|
void Parse( XNODE* aNode );
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Represents a cutout in a closed shape (e.g. OUTLINE)
|
||||||
|
*/
|
||||||
|
struct CUTOUT
|
||||||
|
{
|
||||||
|
std::vector<VERTEX> Vertices;
|
||||||
|
|
||||||
|
void Parse( XNODE* aNode );
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
enum class SHAPE_TYPE
|
||||||
|
{
|
||||||
|
OPENSHAPE, //< Unfilled open shape. Cannot have cutouts.
|
||||||
|
OUTLINE, //< Unfilled closed shape.
|
||||||
|
SOLID, //< Filled closed shape (solid fill).
|
||||||
|
HATCHED //< Filled closed shape (hatch fill).
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct SHAPE
|
||||||
|
{
|
||||||
|
SHAPE_TYPE Type;
|
||||||
|
std::vector<VERTEX> Vertices;
|
||||||
|
std::vector<CUTOUT> Cutouts; ///< Not Applicable to OPENSHAPE Type
|
||||||
|
wxString HatchCodeID; ///< Only Applicable for HATCHED Type
|
||||||
|
|
||||||
|
static bool IsShape( XNODE* aNode );
|
||||||
|
void Parse( XNODE* aNode );
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static void InsertAttributeAtEnd( XNODE* aNode, wxString aValue );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reads a CADSTAR Archive file (S-parameter format)
|
||||||
|
* @param aFileName
|
||||||
|
* @param aFileTypeIdentifier Identifier of the first node in the file to check against.
|
||||||
|
E.g. "CADSTARPCB"
|
||||||
|
* @return XNODE pointing to the top of the tree for further parsing. Each node has the first
|
||||||
|
* element as the node's name and subsequent elements as node attributes ("attr0",
|
||||||
|
* "attr1", "attr2", etc.). Caller is responsible for deleting to avoid memory leaks.
|
||||||
|
* @throws IO_ERROR
|
||||||
|
*/
|
||||||
|
static XNODE* LoadArchiveFile( const wxString& aFileName, const wxString& aFileTypeIdentifier );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* @param aNode
|
||||||
|
* @param aID
|
||||||
|
* @return returns the value of attribute "attrX" in aNode where 'X' is aID
|
||||||
|
* @throws IO_ERROR if attribute does not exist
|
||||||
|
*/
|
||||||
|
static wxString GetXmlAttributeIDString( XNODE* aNode, unsigned int aID );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* @param aNode
|
||||||
|
* @param aID
|
||||||
|
* @return returns the value of attribute "attrX" in aNode where 'X' is aID
|
||||||
|
* @throws IO_ERROR if attribute does not exist
|
||||||
|
*/
|
||||||
|
static long GetXmlAttributeIDLong( XNODE* aNode, unsigned int aID );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* @param aNode
|
||||||
|
* @throw IO_ERROR if a child node was found
|
||||||
|
*/
|
||||||
|
static void CheckNoChildNodes( XNODE* aNode );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* @param aNode
|
||||||
|
* @throw IO_ERROR if a node adjacent to aNode was found
|
||||||
|
*/
|
||||||
|
static void CheckNoNextNodes( XNODE* aNode );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* @param aNode with a child node containing an EVALUE
|
||||||
|
* @param aValueToParse
|
||||||
|
* @throw IO_ERROR if unable to parse or node is not an EVALUE
|
||||||
|
*/
|
||||||
|
static void ParseChildEValue( XNODE* aNode, EVALUE& aValueToParse );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief if no childs are present, it just returns an empty
|
||||||
|
* vector (without throwing an exception)
|
||||||
|
* @param aNode containing a series of POINT objects
|
||||||
|
* @param aTestAllChildNodes
|
||||||
|
* @param aExpectedNumPoints if UNDEFINED_VALUE (i.e. -1), this is check is disabled
|
||||||
|
* @return std::vector containing all POINT objects
|
||||||
|
* @throw IO_ERROR if one of the following:
|
||||||
|
* - Unable to parse a POINT object
|
||||||
|
* - aTestAllChildNodes is true and one of the child nodes is not a valid POINT object
|
||||||
|
* - aExpectedNumPoints is non-negative and the number of POINT objects found is different
|
||||||
|
*/
|
||||||
|
static std::vector<POINT> ParseAllChildPoints( XNODE* aNode, bool aTestAllChildNodes = false,
|
||||||
|
int aExpectedNumPoints = UNDEFINED_VALUE );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief if no childs are present, it just returns an empty
|
||||||
|
* vector (without throwing an exception)
|
||||||
|
* @param aNode containing a series of VERTEX objects
|
||||||
|
* @param aTestAllChildNodes
|
||||||
|
* @param aExpectedNumPoints if -1, this is check is disabled
|
||||||
|
* @return std::vector containing all VERTEX objects
|
||||||
|
* @throw IO_ERROR if one of the following:
|
||||||
|
* - Unable to parse a VERTEX object
|
||||||
|
* - aTestAllChildNodes is true and one of the child nodes is not a valid VERTEX object
|
||||||
|
*/
|
||||||
|
static std::vector<VERTEX> ParseAllChildVertices(
|
||||||
|
XNODE* aNode, bool aTestAllChildNodes = false );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief if no childs are present, it just returns an empty
|
||||||
|
* vector (without throwing an exception)
|
||||||
|
* @param aNode containing a series of CUTOUT objects
|
||||||
|
* @param aTestAllChildNodes
|
||||||
|
* @param aExpectedNumPoints if -1, this is check is disabled
|
||||||
|
* @return std::vector containing all CUTOUT objects
|
||||||
|
* @throw IO_ERROR if one of the following:
|
||||||
|
* - Unable to parse a CUTOUT object
|
||||||
|
* - aTestAllChildNodes is true and one of the child nodes is not a valid CUTOUT object
|
||||||
|
*/
|
||||||
|
static std::vector<CUTOUT> ParseAllChildCutouts(
|
||||||
|
XNODE* aNode, bool aTestAllChildNodes = false );
|
||||||
|
|
||||||
|
|
||||||
|
}; // class CADSTAR_ARCHIVE_COMMON
|
||||||
|
|
||||||
|
#endif // CADSTAR_COMMON_H_
|
|
@ -1,253 +0,0 @@
|
||||||
/*
|
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2020 Roberto Fernandez Bautista <@Qbort>
|
|
||||||
* Copyright (C) 2020 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 as published by the
|
|
||||||
* Free Software Foundation, either version 3 of the License, or (at your
|
|
||||||
* option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file cadstar_common.cpp
|
|
||||||
* @brief Helper functions and common defines
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <cadstar_common.h>
|
|
||||||
|
|
||||||
|
|
||||||
void CADSTAR_COMMON::EVALUE::Parse( XNODE* aNode )
|
|
||||||
{
|
|
||||||
wxASSERT( aNode->GetName() == wxT( "E" ) );
|
|
||||||
|
|
||||||
if( ( !CADSTAR_COMMON::GetAttributeID( aNode, 0 ).ToLong( &Base ) )
|
|
||||||
|| ( !CADSTAR_COMMON::GetAttributeID( aNode, 1 ).ToLong( &Exponent ) ) )
|
|
||||||
THROW_PARSING_IO_ERROR( wxT( "Base and Exponent" ),
|
|
||||||
wxString::Format(
|
|
||||||
"%s->%s", aNode->GetParent()->GetName(), aNode->GetParent()->GetName() ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void CADSTAR_COMMON::POINT::Parse( XNODE* aNode )
|
|
||||||
{
|
|
||||||
wxASSERT( aNode->GetName() == wxT( "PT" ) );
|
|
||||||
|
|
||||||
X = CADSTAR_COMMON::GetAttributeIDLong( aNode, 0 );
|
|
||||||
Y = CADSTAR_COMMON::GetAttributeIDLong( aNode, 1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
double CADSTAR_COMMON::EVALUE::GetDouble()
|
|
||||||
{
|
|
||||||
return Base * std::pow( 10.0, Exponent );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void CADSTAR_COMMON::InsertAttributeAtEnd( XNODE* aNode, wxString aValue )
|
|
||||||
{
|
|
||||||
wxString result, paramName = "attr0";
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
while( aNode->GetAttribute( paramName, &result ) )
|
|
||||||
{
|
|
||||||
paramName = wxT( "attr" );
|
|
||||||
paramName << i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
aNode->AddAttribute( paramName, aValue );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
XNODE* CADSTAR_COMMON::LoadArchiveFile( const wxString& aFileName, FILE_TYPE aType )
|
|
||||||
{
|
|
||||||
KEYWORD emptyKeywords[1] = {};
|
|
||||||
XNODE * iNode = NULL, *cNode = NULL;
|
|
||||||
int tok;
|
|
||||||
bool cadstarFileCheckDone = false;
|
|
||||||
wxString str, fileIdentifier;
|
|
||||||
wxCSConv win1252( wxT( "windows-1252" ) );
|
|
||||||
wxMBConv* conv = &win1252; // Initial testing suggests file encoding to be Windows-1252
|
|
||||||
// More samples required.
|
|
||||||
FILE* fp = wxFopen( aFileName, wxT( "rt" ) );
|
|
||||||
|
|
||||||
if( !fp )
|
|
||||||
THROW_IO_ERROR( wxString::Format( _( "Cannot open file '%s'" ), aFileName ) );
|
|
||||||
|
|
||||||
|
|
||||||
switch( aType )
|
|
||||||
{
|
|
||||||
case FILE_TYPE::PCB_ARCHIVE:
|
|
||||||
fileIdentifier = wxT( "CADSTARPCB" );
|
|
||||||
break;
|
|
||||||
|
|
||||||
//add others here
|
|
||||||
// SCHEMATIC_ARCHIVE
|
|
||||||
// ...
|
|
||||||
|
|
||||||
default:
|
|
||||||
wxASSERT_MSG( true, "Unknown CADSTAR filetype specified" );
|
|
||||||
}
|
|
||||||
|
|
||||||
DSNLEXER lexer( emptyKeywords, 0, fp, aFileName );
|
|
||||||
|
|
||||||
while( ( tok = lexer.NextTok() ) != DSN_EOF )
|
|
||||||
{
|
|
||||||
if( tok == DSN_RIGHT )
|
|
||||||
{
|
|
||||||
cNode = iNode;
|
|
||||||
if( cNode )
|
|
||||||
{
|
|
||||||
iNode = cNode->GetParent();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//too many closing brackets
|
|
||||||
THROW_IO_ERROR( _( "The selected file is not valid or might be corrupt!" ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if( tok == DSN_LEFT )
|
|
||||||
{
|
|
||||||
tok = lexer.NextTok();
|
|
||||||
str = wxString( lexer.CurText(), *conv );
|
|
||||||
cNode = new XNODE( wxXML_ELEMENT_NODE, str );
|
|
||||||
|
|
||||||
if( iNode )
|
|
||||||
{
|
|
||||||
//we will add it as attribute as well as child node
|
|
||||||
InsertAttributeAtEnd( iNode, str );
|
|
||||||
iNode->AddChild( cNode );
|
|
||||||
}
|
|
||||||
else if( !cadstarFileCheckDone )
|
|
||||||
{
|
|
||||||
|
|
||||||
if( cNode->GetName() != fileIdentifier )
|
|
||||||
{
|
|
||||||
THROW_IO_ERROR( _( "The selected file is not valid or might be corrupt!" ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
iNode = cNode;
|
|
||||||
}
|
|
||||||
else if( iNode )
|
|
||||||
{
|
|
||||||
str = wxString( lexer.CurText(), *conv );
|
|
||||||
//Insert even if string is empty
|
|
||||||
InsertAttributeAtEnd( iNode, str );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//not enough closing brackets
|
|
||||||
THROW_IO_ERROR( _( "The selected file is not valid or might be corrupt!" ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( iNode != NULL )
|
|
||||||
{
|
|
||||||
//not enough closing brackets
|
|
||||||
THROW_IO_ERROR( _( "The selected file is not valid or might be corrupt!" ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( cNode )
|
|
||||||
{
|
|
||||||
return cNode;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//no data?
|
|
||||||
THROW_IO_ERROR( _( "The selected file is not valid or might be corrupt!" ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
wxString CADSTAR_COMMON::GetAttributeID( XNODE* aNode, unsigned int aID )
|
|
||||||
{
|
|
||||||
wxString attrName, retVal;
|
|
||||||
attrName = "attr";
|
|
||||||
attrName << aID;
|
|
||||||
|
|
||||||
if( !aNode->GetAttribute( attrName, &retVal ) )
|
|
||||||
THROW_MISSING_PARAMETER_IO_ERROR( std::to_string( aID ), aNode->GetName() );
|
|
||||||
|
|
||||||
return retVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
long CADSTAR_COMMON::GetAttributeIDLong( XNODE* aNode, unsigned int aID )
|
|
||||||
{
|
|
||||||
long retVal;
|
|
||||||
|
|
||||||
if( !CADSTAR_COMMON::GetAttributeID( aNode, aID ).ToLong( &retVal ) )
|
|
||||||
THROW_PARSING_IO_ERROR( std::to_string( aID ), aNode->GetName() );
|
|
||||||
|
|
||||||
return retVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void CADSTAR_COMMON::CheckNoChildNodes( XNODE* aNode )
|
|
||||||
{
|
|
||||||
if( aNode->GetChildren() )
|
|
||||||
{
|
|
||||||
THROW_UNKNOWN_NODE_IO_ERROR( aNode->GetChildren()->GetName(), aNode->GetName() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void CADSTAR_COMMON::CheckNoNextNodes( XNODE* aNode )
|
|
||||||
{
|
|
||||||
if( aNode->GetNext() )
|
|
||||||
{
|
|
||||||
THROW_UNKNOWN_NODE_IO_ERROR( aNode->GetNext()->GetName(), aNode->GetParent()->GetName() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void CADSTAR_COMMON::ParseChildEValue( XNODE* aNode, CADSTAR_COMMON::EVALUE& aValueToParse )
|
|
||||||
{
|
|
||||||
if( aNode->GetChildren()->GetName() == wxT( "E" ) )
|
|
||||||
{
|
|
||||||
aValueToParse.Parse( aNode->GetChildren() );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
THROW_UNKNOWN_NODE_IO_ERROR( aNode->GetChildren()->GetName(), aNode->GetName() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<CADSTAR_COMMON::POINT> CADSTAR_COMMON::ParseAllChildPoints(
|
|
||||||
XNODE* aNode, bool aTestAllChildNodes, int aExpectedNumPoints )
|
|
||||||
{
|
|
||||||
std::vector<CADSTAR_COMMON::POINT> retVal;
|
|
||||||
|
|
||||||
XNODE* cNode = aNode->GetChildren();
|
|
||||||
|
|
||||||
for( ; cNode; cNode = cNode->GetNext() )
|
|
||||||
{
|
|
||||||
if( cNode->GetName() == wxT( "PT" ) )
|
|
||||||
{
|
|
||||||
POINT pt;
|
|
||||||
//TODO try.. catch + throw again with more detailed error information
|
|
||||||
pt.Parse( cNode );
|
|
||||||
retVal.push_back( pt );
|
|
||||||
}
|
|
||||||
else if( aTestAllChildNodes )
|
|
||||||
THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( aExpectedNumPoints >= 0 && retVal.size() != aExpectedNumPoints )
|
|
||||||
THROW_IO_ERROR( wxString::Format(
|
|
||||||
_( "Unexpected number of points in '%s'. Found %d but expected %d." ),
|
|
||||||
aNode->GetName(), retVal.size(), aExpectedNumPoints ) );
|
|
||||||
|
|
||||||
return retVal;
|
|
||||||
}
|
|
|
@ -1,164 +0,0 @@
|
||||||
/*
|
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2020 Roberto Fernandez Bautista <@Qbort>
|
|
||||||
* Copyright (C) 2020 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 as published by the
|
|
||||||
* Free Software Foundation, either version 3 of the License, or (at your
|
|
||||||
* option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file cadstar_common.h
|
|
||||||
* @brief Helper functions and common defines
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef CADSTAR_COMMON_H_
|
|
||||||
#define CADSTAR_COMMON_H_
|
|
||||||
|
|
||||||
#include <class_board.h>
|
|
||||||
#include <dsnlexer.h>
|
|
||||||
#include <macros.h>
|
|
||||||
#include <vector>
|
|
||||||
#include <wx/wx.h>
|
|
||||||
#include <wx/xml/xml.h>
|
|
||||||
#include <xnode.h>
|
|
||||||
|
|
||||||
#define THROW_MISSING_NODE_IO_ERROR( nodename, location ) \
|
|
||||||
THROW_IO_ERROR( wxString::Format( _( "Missing node '%s' in '%s'" ), nodename, location ) )
|
|
||||||
|
|
||||||
#define THROW_UNKNOWN_NODE_IO_ERROR( nodename, location ) \
|
|
||||||
THROW_IO_ERROR( wxString::Format( _( "Unknown node '%s' in '%s'" ), nodename, location ) )
|
|
||||||
|
|
||||||
#define THROW_MISSING_PARAMETER_IO_ERROR( param, location ) \
|
|
||||||
THROW_IO_ERROR( wxString::Format( _( "Missing Parameter '%s' in '%s'" ), param, location ) )
|
|
||||||
|
|
||||||
#define THROW_UNKNOWN_PARAMETER_IO_ERROR( param, location ) \
|
|
||||||
THROW_IO_ERROR( wxString::Format( _( "Unknown Parameter '%s' in '%s'" ), param, location ) )
|
|
||||||
|
|
||||||
#define THROW_PARSING_IO_ERROR( param, location ) \
|
|
||||||
THROW_IO_ERROR( wxString::Format( _( "Unable to parse '%s' in '%s'" ), param, location ) )
|
|
||||||
|
|
||||||
|
|
||||||
namespace CADSTAR_COMMON
|
|
||||||
{
|
|
||||||
enum class FILE_TYPE
|
|
||||||
{
|
|
||||||
PCB_ARCHIVE,
|
|
||||||
SCHEMATIC_ARCHIVE //for future schematic importer
|
|
||||||
//cadstar libraries?
|
|
||||||
//etc.
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Represents a floating value in E notation
|
|
||||||
*/
|
|
||||||
struct EVALUE
|
|
||||||
{
|
|
||||||
long Base = 0;
|
|
||||||
long Exponent = 0;
|
|
||||||
|
|
||||||
void Parse( XNODE* aNode );
|
|
||||||
double GetDouble();
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Represents a point in x,y coordinates
|
|
||||||
*/
|
|
||||||
struct POINT
|
|
||||||
{
|
|
||||||
long X;
|
|
||||||
long Y;
|
|
||||||
|
|
||||||
void Parse( XNODE* aNode );
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
extern void InsertAttributeAtEnd( XNODE* aNode, wxString aValue );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Reads a CADSTAR Archive file (S-parameter format)
|
|
||||||
* @param aFileName
|
|
||||||
* @param aType
|
|
||||||
* @return XNODE pointing to the top of the tree for further parsing. Each node has the first
|
|
||||||
* element as the node's name and subsequent elements as node attributes ("attr0",
|
|
||||||
* "attr1", "attr2", etc.). Caller is responsible for deleting to avoid memory leaks.
|
|
||||||
* @throws IO_ERROR
|
|
||||||
*/
|
|
||||||
extern XNODE* LoadArchiveFile(
|
|
||||||
const wxString& aFileName, FILE_TYPE aType = FILE_TYPE::PCB_ARCHIVE );
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief
|
|
||||||
* @param aNode
|
|
||||||
* @param aID
|
|
||||||
* @return returns the value of attribute "attrX" in aNode where 'X' is aID
|
|
||||||
* @throws IO_ERROR if attribute does not exist
|
|
||||||
*/
|
|
||||||
extern wxString GetAttributeID( XNODE* aNode, unsigned int aID );
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief
|
|
||||||
* @param aNode
|
|
||||||
* @param aID
|
|
||||||
* @return returns the value of attribute "attrX" in aNode where 'X' is aID
|
|
||||||
* @throws IO_ERROR if attribute does not exist
|
|
||||||
*/
|
|
||||||
extern long GetAttributeIDLong( XNODE* aNode, unsigned int aID );
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief
|
|
||||||
* @param aNode
|
|
||||||
* @throw IO_ERROR if a child node was found
|
|
||||||
*/
|
|
||||||
extern void CheckNoChildNodes( XNODE* aNode );
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief
|
|
||||||
* @param aNode
|
|
||||||
* @throw IO_ERROR if a node adjacent to aNode was found
|
|
||||||
*/
|
|
||||||
extern void CheckNoNextNodes( XNODE* aNode );
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief
|
|
||||||
* @param aNode with a child node containing an EVALUE
|
|
||||||
* @param aValueToParse
|
|
||||||
* @throw IO_ERROR if unable to parse or node is not an EVALUE
|
|
||||||
*/
|
|
||||||
extern void ParseChildEValue( XNODE* aNode, EVALUE& aValueToParse );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief if no childs are present, it just returns an empty
|
|
||||||
* vector (without throwing an exception)
|
|
||||||
* @param aNode containing a series of POINT objects
|
|
||||||
* @param aTestAllChildNodes
|
|
||||||
* @param aExpectedNumPoints if -1, this is check is disabled
|
|
||||||
* @return std::vector containing all POINT objects
|
|
||||||
* @throw IO_ERROR if one of the following:
|
|
||||||
* - Unable to parse a POINT object
|
|
||||||
* - aTestAllChildNodes is true and one of the child nodes is not a valid POINT object
|
|
||||||
* - aExpectedNumPoints is non-negative and the number of POINT objects found is different
|
|
||||||
*/
|
|
||||||
extern std::vector<POINT> ParseAllChildPoints(
|
|
||||||
XNODE* aNode, bool aTestAllChildNodes = true, int aExpectedNumPoints = -1 );
|
|
||||||
|
|
||||||
} // namespace CADSTAR_COMMON
|
|
||||||
|
|
||||||
#endif // CADSTAR_COMMON_H_
|
|
|
@ -20,36 +20,38 @@
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file cadstar_pcb.cpp
|
* @file cadstar_pcb.cpp
|
||||||
* @brief Converts a CPA_FILE object into a KiCad BOARD object
|
* @brief Converts a CADSTAR_PCB_ARCHIVE_PARSER object into a KiCad BOARD object
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <board_stackup_manager/stackup_predefined_prms.h> //KEY_COPPER, KEY_CORE, KEY_PREPREG
|
#include <board_stackup_manager/stackup_predefined_prms.h> //KEY_COPPER, KEY_CORE, KEY_PREPREG
|
||||||
#include <cadstar_pcb.h>
|
#include <cadstar_pcb.h>
|
||||||
|
|
||||||
|
|
||||||
void CADSTAR_PCB::Load( CPA_FILE* aCPAfile )
|
void CADSTAR_PCB::Load( BOARD* aBoard )
|
||||||
{
|
{
|
||||||
loadBoardStackup( aCPAfile );
|
mBoard = aBoard;
|
||||||
|
Parse();
|
||||||
|
loadBoardStackup();
|
||||||
|
|
||||||
//TODO: process all other items
|
//TODO: process all other items
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CADSTAR_PCB::loadBoardStackup( CPA_FILE* aCPAfile )
|
void CADSTAR_PCB::loadBoardStackup()
|
||||||
{
|
{
|
||||||
std::map<CPA_ID, CPA_LAYER>& cpaLayers = aCPAfile->Assignments.Layerdefs.Layers;
|
std::map<LAYER_ID, LAYER>& cpaLayers = Assignments.Layerdefs.Layers;
|
||||||
std::map<CPA_ID, CPA_MATERIAL>& cpaMaterials = aCPAfile->Assignments.Layerdefs.Materials;
|
std::map<MATERIAL_ID, MATERIAL>& cpaMaterials = Assignments.Layerdefs.Materials;
|
||||||
std::vector<CPA_ID>& cpaLayerStack = aCPAfile->Assignments.Layerdefs.LayerStack;
|
std::vector<LAYER_ID>& cpaLayerStack = Assignments.Layerdefs.LayerStack;
|
||||||
unsigned numElectricalAndPowerLayers = 0;
|
unsigned numElecAndPowerLayers = 0;
|
||||||
BOARD_DESIGN_SETTINGS& designSettings = mBoard->GetDesignSettings();
|
BOARD_DESIGN_SETTINGS& designSettings = mBoard->GetDesignSettings();
|
||||||
BOARD_STACKUP& stackup = designSettings.GetStackupDescriptor();
|
BOARD_STACKUP& stackup = designSettings.GetStackupDescriptor();
|
||||||
int noOfKiCadStackupLayers = 0;
|
int noOfKiCadStackupLayers = 0;
|
||||||
int lastElectricalLayerIndex = 0;
|
int lastElectricalLayerIndex = 0;
|
||||||
int dielectricSublayer = 0;
|
int dielectricSublayer = 0;
|
||||||
int numDielectricLayers = 0;
|
int numDielectricLayers = 0;
|
||||||
bool prevWasDielectric = false;
|
bool prevWasDielectric = false;
|
||||||
BOARD_STACKUP_ITEM* tempKiCadLayer;
|
BOARD_STACKUP_ITEM* tempKiCadLayer;
|
||||||
std::vector<PCB_LAYER_ID> layerIDs;
|
std::vector<PCB_LAYER_ID> layerIDs;
|
||||||
|
|
||||||
//Remove all layers except required ones
|
//Remove all layers except required ones
|
||||||
stackup.RemoveAll();
|
stackup.RemoveAll();
|
||||||
|
@ -61,7 +63,7 @@ void CADSTAR_PCB::loadBoardStackup( CPA_FILE* aCPAfile )
|
||||||
|
|
||||||
for( auto it = cpaLayerStack.begin(); it != cpaLayerStack.end(); ++it )
|
for( auto it = cpaLayerStack.begin(); it != cpaLayerStack.end(); ++it )
|
||||||
{
|
{
|
||||||
CPA_LAYER curLayer = cpaLayers[*it];
|
LAYER curLayer = cpaLayers[*it];
|
||||||
BOARD_STACKUP_ITEM_TYPE kicadLayerType = BOARD_STACKUP_ITEM_TYPE::BS_ITEM_TYPE_UNDEFINED;
|
BOARD_STACKUP_ITEM_TYPE kicadLayerType = BOARD_STACKUP_ITEM_TYPE::BS_ITEM_TYPE_UNDEFINED;
|
||||||
LAYER_T copperType = LAYER_T::LT_UNDEFINED;
|
LAYER_T copperType = LAYER_T::LT_UNDEFINED;
|
||||||
PCB_LAYER_ID kicadLayerID = PCB_LAYER_ID::UNDEFINED_LAYER;
|
PCB_LAYER_ID kicadLayerID = PCB_LAYER_ID::UNDEFINED_LAYER;
|
||||||
|
@ -70,7 +72,7 @@ void CADSTAR_PCB::loadBoardStackup( CPA_FILE* aCPAfile )
|
||||||
if( cpaLayers.count( *it ) == 0 )
|
if( cpaLayers.count( *it ) == 0 )
|
||||||
wxASSERT_MSG( true, wxT( "Unable to find layer index" ) );
|
wxASSERT_MSG( true, wxT( "Unable to find layer index" ) );
|
||||||
|
|
||||||
if( prevWasDielectric && ( curLayer.Type != CPA_LAYER_TYPE::CONSTRUCTION ) )
|
if( prevWasDielectric && ( curLayer.Type != LAYER_TYPE::CONSTRUCTION ) )
|
||||||
{
|
{
|
||||||
stackup.Add( tempKiCadLayer ); //only add dielectric layers here after all are done
|
stackup.Add( tempKiCadLayer ); //only add dielectric layers here after all are done
|
||||||
dielectricSublayer = 0;
|
dielectricSublayer = 0;
|
||||||
|
@ -80,34 +82,34 @@ void CADSTAR_PCB::loadBoardStackup( CPA_FILE* aCPAfile )
|
||||||
|
|
||||||
switch( curLayer.Type )
|
switch( curLayer.Type )
|
||||||
{
|
{
|
||||||
case CPA_LAYER_TYPE::ALLDOC:
|
case LAYER_TYPE::ALLDOC:
|
||||||
case CPA_LAYER_TYPE::ALLELEC:
|
case LAYER_TYPE::ALLELEC:
|
||||||
case CPA_LAYER_TYPE::ALLLAYER:
|
case LAYER_TYPE::ALLLAYER:
|
||||||
case CPA_LAYER_TYPE::ASSCOMPCOPP:
|
case LAYER_TYPE::ASSCOMPCOPP:
|
||||||
case CPA_LAYER_TYPE::NOLAYER:
|
case LAYER_TYPE::NOLAYER:
|
||||||
//Shouldn't be here if CPA file is correctly parsed and not corrupt
|
//Shouldn't be here if CPA file is correctly parsed and not corrupt
|
||||||
THROW_IO_ERROR( wxString::Format(
|
THROW_IO_ERROR( wxString::Format(
|
||||||
_( "Unexpected layer '%s' in layer stack." ), curLayer.Name ) );
|
_( "Unexpected layer '%s' in layer stack." ), curLayer.Name ) );
|
||||||
continue;
|
continue;
|
||||||
case CPA_LAYER_TYPE::JUMPERLAYER:
|
case LAYER_TYPE::JUMPERLAYER:
|
||||||
copperType = LAYER_T::LT_JUMPER;
|
copperType = LAYER_T::LT_JUMPER;
|
||||||
kicadLayerID = getKiCadCopperLayerID( numElectricalAndPowerLayers++ );
|
kicadLayerID = getKiCadCopperLayerID( numElecAndPowerLayers++ );
|
||||||
kicadLayerType = BOARD_STACKUP_ITEM_TYPE::BS_ITEM_TYPE_COPPER;
|
kicadLayerType = BOARD_STACKUP_ITEM_TYPE::BS_ITEM_TYPE_COPPER;
|
||||||
layerTypeName = KEY_COPPER;
|
layerTypeName = KEY_COPPER;
|
||||||
break;
|
break;
|
||||||
case CPA_LAYER_TYPE::ELEC:
|
case LAYER_TYPE::ELEC:
|
||||||
copperType = LAYER_T::LT_SIGNAL;
|
copperType = LAYER_T::LT_SIGNAL;
|
||||||
kicadLayerID = getKiCadCopperLayerID( numElectricalAndPowerLayers++ );
|
kicadLayerID = getKiCadCopperLayerID( numElecAndPowerLayers++ );
|
||||||
kicadLayerType = BOARD_STACKUP_ITEM_TYPE::BS_ITEM_TYPE_COPPER;
|
kicadLayerType = BOARD_STACKUP_ITEM_TYPE::BS_ITEM_TYPE_COPPER;
|
||||||
layerTypeName = KEY_COPPER;
|
layerTypeName = KEY_COPPER;
|
||||||
break;
|
break;
|
||||||
case CPA_LAYER_TYPE::POWER:
|
case LAYER_TYPE::POWER:
|
||||||
copperType = LAYER_T::LT_POWER;
|
copperType = LAYER_T::LT_POWER;
|
||||||
kicadLayerID = getKiCadCopperLayerID( numElectricalAndPowerLayers++ );
|
kicadLayerID = getKiCadCopperLayerID( numElecAndPowerLayers++ );
|
||||||
kicadLayerType = BOARD_STACKUP_ITEM_TYPE::BS_ITEM_TYPE_COPPER;
|
kicadLayerType = BOARD_STACKUP_ITEM_TYPE::BS_ITEM_TYPE_COPPER;
|
||||||
layerTypeName = KEY_COPPER;
|
layerTypeName = KEY_COPPER;
|
||||||
break;
|
break;
|
||||||
case CPA_LAYER_TYPE::CONSTRUCTION:
|
case LAYER_TYPE::CONSTRUCTION:
|
||||||
kicadLayerID = PCB_LAYER_ID::UNDEFINED_LAYER;
|
kicadLayerID = PCB_LAYER_ID::UNDEFINED_LAYER;
|
||||||
kicadLayerType = BOARD_STACKUP_ITEM_TYPE::BS_ITEM_TYPE_DIELECTRIC;
|
kicadLayerType = BOARD_STACKUP_ITEM_TYPE::BS_ITEM_TYPE_DIELECTRIC;
|
||||||
prevWasDielectric = true;
|
prevWasDielectric = true;
|
||||||
|
@ -117,20 +119,20 @@ void CADSTAR_PCB::loadBoardStackup( CPA_FILE* aCPAfile )
|
||||||
//check electrical layers above and below to decide if current layer is prepreg
|
//check electrical layers above and below to decide if current layer is prepreg
|
||||||
// or core
|
// or core
|
||||||
break;
|
break;
|
||||||
case CPA_LAYER_TYPE::DOC:
|
case LAYER_TYPE::DOC:
|
||||||
//TODO find out a suitable KiCad Layer alternative for this CADSTAR type
|
//TODO find out a suitable KiCad Layer alternative for this CADSTAR type
|
||||||
continue; //ignore
|
continue; //ignore
|
||||||
case CPA_LAYER_TYPE::NONELEC:
|
case LAYER_TYPE::NONELEC:
|
||||||
switch( curLayer.SubType )
|
switch( curLayer.SubType )
|
||||||
{
|
{
|
||||||
case CPA_LAYER_SUBTYPE::LAYERSUBTYPE_ASSEMBLY:
|
case LAYER_SUBTYPE::LAYERSUBTYPE_ASSEMBLY:
|
||||||
case CPA_LAYER_SUBTYPE::LAYERSUBTYPE_NONE:
|
case LAYER_SUBTYPE::LAYERSUBTYPE_NONE:
|
||||||
case CPA_LAYER_SUBTYPE::LAYERSUBTYPE_PLACEMENT:
|
case LAYER_SUBTYPE::LAYERSUBTYPE_PLACEMENT:
|
||||||
//TODO find out a suitable KiCad Layer alternative for these CADSTAR types
|
//TODO find out a suitable KiCad Layer alternative for these CADSTAR types
|
||||||
continue; //ignore these layer types for now
|
continue; //ignore these layer types for now
|
||||||
case CPA_LAYER_SUBTYPE::LAYERSUBTYPE_PASTE:
|
case LAYER_SUBTYPE::LAYERSUBTYPE_PASTE:
|
||||||
kicadLayerType = BOARD_STACKUP_ITEM_TYPE::BS_ITEM_TYPE_SOLDERPASTE;
|
kicadLayerType = BOARD_STACKUP_ITEM_TYPE::BS_ITEM_TYPE_SOLDERPASTE;
|
||||||
if( numElectricalAndPowerLayers > 0 )
|
if( numElecAndPowerLayers > 0 )
|
||||||
{
|
{
|
||||||
kicadLayerID = PCB_LAYER_ID::F_Paste;
|
kicadLayerID = PCB_LAYER_ID::F_Paste;
|
||||||
layerTypeName = _HKI( "Top Solder Paste" );
|
layerTypeName = _HKI( "Top Solder Paste" );
|
||||||
|
@ -141,9 +143,9 @@ void CADSTAR_PCB::loadBoardStackup( CPA_FILE* aCPAfile )
|
||||||
layerTypeName = _HKI( "Bottom Solder Paste" );
|
layerTypeName = _HKI( "Bottom Solder Paste" );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CPA_LAYER_SUBTYPE::LAYERSUBTYPE_SILKSCREEN:
|
case LAYER_SUBTYPE::LAYERSUBTYPE_SILKSCREEN:
|
||||||
kicadLayerType = BOARD_STACKUP_ITEM_TYPE::BS_ITEM_TYPE_SILKSCREEN;
|
kicadLayerType = BOARD_STACKUP_ITEM_TYPE::BS_ITEM_TYPE_SILKSCREEN;
|
||||||
if( numElectricalAndPowerLayers > 0 )
|
if( numElecAndPowerLayers > 0 )
|
||||||
{
|
{
|
||||||
kicadLayerID = PCB_LAYER_ID::F_SilkS;
|
kicadLayerID = PCB_LAYER_ID::F_SilkS;
|
||||||
layerTypeName = _HKI( "Top Silk Screen" );
|
layerTypeName = _HKI( "Top Silk Screen" );
|
||||||
|
@ -154,9 +156,9 @@ void CADSTAR_PCB::loadBoardStackup( CPA_FILE* aCPAfile )
|
||||||
layerTypeName = _HKI( "Bottom Silk Screen" );
|
layerTypeName = _HKI( "Bottom Silk Screen" );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CPA_LAYER_SUBTYPE::LAYERSUBTYPE_SOLDERRESIST:
|
case LAYER_SUBTYPE::LAYERSUBTYPE_SOLDERRESIST:
|
||||||
kicadLayerType = BOARD_STACKUP_ITEM_TYPE::BS_ITEM_TYPE_SOLDERMASK;
|
kicadLayerType = BOARD_STACKUP_ITEM_TYPE::BS_ITEM_TYPE_SOLDERMASK;
|
||||||
if( numElectricalAndPowerLayers > 0 )
|
if( numElecAndPowerLayers > 0 )
|
||||||
{
|
{
|
||||||
kicadLayerID = PCB_LAYER_ID::F_Mask;
|
kicadLayerID = PCB_LAYER_ID::F_Mask;
|
||||||
layerTypeName = _HKI( "Top Solder Mask" );
|
layerTypeName = _HKI( "Top Solder Mask" );
|
||||||
|
@ -195,7 +197,7 @@ void CADSTAR_PCB::loadBoardStackup( CPA_FILE* aCPAfile )
|
||||||
tempKiCadLayer->AddDielectricPrms( dielectricSublayer );
|
tempKiCadLayer->AddDielectricPrms( dielectricSublayer );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !curLayer.MaterialId.IsEmpty() )
|
if( curLayer.MaterialId != UNDEFINED_MATERIAL_ID )
|
||||||
{
|
{
|
||||||
tempKiCadLayer->SetMaterial(
|
tempKiCadLayer->SetMaterial(
|
||||||
cpaMaterials[curLayer.MaterialId].Name, dielectricSublayer );
|
cpaMaterials[curLayer.MaterialId].Name, dielectricSublayer );
|
||||||
|
@ -206,8 +208,8 @@ void CADSTAR_PCB::loadBoardStackup( CPA_FILE* aCPAfile )
|
||||||
//TODO add Resistivity when KiCad supports it
|
//TODO add Resistivity when KiCad supports it
|
||||||
}
|
}
|
||||||
|
|
||||||
int unitMultiplier = aCPAfile->KiCadUnitMultiplier;
|
tempKiCadLayer->SetThickness(
|
||||||
tempKiCadLayer->SetThickness( curLayer.Thickness * unitMultiplier, dielectricSublayer );
|
curLayer.Thickness * KiCadUnitMultiplier, dielectricSublayer );
|
||||||
|
|
||||||
wxASSERT( layerTypeName != wxEmptyString );
|
wxASSERT( layerTypeName != wxEmptyString );
|
||||||
tempKiCadLayer->SetTypeName( layerTypeName );
|
tempKiCadLayer->SetTypeName( layerTypeName );
|
||||||
|
@ -250,7 +252,7 @@ void CADSTAR_PCB::loadBoardStackup( CPA_FILE* aCPAfile )
|
||||||
mBoard->SetEnabledLayers( LSET( &layerIDs[0], layerIDs.size() ) );
|
mBoard->SetEnabledLayers( LSET( &layerIDs[0], layerIDs.size() ) );
|
||||||
mBoard->SetVisibleLayers( LSET( &layerIDs[0], layerIDs.size() ) );
|
mBoard->SetVisibleLayers( LSET( &layerIDs[0], layerIDs.size() ) );
|
||||||
|
|
||||||
mBoard->SetCopperLayerCount( numElectricalAndPowerLayers );
|
mBoard->SetCopperLayerCount( numElecAndPowerLayers );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file cadstar_pcb.h
|
* @file cadstar_pcb.h
|
||||||
* @brief Converts a CPA_FILE object into a KiCad BOARD object
|
* @brief Converts a CADSTAR_PCB_ARCHIVE_PARSER object into a KiCad BOARD object
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef CADSTAR_PCB_H_
|
#ifndef CADSTAR_PCB_H_
|
||||||
|
@ -30,25 +30,25 @@
|
||||||
|
|
||||||
class BOARD;
|
class BOARD;
|
||||||
|
|
||||||
class CADSTAR_PCB
|
class CADSTAR_PCB : public CADSTAR_PCB_ARCHIVE_PARSER
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit CADSTAR_PCB( BOARD* aBoard ) : mBoard( aBoard )
|
explicit CADSTAR_PCB( wxString aFilename ) : CADSTAR_PCB_ARCHIVE_PARSER( aFilename )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Loads a CADSTAR PCB Archive into the KiCad BOARD
|
* @brief Loads a CADSTAR PCB Archive file into the KiCad BOARD object given
|
||||||
* @param aCPAfile
|
* @param aBoard
|
||||||
*/
|
*/
|
||||||
void Load( CPA_FILE* aCPAfile );
|
void Load( BOARD* aBoard );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BOARD* mBoard;
|
BOARD* mBoard;
|
||||||
std::map<CPA_ID, PCB_LAYER_ID> mLayermap; //<Map between Cadstar and KiCad Layers
|
std::map<LAYER_ID, PCB_LAYER_ID> mLayermap; //<Map between Cadstar and KiCad Layers
|
||||||
std::map<CPA_PHYSICAL_LAYER, CPA_ID> mCopperLayers;
|
std::map<PHYSICAL_LAYER, LAYER_ID> mCopperLayers;
|
||||||
void loadBoardStackup( CPA_FILE* aCPAfile );
|
void loadBoardStackup();
|
||||||
PCB_LAYER_ID getKiCadCopperLayerID( unsigned int aLayerNum );
|
PCB_LAYER_ID getKiCadCopperLayerID( unsigned int aLayerNum );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -24,9 +24,7 @@
|
||||||
* based on S-expressions.
|
* based on S-expressions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <cadstar_common.h>
|
|
||||||
#include <cadstar_pcb.h>
|
#include <cadstar_pcb.h>
|
||||||
#include <cadstar_pcb_archive_parser.h>
|
|
||||||
#include <cadstar_pcb_archive_plugin.h>
|
#include <cadstar_pcb_archive_plugin.h>
|
||||||
#include <class_board.h>
|
#include <class_board.h>
|
||||||
|
|
||||||
|
@ -61,10 +59,8 @@ BOARD* CADSTAR_PCB_ARCHIVE_PLUGIN::Load(
|
||||||
m_props = aProperties;
|
m_props = aProperties;
|
||||||
m_board = aAppendToMe ? aAppendToMe : new BOARD();
|
m_board = aAppendToMe ? aAppendToMe : new BOARD();
|
||||||
|
|
||||||
CADSTAR_PCB tempPCB( m_board );
|
CADSTAR_PCB tempPCB( aFileName );
|
||||||
CPA_FILE theFile( aFileName );
|
tempPCB.Load( m_board );
|
||||||
theFile.Parse();
|
|
||||||
tempPCB.Load( &theFile );
|
|
||||||
|
|
||||||
return m_board;
|
return m_board;
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,6 +103,7 @@ target_link_libraries( drc_proto
|
||||||
pcbcommon
|
pcbcommon
|
||||||
bitmaps
|
bitmaps
|
||||||
gal
|
gal
|
||||||
|
cadstar2kicadpcb
|
||||||
common
|
common
|
||||||
pcbcommon
|
pcbcommon
|
||||||
${PCBNEW_IO_LIBRARIES}
|
${PCBNEW_IO_LIBRARIES}
|
||||||
|
|
Loading…
Reference in New Issue