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
|
||||
cadstar_pcb_archive_plugin.cpp
|
||||
cadstar_pcb_archive_parser.cpp
|
||||
cadstar_common.cpp
|
||||
cadstar_archive_common.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,27 +20,29 @@
|
|||
|
||||
/**
|
||||
* @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 <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
|
||||
}
|
||||
|
||||
|
||||
void CADSTAR_PCB::loadBoardStackup( CPA_FILE* aCPAfile )
|
||||
void CADSTAR_PCB::loadBoardStackup()
|
||||
{
|
||||
std::map<CPA_ID, CPA_LAYER>& cpaLayers = aCPAfile->Assignments.Layerdefs.Layers;
|
||||
std::map<CPA_ID, CPA_MATERIAL>& cpaMaterials = aCPAfile->Assignments.Layerdefs.Materials;
|
||||
std::vector<CPA_ID>& cpaLayerStack = aCPAfile->Assignments.Layerdefs.LayerStack;
|
||||
unsigned numElectricalAndPowerLayers = 0;
|
||||
std::map<LAYER_ID, LAYER>& cpaLayers = Assignments.Layerdefs.Layers;
|
||||
std::map<MATERIAL_ID, MATERIAL>& cpaMaterials = Assignments.Layerdefs.Materials;
|
||||
std::vector<LAYER_ID>& cpaLayerStack = Assignments.Layerdefs.LayerStack;
|
||||
unsigned numElecAndPowerLayers = 0;
|
||||
BOARD_DESIGN_SETTINGS& designSettings = mBoard->GetDesignSettings();
|
||||
BOARD_STACKUP& stackup = designSettings.GetStackupDescriptor();
|
||||
int noOfKiCadStackupLayers = 0;
|
||||
|
@ -61,7 +63,7 @@ void CADSTAR_PCB::loadBoardStackup( CPA_FILE* aCPAfile )
|
|||
|
||||
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;
|
||||
LAYER_T copperType = LAYER_T::LT_UNDEFINED;
|
||||
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 )
|
||||
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
|
||||
dielectricSublayer = 0;
|
||||
|
@ -80,34 +82,34 @@ void CADSTAR_PCB::loadBoardStackup( CPA_FILE* aCPAfile )
|
|||
|
||||
switch( curLayer.Type )
|
||||
{
|
||||
case CPA_LAYER_TYPE::ALLDOC:
|
||||
case CPA_LAYER_TYPE::ALLELEC:
|
||||
case CPA_LAYER_TYPE::ALLLAYER:
|
||||
case CPA_LAYER_TYPE::ASSCOMPCOPP:
|
||||
case CPA_LAYER_TYPE::NOLAYER:
|
||||
case LAYER_TYPE::ALLDOC:
|
||||
case LAYER_TYPE::ALLELEC:
|
||||
case LAYER_TYPE::ALLLAYER:
|
||||
case LAYER_TYPE::ASSCOMPCOPP:
|
||||
case LAYER_TYPE::NOLAYER:
|
||||
//Shouldn't be here if CPA file is correctly parsed and not corrupt
|
||||
THROW_IO_ERROR( wxString::Format(
|
||||
_( "Unexpected layer '%s' in layer stack." ), curLayer.Name ) );
|
||||
continue;
|
||||
case CPA_LAYER_TYPE::JUMPERLAYER:
|
||||
case LAYER_TYPE::JUMPERLAYER:
|
||||
copperType = LAYER_T::LT_JUMPER;
|
||||
kicadLayerID = getKiCadCopperLayerID( numElectricalAndPowerLayers++ );
|
||||
kicadLayerID = getKiCadCopperLayerID( numElecAndPowerLayers++ );
|
||||
kicadLayerType = BOARD_STACKUP_ITEM_TYPE::BS_ITEM_TYPE_COPPER;
|
||||
layerTypeName = KEY_COPPER;
|
||||
break;
|
||||
case CPA_LAYER_TYPE::ELEC:
|
||||
case LAYER_TYPE::ELEC:
|
||||
copperType = LAYER_T::LT_SIGNAL;
|
||||
kicadLayerID = getKiCadCopperLayerID( numElectricalAndPowerLayers++ );
|
||||
kicadLayerID = getKiCadCopperLayerID( numElecAndPowerLayers++ );
|
||||
kicadLayerType = BOARD_STACKUP_ITEM_TYPE::BS_ITEM_TYPE_COPPER;
|
||||
layerTypeName = KEY_COPPER;
|
||||
break;
|
||||
case CPA_LAYER_TYPE::POWER:
|
||||
case LAYER_TYPE::POWER:
|
||||
copperType = LAYER_T::LT_POWER;
|
||||
kicadLayerID = getKiCadCopperLayerID( numElectricalAndPowerLayers++ );
|
||||
kicadLayerID = getKiCadCopperLayerID( numElecAndPowerLayers++ );
|
||||
kicadLayerType = BOARD_STACKUP_ITEM_TYPE::BS_ITEM_TYPE_COPPER;
|
||||
layerTypeName = KEY_COPPER;
|
||||
break;
|
||||
case CPA_LAYER_TYPE::CONSTRUCTION:
|
||||
case LAYER_TYPE::CONSTRUCTION:
|
||||
kicadLayerID = PCB_LAYER_ID::UNDEFINED_LAYER;
|
||||
kicadLayerType = BOARD_STACKUP_ITEM_TYPE::BS_ITEM_TYPE_DIELECTRIC;
|
||||
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
|
||||
// or core
|
||||
break;
|
||||
case CPA_LAYER_TYPE::DOC:
|
||||
case LAYER_TYPE::DOC:
|
||||
//TODO find out a suitable KiCad Layer alternative for this CADSTAR type
|
||||
continue; //ignore
|
||||
case CPA_LAYER_TYPE::NONELEC:
|
||||
case LAYER_TYPE::NONELEC:
|
||||
switch( curLayer.SubType )
|
||||
{
|
||||
case CPA_LAYER_SUBTYPE::LAYERSUBTYPE_ASSEMBLY:
|
||||
case CPA_LAYER_SUBTYPE::LAYERSUBTYPE_NONE:
|
||||
case CPA_LAYER_SUBTYPE::LAYERSUBTYPE_PLACEMENT:
|
||||
case LAYER_SUBTYPE::LAYERSUBTYPE_ASSEMBLY:
|
||||
case LAYER_SUBTYPE::LAYERSUBTYPE_NONE:
|
||||
case LAYER_SUBTYPE::LAYERSUBTYPE_PLACEMENT:
|
||||
//TODO find out a suitable KiCad Layer alternative for these CADSTAR types
|
||||
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;
|
||||
if( numElectricalAndPowerLayers > 0 )
|
||||
if( numElecAndPowerLayers > 0 )
|
||||
{
|
||||
kicadLayerID = PCB_LAYER_ID::F_Paste;
|
||||
layerTypeName = _HKI( "Top Solder Paste" );
|
||||
|
@ -141,9 +143,9 @@ void CADSTAR_PCB::loadBoardStackup( CPA_FILE* aCPAfile )
|
|||
layerTypeName = _HKI( "Bottom Solder Paste" );
|
||||
}
|
||||
break;
|
||||
case CPA_LAYER_SUBTYPE::LAYERSUBTYPE_SILKSCREEN:
|
||||
case LAYER_SUBTYPE::LAYERSUBTYPE_SILKSCREEN:
|
||||
kicadLayerType = BOARD_STACKUP_ITEM_TYPE::BS_ITEM_TYPE_SILKSCREEN;
|
||||
if( numElectricalAndPowerLayers > 0 )
|
||||
if( numElecAndPowerLayers > 0 )
|
||||
{
|
||||
kicadLayerID = PCB_LAYER_ID::F_SilkS;
|
||||
layerTypeName = _HKI( "Top Silk Screen" );
|
||||
|
@ -154,9 +156,9 @@ void CADSTAR_PCB::loadBoardStackup( CPA_FILE* aCPAfile )
|
|||
layerTypeName = _HKI( "Bottom Silk Screen" );
|
||||
}
|
||||
break;
|
||||
case CPA_LAYER_SUBTYPE::LAYERSUBTYPE_SOLDERRESIST:
|
||||
case LAYER_SUBTYPE::LAYERSUBTYPE_SOLDERRESIST:
|
||||
kicadLayerType = BOARD_STACKUP_ITEM_TYPE::BS_ITEM_TYPE_SOLDERMASK;
|
||||
if( numElectricalAndPowerLayers > 0 )
|
||||
if( numElecAndPowerLayers > 0 )
|
||||
{
|
||||
kicadLayerID = PCB_LAYER_ID::F_Mask;
|
||||
layerTypeName = _HKI( "Top Solder Mask" );
|
||||
|
@ -195,7 +197,7 @@ void CADSTAR_PCB::loadBoardStackup( CPA_FILE* aCPAfile )
|
|||
tempKiCadLayer->AddDielectricPrms( dielectricSublayer );
|
||||
}
|
||||
|
||||
if( !curLayer.MaterialId.IsEmpty() )
|
||||
if( curLayer.MaterialId != UNDEFINED_MATERIAL_ID )
|
||||
{
|
||||
tempKiCadLayer->SetMaterial(
|
||||
cpaMaterials[curLayer.MaterialId].Name, dielectricSublayer );
|
||||
|
@ -206,8 +208,8 @@ void CADSTAR_PCB::loadBoardStackup( CPA_FILE* aCPAfile )
|
|||
//TODO add Resistivity when KiCad supports it
|
||||
}
|
||||
|
||||
int unitMultiplier = aCPAfile->KiCadUnitMultiplier;
|
||||
tempKiCadLayer->SetThickness( curLayer.Thickness * unitMultiplier, dielectricSublayer );
|
||||
tempKiCadLayer->SetThickness(
|
||||
curLayer.Thickness * KiCadUnitMultiplier, dielectricSublayer );
|
||||
|
||||
wxASSERT( layerTypeName != wxEmptyString );
|
||||
tempKiCadLayer->SetTypeName( layerTypeName );
|
||||
|
@ -250,7 +252,7 @@ void CADSTAR_PCB::loadBoardStackup( CPA_FILE* aCPAfile )
|
|||
mBoard->SetEnabledLayers( 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
|
||||
* @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_
|
||||
|
@ -30,24 +30,24 @@
|
|||
|
||||
class BOARD;
|
||||
|
||||
class CADSTAR_PCB
|
||||
class CADSTAR_PCB : public CADSTAR_PCB_ARCHIVE_PARSER
|
||||
{
|
||||
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
|
||||
* @param aCPAfile
|
||||
* @brief Loads a CADSTAR PCB Archive file into the KiCad BOARD object given
|
||||
* @param aBoard
|
||||
*/
|
||||
void Load( CPA_FILE* aCPAfile );
|
||||
void Load( BOARD* aBoard );
|
||||
|
||||
private:
|
||||
BOARD* mBoard;
|
||||
std::map<CPA_ID, PCB_LAYER_ID> mLayermap; //<Map between Cadstar and KiCad Layers
|
||||
std::map<CPA_PHYSICAL_LAYER, CPA_ID> mCopperLayers;
|
||||
void loadBoardStackup( CPA_FILE* aCPAfile );
|
||||
std::map<LAYER_ID, PCB_LAYER_ID> mLayermap; //<Map between Cadstar and KiCad Layers
|
||||
std::map<PHYSICAL_LAYER, LAYER_ID> mCopperLayers;
|
||||
void loadBoardStackup();
|
||||
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.
|
||||
*/
|
||||
|
||||
#include <cadstar_common.h>
|
||||
#include <cadstar_pcb.h>
|
||||
#include <cadstar_pcb_archive_parser.h>
|
||||
#include <cadstar_pcb_archive_plugin.h>
|
||||
#include <class_board.h>
|
||||
|
||||
|
@ -61,10 +59,8 @@ BOARD* CADSTAR_PCB_ARCHIVE_PLUGIN::Load(
|
|||
m_props = aProperties;
|
||||
m_board = aAppendToMe ? aAppendToMe : new BOARD();
|
||||
|
||||
CADSTAR_PCB tempPCB( m_board );
|
||||
CPA_FILE theFile( aFileName );
|
||||
theFile.Parse();
|
||||
tempPCB.Load( &theFile );
|
||||
CADSTAR_PCB tempPCB( aFileName );
|
||||
tempPCB.Load( m_board );
|
||||
|
||||
return m_board;
|
||||
}
|
||||
|
|
|
@ -103,6 +103,7 @@ target_link_libraries( drc_proto
|
|||
pcbcommon
|
||||
bitmaps
|
||||
gal
|
||||
cadstar2kicadpcb
|
||||
common
|
||||
pcbcommon
|
||||
${PCBNEW_IO_LIBRARIES}
|
||||
|
|
Loading…
Reference in New Issue