CADSTAR PCB Archive Importer: Fix Parsing errors

Change error displayed when a Library .cpa file is opened (instead of a Layout file)
Add warning if variants exist in original design.
Parse LAYERHEIGHT in LAYER (same thing a MAKE but without the MATERIAL_ID)
Parse PADEXCEPTION in COMPONENT
Add DESIGN as one of the valid UNITS
This commit is contained in:
Roberto Fernandez Bautista 2020-09-08 14:01:32 +01:00 committed by Seth Hillbrand
parent 05e5740504
commit c1dec964be
3 changed files with 106 additions and 23 deletions

View File

@ -90,7 +90,10 @@ void CADSTAR_PCB_ARCHIVE_LOADER::Load( ::BOARD* aBoard )
loadCoppers();
loadNets();
//TODO: process all other items
if( Layout.VariantHierarchy.size() > 0 )
wxLogWarning(
_( "The CADSTAR design contains variants which has no KiCad equivalent. All "
"components have been loaded on top of each other. " ) );
wxLogMessage(
_( "The CADSTAR design has been imported successfully.\n"
@ -870,7 +873,9 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadComponents()
}
loadComponentAttributes( comp, m );
m->SetDescription( getPart( comp.PartID ).Definition.Name );
if( !comp.PartID.IsEmpty() && comp.PartID != wxT( "NO_PART" ) )
m->SetDescription( getPart( comp.PartID ).Definition.Name );
mComponentMap.insert( { comp.ID, m } );
}

View File

