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:
Roberto Fernandez Bautista 2020-07-30 23:42:56 +01:00 committed by Seth Hillbrand
parent 0ce95f2803
commit 4c2f38f1ad
11 changed files with 3041 additions and 1391 deletions

View File

@ -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
) )

View File

@ -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" ) );
}

View File

@ -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_

View File

@ -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;
}

View File

@ -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_

View File

@ -20,27 +20,29 @@
/** /**
* @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;
@ -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 );
} }

View File

@ -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,24 +30,24 @@
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

View File

@ -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;
} }

View File

@ -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}