@ -455,10 +455,15 @@ void CADSTAR_PCB_ARCHIVE_PARSER::LAYER::Parse( XNODE* aNode )
{
wxString tempNodeName = tempNode->GetName();
if( tempNodeName == wxT( "MAKE" ) )
if( tempNodeName == wxT( "MAKE" ) || tempNodeName == wxT( "LAYERHEIGHT" ) )
{
MaterialId = GetXmlAttributeIDString( tempNode, 0 );
Thickness = GetXmlAttributeIDLong( tempNode, 1 );
if( tempNodeName == wxT( "LAYERHEIGHT" ) )
Thickness = GetXmlAttributeIDLong( tempNode, 0 );
else
{
MaterialId = GetXmlAttributeIDString( tempNode, 0 );
Thickness = GetXmlAttributeIDLong( tempNode, 1 );
}
XNODE* childOfTempNode = tempNode->GetChildren();
@ -671,7 +676,15 @@ void CADSTAR_PCB_ARCHIVE_PARSER::HEADER::Parse( XNODE* aNode )
Format.Parse( cNode );
if( Format.Type != wxT( "LAYOUT" ) )
THROW_IO_ERROR( "Not a CADSTAR PCB Layout file!" );
if( Format.Type == wxT( "LIBRARY" ) )
THROW_IO_ERROR(
"The selected file is a CADSTAR Library file (as opposed to a Layout "
"file). CADSTAR libraries cannot yet be imported into KiCad." );
else
THROW_IO_ERROR(
"The selected file is an unknown CADSTAR format so cannot be "
"imported into KiCad." );
}
else if( nodeName == wxT( "JOBFILE" ) )
JobFile = GetXmlAttributeIDString( cNode, 0 );
@ -1358,6 +1371,8 @@ CADSTAR_PCB_ARCHIVE_PARSER::UNITS CADSTAR_PCB_ARCHIVE_PARSER::ParseUnits( XNODE*
return UNITS::MM;
else if( unit == wxT( "THOU" ) )
return UNITS::THOU;
else if( unit == wxT( "DESIGN" ) )
return UNITS::DESIGN;
else
THROW_UNKNOWN_PARAMETER_IO_ERROR( unit, wxT( "UNITS" ) );
@ -1563,6 +1578,19 @@ CADSTAR_PCB_ARCHIVE_PARSER::SWAP_RULE CADSTAR_PCB_ARCHIVE_PARSER::ParseSwapRule(
return retval;
}
CADSTAR_PCB_ARCHIVE_PARSER::PAD_SIDE CADSTAR_PCB_ARCHIVE_PARSER::GetPadSide(
const wxString& aPadSideString )
{
if( aPadSideString == wxT( "THRU" ) )
return PAD_SIDE::THROUGH_HOLE;
else if( aPadSideString == wxT( "BOTTOM" ) )
return PAD_SIDE::MAXIMUM;
else if( aPadSideString == wxT( "TOP" ) )
return PAD_SIDE::MINIMUM;
else
return PAD_SIDE::THROUGH_HOLE; // Assume through hole as default
}
void CADSTAR_PCB_ARCHIVE_PARSER::COMPONENT_COPPER::Parse( XNODE* aNode )
{
@ -1712,15 +1740,7 @@ void CADSTAR_PCB_ARCHIVE_PARSER::PAD::Parse( XNODE* aNode )
ID = GetXmlAttributeIDLong( aNode, 0 );
PadCodeID = GetXmlAttributeIDString( aNode, 2 );
wxString padSideStr = GetXmlAttributeIDString( aNode, 3 );
if( padSideStr == wxT( "THRU" ) )
Side = PAD_SIDE::THROUGH_HOLE;
else if( padSideStr == wxT( "BOTTOM" ) )
Side = PAD_SIDE::MAXIMUM;
else if( padSideStr == wxT( "TOP" ) )
Side = PAD_SIDE::MINIMUM;
Side = GetPadSide( GetXmlAttributeIDString( aNode, 3 ) );
XNODE* cNode = aNode->GetChildren();
wxString location = wxString::Format( "PAD %d", ID );
@ -2740,6 +2760,40 @@ void CADSTAR_PCB_ARCHIVE_PARSER::PIN_ATTRIBUTE::Parse( XNODE* aNode )
}
void CADSTAR_PCB_ARCHIVE_PARSER::PADEXCEPTION::Parse( XNODE* aNode )
{
wxASSERT( aNode->GetName() == wxT( "PADEXCEPTION" ) );
ID = GetXmlAttributeIDLong( aNode, 0 );
XNODE* cNode = aNode->GetChildren();
for( ; cNode; cNode = cNode->GetNext() )
{
wxString cNodeName = cNode->GetName();
if( cNodeName == wxT( "PADCODEREF" ) )
{
PadCode = GetXmlAttributeIDString( cNode, 0 );
}
else if( cNodeName == wxT( "SIDE" ) )
{
OverrideSide = true;
Side = GetPadSide( GetXmlAttributeIDString( cNode, 0 ) );
}
else if( cNodeName == wxT( "ORIENT" ) )
{
OverrideOrientation = true;
OrientAngle = GetXmlAttributeIDLong( cNode, 0 );
}
else
{
THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
}
}
}
void CADSTAR_PCB_ARCHIVE_PARSER::COMPONENT::Parse( XNODE* aNode )
{
wxASSERT( aNode->GetName() == wxT( "COMP" ) );
@ -2808,6 +2862,12 @@ void CADSTAR_PCB_ARCHIVE_PARSER::COMPONENT::Parse( XNODE* aNode )
wxString pinLabel = GetXmlAttributeIDString( cNode, 1 );
PinLabels.insert( std::make_pair( pinID, pinLabel ) );
}
else if( cNodeName == wxT( "PADEXCEPTION" ) )
{
PADEXCEPTION padExcept;
padExcept.Parse( cNode );
PadExceptions.insert( std::make_pair( padExcept.ID, padExcept ) );
}
else
{
THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );

View File

@ -246,14 +246,14 @@ public:
LAYER_TYPE Type = LAYER_TYPE::UNDEFINED;
LAYER_SUBTYPE SubType = LAYER_SUBTYPE::LAYERSUBTYPE_NONE;
PHYSICAL_LAYER_ID PhysicalLayer =
UNDEFINED_PHYSICAL_LAYER; ///< If UNDEFINED, no physical layer is
///< assigned (e.g. documentation and
///< construction layers)
LAYER_ID SwapLayerID = UNDEFINED_LAYER_ID; ///< If UNDEFINED_LAYER_ID, no swap layer
ROUTING_BIAS RoutingBias = ROUTING_BIAS::UNBIASED;
long Thickness = 0; ///< Note: Units of length are defined in file header
MATERIAL_ID MaterialId;
EMBEDDING Embedding = EMBEDDING::NONE;
UNDEFINED_PHYSICAL_LAYER; ///< If UNDEFINED, no physical layer is
///< assigned (e.g. documentation and
///< construction layers)
LAYER_ID SwapLayerID = UNDEFINED_LAYER_ID; ///< If UNDEFINED_LAYER_ID, no swap layer
ROUTING_BIAS RoutingBias = ROUTING_BIAS::UNBIASED;
long Thickness = 0; ///< Note: Units of length are defined in file header
MATERIAL_ID MaterialId = UNDEFINED_MATERIAL_ID;
EMBEDDING Embedding = EMBEDDING::NONE;
bool ReferencePlane = false;
bool VariantLayer = false;
@ -800,6 +800,7 @@ public:
enum class UNITS
{
DESIGN, ///< Inherits from design units (assumed Assignments->Technology->Units)
THOU,
INCH,
MICROMETRE,
@ -1039,6 +1040,9 @@ public:
THROUGH_HOLE ///< All physical layers currently defined
};
static PAD_SIDE GetPadSide( const wxString& aPadSideString );
/**
* @brief From CADSTAR help: "For specifying the directions in which routes can enter or exit the
* pad. There are eight pre-defined directions to choose from, North, South, East, West,
@ -1683,6 +1687,19 @@ public:
};
struct PADEXCEPTION
{
PAD_ID ID;
PADCODE_ID PadCode = wxEmptyString; ///< If not empty, override padcode
bool OverrideSide = false;
PAD_SIDE Side;
bool OverrideOrientation = false;
long OrientAngle = 0;
void Parse( XNODE* aNode );
};
struct COMPONENT
{
COMPONENT_ID ID;
@ -1712,6 +1729,7 @@ public:
///< to be out of sync.
///< See PART::DEFINITION::PIN::Label
std::map<PART_DEFINITION_PIN_ID, PIN_ATTRIBUTE> PinAttributes;
std::map<PAD_ID, PADEXCEPTION> PadExceptions;
void Parse( XNODE* aNode );
};