CADSTAR Schematic Archive Importer: Load all Sheets and Hierarchical Blocks
This commit is contained in:
parent
646a733556
commit
2d99703e28
|
@ -295,8 +295,8 @@ void CADSTAR_ARCHIVE_PARSER::EVALUE::Parse( XNODE* aNode )
|
|||
|| ( !GetXmlAttributeIDString( aNode, 1 ).ToLong( &Exponent ) ) )
|
||||
{
|
||||
THROW_PARSING_IO_ERROR( wxT( "Base and Exponent" ),
|
||||
wxString::Format( "%s->%s", aNode->GetParent()->GetName(),
|
||||
aNode->GetParent()->GetName() ) );
|
||||
wxString::Format(
|
||||
"%s->%s", aNode->GetParent()->GetName(), aNode->GetParent()->GetName() ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1928,12 +1928,12 @@ std::vector<CADSTAR_ARCHIVE_PARSER::POINT> CADSTAR_ARCHIVE_PARSER::ParseAllChild
|
|||
}
|
||||
}
|
||||
|
||||
if( aExpectedNumPoints != UNDEFINED_VALUE &&
|
||||
retVal.size() != static_cast<size_t>( aExpectedNumPoints ) )
|
||||
if( aExpectedNumPoints != UNDEFINED_VALUE
|
||||
&& retVal.size() != static_cast<size_t>( aExpectedNumPoints ) )
|
||||
{
|
||||
THROW_IO_ERROR( wxString::Format(
|
||||
_( "Unexpected number of points in '%s'. Found %d but expected %d." ),
|
||||
aNode->GetName(), retVal.size(), aExpectedNumPoints ) );
|
||||
_( "Unexpected number of points in '%s'. Found %d but expected %d." ),
|
||||
aNode->GetName(), retVal.size(), aExpectedNumPoints ) );
|
||||
}
|
||||
|
||||
return retVal;
|
||||
|
|
|
@ -562,8 +562,8 @@ public:
|
|||
///< Note that this is different from BOTTOM_LEFT (which is bottom
|
||||
///< left of the whole text block)
|
||||
|
||||
void ParseIdentifiers( XNODE* aNode );
|
||||
bool ParseSubNode( XNODE* aChildNode );
|
||||
void ParseIdentifiers( XNODE* aNode );
|
||||
bool ParseSubNode( XNODE* aChildNode );
|
||||
virtual void Parse( XNODE* aNode );
|
||||
};
|
||||
|
||||
|
@ -731,10 +731,10 @@ public:
|
|||
{
|
||||
GROUP_ID ID;
|
||||
wxString Name;
|
||||
bool Fixed = false;
|
||||
bool Transfer = false; ///< If true, the group is transferred to PCB
|
||||
GROUP_ID GroupID = wxEmptyString; ///< If not empty, this GROUP
|
||||
///< is part of another GROUP
|
||||
bool Fixed = false;
|
||||
bool Transfer = false; ///< If true, the group is transferred to PCB
|
||||
GROUP_ID GroupID = wxEmptyString; ///< If not empty, this GROUP
|
||||
///< is part of another GROUP
|
||||
REUSEBLOCKREF ReuseBlockRef;
|
||||
|
||||
void Parse( XNODE* aNode );
|
||||
|
@ -1133,7 +1133,8 @@ public:
|
|||
* @return returns the value (wxString) 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, bool aIsRequired = true );
|
||||
static wxString GetXmlAttributeIDString(
|
||||
XNODE* aNode, unsigned int aID, bool aIsRequired = true );
|
||||
|
||||
/**
|
||||
* @brief
|
||||
|
|
|
@ -611,7 +611,7 @@ void SCH_EDIT_FRAME::OnImportProject( wxCommandEvent& aEvent )
|
|||
if( ADVANCED_CFG::GetCfg().m_PluginAltiumSch )
|
||||
loaders.emplace_back( AltiumSchematicFileWildcard(), SCH_IO_MGR::SCH_ALTIUM ); // Import Altium schematic files
|
||||
|
||||
loaders.emplace_back( CadstarSchematicArchiveFileWildcard(), SCH_IO_MGR::CADSTAR_SCH_ARCHIVE ); //Import CADSTAR Schematic Archive files
|
||||
loaders.emplace_back( CadstarSchematicArchiveFileWildcard(), SCH_IO_MGR::SCH_CADSTAR_ARCHIVE ); //Import CADSTAR Schematic Archive files
|
||||
loaders.emplace_back( EagleSchematicFileWildcard(), SCH_IO_MGR::SCH_EAGLE ); // Import Eagle schematic files
|
||||
// clang-format on
|
||||
|
||||
|
@ -868,7 +868,7 @@ bool SCH_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType )
|
|||
switch( (SCH_IO_MGR::SCH_FILE_T) aFileType )
|
||||
{
|
||||
case SCH_IO_MGR::SCH_ALTIUM:
|
||||
case SCH_IO_MGR::CADSTAR_SCH_ARCHIVE:
|
||||
case SCH_IO_MGR::SCH_CADSTAR_ARCHIVE:
|
||||
case SCH_IO_MGR::SCH_EAGLE:
|
||||
// We insist on caller sending us an absolute path, if it does not, we say it's a bug.
|
||||
wxASSERT_MSG( wxFileName( aFileName ).IsAbsolute(),
|
||||
|
|
|
@ -62,7 +62,7 @@ SCH_PLUGIN* SCH_IO_MGR::FindPlugin( SCH_FILE_T aFileType )
|
|||
return new SCH_SEXPR_PLUGIN();
|
||||
case SCH_ALTIUM:
|
||||
return new SCH_ALTIUM_PLUGIN();
|
||||
case CADSTAR_SCH_ARCHIVE:
|
||||
case SCH_CADSTAR_ARCHIVE:
|
||||
return new CADSTAR_SCH_ARCHIVE_PLUGIN();
|
||||
case SCH_EAGLE:
|
||||
return new SCH_EAGLE_PLUGIN();
|
||||
|
@ -104,7 +104,7 @@ const wxString SCH_IO_MGR::ShowType( SCH_FILE_T aType )
|
|||
case SCH_ALTIUM:
|
||||
return wxString( wxT( "Altium" ) );
|
||||
|
||||
case CADSTAR_SCH_ARCHIVE:
|
||||
case SCH_CADSTAR_ARCHIVE:
|
||||
return wxString( wxT( "CADSTAR Schematic Archive" ) );
|
||||
|
||||
case SCH_EAGLE:
|
||||
|
@ -126,7 +126,7 @@ SCH_IO_MGR::SCH_FILE_T SCH_IO_MGR::EnumFromStr( const wxString& aType )
|
|||
else if( aType == wxT( "Altium" ) )
|
||||
return SCH_ALTIUM;
|
||||
else if( aType == wxT( "CADSTAR Schematic Archive" ) )
|
||||
return CADSTAR_SCH_ARCHIVE;
|
||||
return SCH_CADSTAR_ARCHIVE;
|
||||
else if( aType == wxT( "EAGLE" ) )
|
||||
return SCH_EAGLE;
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ public:
|
|||
SCH_LEGACY, ///< Legacy Eeschema file formats prior to s-expression.
|
||||
SCH_KICAD, ///< The s-expression version of the schematic file formats.
|
||||
SCH_ALTIUM, ///< Altium file format
|
||||
CADSTAR_SCH_ARCHIVE, ///< CADSTAR Schematic Archive
|
||||
SCH_CADSTAR_ARCHIVE, ///< CADSTAR Schematic Archive
|
||||
SCH_EAGLE, ///< Autodesk Eagle file format
|
||||
// Add your schematic type here.
|
||||
|
||||
|
|
|
@ -24,13 +24,526 @@
|
|||
*/
|
||||
|
||||
#include <sch_plugins/cadstar/cadstar_sch_archive_loader.h>
|
||||
#include <sch_screen.h>
|
||||
#include <sch_sheet.h>
|
||||
#include <trigo.h>
|
||||
|
||||
|
||||
void CADSTAR_SCH_ARCHIVE_LOADER::Load( ::SCHEMATIC* aSchematic )
|
||||
void CADSTAR_SCH_ARCHIVE_LOADER::Load( ::SCHEMATIC* aSchematic, ::SCH_SHEET* aRootSheet )
|
||||
{
|
||||
Parse();
|
||||
|
||||
mSchematic = aSchematic;
|
||||
LONGPOINT designLimit = Assignments.Settings.DesignLimit;
|
||||
|
||||
// Load everything!
|
||||
//Note: can't use getKiCadPoint() due wxPoint being int - need long long to make the check
|
||||
long long designSizeXkicad = (long long) designLimit.x * KiCadUnitMultiplier;
|
||||
long long designSizeYkicad = (long long) designLimit.y * KiCadUnitMultiplier;
|
||||
|
||||
// Max size limited by the positive dimension of wxPoint (which is an int)
|
||||
long long maxDesignSizekicad = std::numeric_limits<int>::max();
|
||||
|
||||
if( designSizeXkicad > maxDesignSizekicad || designSizeYkicad > maxDesignSizekicad )
|
||||
THROW_IO_ERROR( wxString::Format(
|
||||
_( "The design is too large and cannot be imported into KiCad. \n"
|
||||
"Please reduce the maximum design size in CADSTAR by navigating to: \n"
|
||||
"Design Tab -> Properties -> Design Options -> Maximum Design Size. \n"
|
||||
"Current Design size: %.2f, %.2f millimeters. \n"
|
||||
"Maximum permitted design size: %.2f, %.2f millimeters.\n" ),
|
||||
(double) designSizeXkicad / SCH_IU_PER_MM,
|
||||
(double) designSizeYkicad / SCH_IU_PER_MM,
|
||||
(double) maxDesignSizekicad / SCH_IU_PER_MM,
|
||||
(double) maxDesignSizekicad / SCH_IU_PER_MM ) );
|
||||
|
||||
mDesignCenter =
|
||||
( Assignments.Settings.DesignArea.first + Assignments.Settings.DesignArea.second ) / 2;
|
||||
|
||||
mSchematic = aSchematic;
|
||||
mRootSheet = aRootSheet;
|
||||
|
||||
loadSheets();
|
||||
// Load everything!
|
||||
}
|
||||
|
||||
|
||||
void CADSTAR_SCH_ARCHIVE_LOADER::loadSheets()
|
||||
{
|
||||
const std::vector<LAYER_ID>& orphanSheets = findOrphanSheets();
|
||||
|
||||
if( orphanSheets.size() > 1 )
|
||||
{
|
||||
int x = 1;
|
||||
int y = 1;
|
||||
|
||||
for( LAYER_ID sheetID : orphanSheets )
|
||||
{
|
||||
wxPoint pos( x * Mils2iu( 1000 ), y * Mils2iu( 1000 ) );
|
||||
wxSize siz( Mils2iu( 1000 ), Mils2iu( 1000 ) );
|
||||
|
||||
loadSheetAndChildSheets( sheetID, pos, siz, mRootSheet );
|
||||
|
||||
x += 2;
|
||||
|
||||
if( x > 10 ) // start next row
|
||||
{
|
||||
x = 1;
|
||||
y += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( orphanSheets.size() > 0 )
|
||||
{
|
||||
LAYER_ID rootSheetID = orphanSheets.at( 0 );
|
||||
mSheetMap.insert( { rootSheetID, mRootSheet } );
|
||||
loadChildSheets( rootSheetID );
|
||||
}
|
||||
else
|
||||
{
|
||||
THROW_IO_ERROR( _( "The CADSTAR schematic might be corrupt: there is no root sheet." ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CADSTAR_SCH_ARCHIVE_LOADER::loadSheetAndChildSheets(
|
||||
LAYER_ID aCadstarSheetID, wxPoint aPosition, wxSize aSheetSize, SCH_SHEET* aParentSheet )
|
||||
{
|
||||
wxCHECK_MSG( mSheetMap.find( aCadstarSheetID ) == mSheetMap.end(), , "Sheet already loaded!" );
|
||||
|
||||
SCH_SHEET* sheet = new SCH_SHEET( aParentSheet, aPosition );
|
||||
SCH_SCREEN* screen = new SCH_SCREEN( mSchematic );
|
||||
|
||||
sheet->SetSize( aSheetSize );
|
||||
sheet->SetScreen( screen );
|
||||
|
||||
//wxString name = wxString::Format( "%d", i );
|
||||
wxString name =
|
||||
wxString::Format( "%s - %s", aCadstarSheetID, Sheets.SheetNames.at( aCadstarSheetID ) );
|
||||
|
||||
SCH_FIELD& sheetNameField = sheet->GetFields()[SHEETNAME];
|
||||
SCH_FIELD& filenameField = sheet->GetFields()[SHEETFILENAME];
|
||||
|
||||
sheetNameField.SetText( name );
|
||||
|
||||
wxFileName loadedFilePath = wxFileName( Filename );
|
||||
std::string filename =
|
||||
wxString::Format( "%s_%d", loadedFilePath.GetName(), getSheetNumber( aCadstarSheetID ) )
|
||||
.ToStdString();
|
||||
|
||||
ReplaceIllegalFileNameChars( &filename );
|
||||
filename += wxString( ".kicad_sch" );
|
||||
|
||||
filenameField.SetText( filename );
|
||||
wxFileName fn( filename );
|
||||
sheet->GetScreen()->SetFileName( fn.GetFullPath() );
|
||||
aParentSheet->GetScreen()->Append( sheet );
|
||||
|
||||
mSheetMap.insert( { aCadstarSheetID, sheet } );
|
||||
|
||||
loadChildSheets( aCadstarSheetID );
|
||||
}
|
||||
|
||||
|
||||
void CADSTAR_SCH_ARCHIVE_LOADER::loadChildSheets( LAYER_ID aCadstarSheetID )
|
||||
{
|
||||
wxCHECK_MSG( mSheetMap.find( aCadstarSheetID ) != mSheetMap.end(), ,
|
||||
"FIXME! Parent sheet should be loaded before attempting to load subsheets" );
|
||||
|
||||
for( std::pair<BLOCK_ID, BLOCK> blockPair : Schematic.Blocks )
|
||||
{
|
||||
BLOCK& block = blockPair.second;
|
||||
|
||||
if( block.LayerID == aCadstarSheetID && block.Type == BLOCK::TYPE::CHILD )
|
||||
{
|
||||
// In KiCad you can only draw rectangular shapes whereas in Cadstar arbitrary shapes
|
||||
// are allowed. We will calculate the extents of the Cadstar shape and draw a rectangle
|
||||
|
||||
std::pair<wxPoint, wxSize> blockExtents;
|
||||
|
||||
if( block.Figures.size() > 0 )
|
||||
{
|
||||
blockExtents = getFigureExtentsKiCad( block.Figures.begin()->second );
|
||||
}
|
||||
else
|
||||
{
|
||||
THROW_IO_ERROR( wxString::Format(
|
||||
_( "The CADSTAR schematic might be corrupt: Block %s references a "
|
||||
"child sheet but has no Figure defined." ),
|
||||
block.ID ) );
|
||||
}
|
||||
|
||||
loadSheetAndChildSheets( block.AssocLayerID, blockExtents.first, blockExtents.second,
|
||||
mSheetMap.at( aCadstarSheetID ) );
|
||||
|
||||
if( block.HasBlockLabel )
|
||||
{
|
||||
// Add the block label as a separate field
|
||||
SCH_SHEET* loadedSheet = mSheetMap.at( block.AssocLayerID );
|
||||
SCH_FIELDS fields = loadedSheet->GetFields();
|
||||
|
||||
for( SCH_FIELD& field : fields )
|
||||
{
|
||||
field.SetVisible( false );
|
||||
}
|
||||
|
||||
SCH_FIELD blockNameField( getKiCadPoint( block.BlockLabel.Position ), 2,
|
||||
loadedSheet, wxString( "Block name" ) );
|
||||
applyTextSettings( block.BlockLabel.TextCodeID, block.BlockLabel.Alignment,
|
||||
block.BlockLabel.Justification, &blockNameField );
|
||||
blockNameField.SetTextAngle( getAngleTenthDegree( block.BlockLabel.OrientAngle ) );
|
||||
blockNameField.SetText( block.Name );
|
||||
blockNameField.SetVisible( true );
|
||||
fields.push_back( blockNameField );
|
||||
loadedSheet->SetFields( fields );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::vector<CADSTAR_SCH_ARCHIVE_LOADER::LAYER_ID> CADSTAR_SCH_ARCHIVE_LOADER::findOrphanSheets()
|
||||
{
|
||||
std::vector<LAYER_ID> childSheets, orphanSheets;
|
||||
|
||||
//Find all sheets that are child of another
|
||||
for( std::pair<BLOCK_ID, BLOCK> blockPair : Schematic.Blocks )
|
||||
{
|
||||
BLOCK& block = blockPair.second;
|
||||
LAYER_ID& assocSheetID = block.AssocLayerID;
|
||||
|
||||
if( block.Type == BLOCK::TYPE::CHILD )
|
||||
childSheets.push_back( assocSheetID );
|
||||
}
|
||||
|
||||
//Add sheets that do not have a parent
|
||||
for( LAYER_ID sheetID : Sheets.SheetOrder )
|
||||
{
|
||||
if( std::find( childSheets.begin(), childSheets.end(), sheetID ) == childSheets.end() )
|
||||
orphanSheets.push_back( sheetID );
|
||||
}
|
||||
|
||||
return orphanSheets;
|
||||
}
|
||||
|
||||
|
||||
int CADSTAR_SCH_ARCHIVE_LOADER::getSheetNumber( LAYER_ID aCadstarSheetID )
|
||||
{
|
||||
int i = 1;
|
||||
|
||||
for( LAYER_ID sheetID : Sheets.SheetOrder )
|
||||
{
|
||||
if( sheetID == aCadstarSheetID )
|
||||
return i;
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
void CADSTAR_SCH_ARCHIVE_LOADER::checkAndLogHatchCode( const HATCHCODE_ID& aCadstarHatchcodeID )
|
||||
{
|
||||
if( mHatchcodesTested.find( aCadstarHatchcodeID ) != mHatchcodesTested.end() )
|
||||
{
|
||||
return; //already checked
|
||||
}
|
||||
else
|
||||
{
|
||||
HATCHCODE hcode = getHatchCode( aCadstarHatchcodeID );
|
||||
|
||||
if( hcode.Hatches.size() != 2 )
|
||||
{
|
||||
wxLogWarning( wxString::Format(
|
||||
_( "The CADSTAR Hatching code '%s' has %d hatches defined. "
|
||||
"KiCad only supports 2 hatches (crosshatching) 90 degrees apart. "
|
||||
"The imported hatching is crosshatched." ),
|
||||
hcode.Name, (int) hcode.Hatches.size() ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( hcode.Hatches.at( 0 ).LineWidth != hcode.Hatches.at( 1 ).LineWidth )
|
||||
{
|
||||
wxLogWarning( wxString::Format(
|
||||
_( "The CADSTAR Hatching code '%s' has different line widths for each "
|
||||
"hatch. KiCad only supports one width for the haching. The imported "
|
||||
"hatching uses the width defined in the first hatch definition, i.e. "
|
||||
"%.2f mm." ),
|
||||
hcode.Name,
|
||||
(double) ( (double) getKiCadLength( hcode.Hatches.at( 0 ).LineWidth ) )
|
||||
/ 1E6 ) );
|
||||
}
|
||||
|
||||
if( hcode.Hatches.at( 0 ).Step != hcode.Hatches.at( 1 ).Step )
|
||||
{
|
||||
wxLogWarning( wxString::Format(
|
||||
_( "The CADSTAR Hatching code '%s' has different step sizes for each "
|
||||
"hatch. KiCad only supports one step size for the haching. The imported "
|
||||
"hatching uses the step size defined in the first hatching definition, "
|
||||
"i.e. %.2f mm." ),
|
||||
hcode.Name,
|
||||
(double) ( (double) getKiCadLength( hcode.Hatches.at( 0 ).Step ) )
|
||||
/ 1E6 ) );
|
||||
}
|
||||
|
||||
if( abs( hcode.Hatches.at( 0 ).OrientAngle - hcode.Hatches.at( 1 ).OrientAngle )
|
||||
!= 90000 )
|
||||
{
|
||||
wxLogWarning( wxString::Format(
|
||||
_( "The hatches in CADSTAR Hatching code '%s' have an angle "
|
||||
"difference of %.1f degrees. KiCad only supports hatching 90 "
|
||||
"degrees apart. The imported hatching has two hatches 90 "
|
||||
"degrees apart, oriented %.1f degrees from horizontal." ),
|
||||
hcode.Name,
|
||||
getAngleDegrees( abs( hcode.Hatches.at( 0 ).OrientAngle
|
||||
- hcode.Hatches.at( 1 ).OrientAngle ) ),
|
||||
getAngleDegrees( hcode.Hatches.at( 0 ).OrientAngle ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
mHatchcodesTested.insert( aCadstarHatchcodeID );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int CADSTAR_SCH_ARCHIVE_LOADER::getLineThickness( const LINECODE_ID& aCadstarLineCodeID )
|
||||
{
|
||||
wxCHECK( Assignments.Codedefs.LineCodes.find( aCadstarLineCodeID )
|
||||
!= Assignments.Codedefs.LineCodes.end(),
|
||||
mSchematic->Settings().m_DefaultWireThickness );
|
||||
|
||||
return getKiCadLength( Assignments.Codedefs.LineCodes.at( aCadstarLineCodeID ).Width );
|
||||
}
|
||||
|
||||
|
||||
CADSTAR_SCH_ARCHIVE_LOADER::HATCHCODE CADSTAR_SCH_ARCHIVE_LOADER::getHatchCode(
|
||||
const HATCHCODE_ID& aCadstarHatchcodeID )
|
||||
{
|
||||
wxCHECK( Assignments.Codedefs.HatchCodes.find( aCadstarHatchcodeID )
|
||||
!= Assignments.Codedefs.HatchCodes.end(),
|
||||
HATCHCODE() );
|
||||
|
||||
return Assignments.Codedefs.HatchCodes.at( aCadstarHatchcodeID );
|
||||
}
|
||||
|
||||
|
||||
CADSTAR_SCH_ARCHIVE_LOADER::TEXTCODE CADSTAR_SCH_ARCHIVE_LOADER::getTextCode(
|
||||
const TEXTCODE_ID& aCadstarTextCodeID )
|
||||
{
|
||||
wxCHECK( Assignments.Codedefs.TextCodes.find( aCadstarTextCodeID )
|
||||
!= Assignments.Codedefs.TextCodes.end(),
|
||||
TEXTCODE() );
|
||||
|
||||
return Assignments.Codedefs.TextCodes.at( aCadstarTextCodeID );
|
||||
}
|
||||
|
||||
|
||||
wxString CADSTAR_SCH_ARCHIVE_LOADER::getAttributeName( const ATTRIBUTE_ID& aCadstarAttributeID )
|
||||
{
|
||||
wxCHECK( Assignments.Codedefs.AttributeNames.find( aCadstarAttributeID )
|
||||
!= Assignments.Codedefs.AttributeNames.end(),
|
||||
wxEmptyString );
|
||||
|
||||
return Assignments.Codedefs.AttributeNames.at( aCadstarAttributeID ).Name;
|
||||
}
|
||||
|
||||
|
||||
CADSTAR_SCH_ARCHIVE_LOADER::PART CADSTAR_SCH_ARCHIVE_LOADER::getPart(
|
||||
const PART_ID& aCadstarPartID )
|
||||
{
|
||||
wxCHECK( Parts.PartDefinitions.find( aCadstarPartID ) != Parts.PartDefinitions.end(), PART() );
|
||||
|
||||
return Parts.PartDefinitions.at( aCadstarPartID );
|
||||
}
|
||||
|
||||
|
||||
CADSTAR_SCH_ARCHIVE_LOADER::ROUTECODE CADSTAR_SCH_ARCHIVE_LOADER::getRouteCode(
|
||||
const ROUTECODE_ID& aCadstarRouteCodeID )
|
||||
{
|
||||
wxCHECK( Assignments.Codedefs.RouteCodes.find( aCadstarRouteCodeID )
|
||||
!= Assignments.Codedefs.RouteCodes.end(),
|
||||
ROUTECODE() );
|
||||
|
||||
return Assignments.Codedefs.RouteCodes.at( aCadstarRouteCodeID );
|
||||
}
|
||||
|
||||
|
||||
wxString CADSTAR_SCH_ARCHIVE_LOADER::getAttributeValue( const ATTRIBUTE_ID& aCadstarAttributeID,
|
||||
const std::map<ATTRIBUTE_ID, ATTRIBUTE_VALUE>& aCadstarAttributeMap )
|
||||
{
|
||||
wxCHECK( aCadstarAttributeMap.find( aCadstarAttributeID ) != aCadstarAttributeMap.end(),
|
||||
wxEmptyString );
|
||||
|
||||
return aCadstarAttributeMap.at( aCadstarAttributeID ).Value;
|
||||
}
|
||||
|
||||
|
||||
double CADSTAR_SCH_ARCHIVE_LOADER::getHatchCodeAngleDegrees(
|
||||
const HATCHCODE_ID& aCadstarHatchcodeID )
|
||||
{
|
||||
checkAndLogHatchCode( aCadstarHatchcodeID );
|
||||
HATCHCODE hcode = getHatchCode( aCadstarHatchcodeID );
|
||||
|
||||
if( hcode.Hatches.size() < 1 )
|
||||
return mSchematic->Settings().m_DefaultWireThickness;
|
||||
else
|
||||
return getAngleDegrees( hcode.Hatches.at( 0 ).OrientAngle );
|
||||
}
|
||||
|
||||
|
||||
int CADSTAR_SCH_ARCHIVE_LOADER::getKiCadHatchCodeThickness(
|
||||
const HATCHCODE_ID& aCadstarHatchcodeID )
|
||||
{
|
||||
checkAndLogHatchCode( aCadstarHatchcodeID );
|
||||
HATCHCODE hcode = getHatchCode( aCadstarHatchcodeID );
|
||||
|
||||
if( hcode.Hatches.size() < 1 )
|
||||
return mSchematic->Settings().m_DefaultWireThickness;
|
||||
else
|
||||
return getKiCadLength( hcode.Hatches.at( 0 ).LineWidth );
|
||||
}
|
||||
|
||||
|
||||
int CADSTAR_SCH_ARCHIVE_LOADER::getKiCadHatchCodeGap( const HATCHCODE_ID& aCadstarHatchcodeID )
|
||||
{
|
||||
checkAndLogHatchCode( aCadstarHatchcodeID );
|
||||
HATCHCODE hcode = getHatchCode( aCadstarHatchcodeID );
|
||||
|
||||
if( hcode.Hatches.size() < 1 )
|
||||
return mSchematic->Settings().m_DefaultWireThickness;
|
||||
else
|
||||
return getKiCadLength( hcode.Hatches.at( 0 ).Step );
|
||||
}
|
||||
|
||||
int CADSTAR_SCH_ARCHIVE_LOADER::getKiCadUnitNumberFromGate( const GATE_ID& aCadstarGateID )
|
||||
{
|
||||
if( aCadstarGateID.IsEmpty() )
|
||||
return 1;
|
||||
|
||||
return (int) aCadstarGateID.Upper().GetChar( 0 ) - (int) wxUniChar( 'A' ) + 1;
|
||||
}
|
||||
|
||||
|
||||
void CADSTAR_SCH_ARCHIVE_LOADER::applyTextSettings( const TEXTCODE_ID& aCadstarTextCodeID,
|
||||
const ALIGNMENT& aCadstarAlignment, const JUSTIFICATION& aCadstarJustification,
|
||||
EDA_TEXT* aKiCadTextItem )
|
||||
{
|
||||
TEXTCODE textCode = getTextCode( aCadstarTextCodeID );
|
||||
|
||||
aKiCadTextItem->SetTextWidth( getKiCadLength( textCode.Width ) );
|
||||
aKiCadTextItem->SetTextHeight( getKiCadLength( textCode.Height ) );
|
||||
aKiCadTextItem->SetTextThickness( getKiCadLength( textCode.LineWidth ) );
|
||||
|
||||
switch( aCadstarAlignment )
|
||||
{
|
||||
case ALIGNMENT::NO_ALIGNMENT: // Default for Single line text is Bottom Left
|
||||
case ALIGNMENT::BOTTOMLEFT:
|
||||
aKiCadTextItem->SetVertJustify( GR_TEXT_VJUSTIFY_BOTTOM );
|
||||
aKiCadTextItem->SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT );
|
||||
break;
|
||||
|
||||
case ALIGNMENT::BOTTOMCENTER:
|
||||
aKiCadTextItem->SetVertJustify( GR_TEXT_VJUSTIFY_BOTTOM );
|
||||
aKiCadTextItem->SetHorizJustify( GR_TEXT_HJUSTIFY_CENTER );
|
||||
break;
|
||||
|
||||
case ALIGNMENT::BOTTOMRIGHT:
|
||||
aKiCadTextItem->SetVertJustify( GR_TEXT_VJUSTIFY_BOTTOM );
|
||||
aKiCadTextItem->SetHorizJustify( GR_TEXT_HJUSTIFY_RIGHT );
|
||||
break;
|
||||
|
||||
case ALIGNMENT::CENTERLEFT:
|
||||
aKiCadTextItem->SetVertJustify( GR_TEXT_VJUSTIFY_CENTER );
|
||||
aKiCadTextItem->SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT );
|
||||
break;
|
||||
|
||||
case ALIGNMENT::CENTERCENTER:
|
||||
aKiCadTextItem->SetVertJustify( GR_TEXT_VJUSTIFY_CENTER );
|
||||
aKiCadTextItem->SetHorizJustify( GR_TEXT_HJUSTIFY_CENTER );
|
||||
break;
|
||||
|
||||
case ALIGNMENT::CENTERRIGHT:
|
||||
aKiCadTextItem->SetVertJustify( GR_TEXT_VJUSTIFY_CENTER );
|
||||
aKiCadTextItem->SetHorizJustify( GR_TEXT_HJUSTIFY_RIGHT );
|
||||
break;
|
||||
|
||||
case ALIGNMENT::TOPLEFT:
|
||||
aKiCadTextItem->SetVertJustify( GR_TEXT_VJUSTIFY_TOP );
|
||||
aKiCadTextItem->SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT );
|
||||
break;
|
||||
|
||||
case ALIGNMENT::TOPCENTER:
|
||||
aKiCadTextItem->SetVertJustify( GR_TEXT_VJUSTIFY_TOP );
|
||||
aKiCadTextItem->SetHorizJustify( GR_TEXT_HJUSTIFY_CENTER );
|
||||
break;
|
||||
|
||||
case ALIGNMENT::TOPRIGHT:
|
||||
aKiCadTextItem->SetVertJustify( GR_TEXT_VJUSTIFY_TOP );
|
||||
aKiCadTextItem->SetHorizJustify( GR_TEXT_HJUSTIFY_RIGHT );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::pair<wxPoint, wxSize> CADSTAR_SCH_ARCHIVE_LOADER::getFigureExtentsKiCad(
|
||||
const FIGURE& aCadstarFigure )
|
||||
{
|
||||
wxPoint upperLeft( Assignments.Settings.DesignLimit.x, 0 );
|
||||
wxPoint lowerRight( 0, Assignments.Settings.DesignLimit.y );
|
||||
|
||||
for( const VERTEX& v : aCadstarFigure.Shape.Vertices )
|
||||
{
|
||||
if( upperLeft.x > v.End.x )
|
||||
upperLeft.x = v.End.x;
|
||||
|
||||
if( upperLeft.y < v.End.y )
|
||||
upperLeft.y = v.End.y;
|
||||
|
||||
if( lowerRight.x < v.End.x )
|
||||
lowerRight.x = v.End.x;
|
||||
|
||||
if( lowerRight.y > v.End.y )
|
||||
lowerRight.y = v.End.y;
|
||||
}
|
||||
|
||||
for( CUTOUT cutout : aCadstarFigure.Shape.Cutouts )
|
||||
{
|
||||
for( const VERTEX& v : aCadstarFigure.Shape.Vertices )
|
||||
{
|
||||
if( upperLeft.x > v.End.x )
|
||||
upperLeft.x = v.End.x;
|
||||
|
||||
if( upperLeft.y < v.End.y )
|
||||
upperLeft.y = v.End.y;
|
||||
|
||||
if( lowerRight.x < v.End.x )
|
||||
lowerRight.x = v.End.x;
|
||||
|
||||
if( lowerRight.y > v.End.y )
|
||||
lowerRight.y = v.End.y;
|
||||
}
|
||||
}
|
||||
|
||||
wxPoint upperLeftKiCad = getKiCadPoint( upperLeft );
|
||||
wxPoint lowerRightKiCad = getKiCadPoint( lowerRight );
|
||||
|
||||
wxPoint size = lowerRightKiCad - upperLeftKiCad;
|
||||
|
||||
return { upperLeftKiCad, wxSize( abs( size.x ), abs( size.y ) ) };
|
||||
}
|
||||
|
||||
|
||||
wxPoint CADSTAR_SCH_ARCHIVE_LOADER::getKiCadPoint( wxPoint aCadstarPoint )
|
||||
{
|
||||
wxPoint retval;
|
||||
|
||||
retval.x = ( aCadstarPoint.x - mDesignCenter.x ) * KiCadUnitMultiplier;
|
||||
retval.y = -( aCadstarPoint.y - mDesignCenter.y ) * KiCadUnitMultiplier;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
double CADSTAR_SCH_ARCHIVE_LOADER::getPolarAngle( wxPoint aPoint )
|
||||
{
|
||||
|
||||
return NormalizeAnglePos( ArcTangente( aPoint.y, aPoint.x ) );
|
||||
}
|
||||
|
|
|
@ -27,8 +27,9 @@
|
|||
#define CADSTAR_SCH_ARCHIVE_LOADER_H_
|
||||
|
||||
#include <sch_plugins/cadstar/cadstar_sch_archive_parser.h>
|
||||
#include <schematic.h>
|
||||
|
||||
#include <eda_text.h>
|
||||
#include <schematic.h>
|
||||
|
||||
class CADSTAR_SCH_ARCHIVE_LOADER : public CADSTAR_SCH_ARCHIVE_PARSER
|
||||
{
|
||||
|
@ -36,7 +37,10 @@ public:
|
|||
explicit CADSTAR_SCH_ARCHIVE_LOADER( wxString aFilename )
|
||||
: CADSTAR_SCH_ARCHIVE_PARSER( aFilename )
|
||||
{
|
||||
mSchematic = nullptr;
|
||||
mSchematic = nullptr;
|
||||
mRootSheet = nullptr;
|
||||
mDesignCenter.x = 0;
|
||||
mDesignCenter.y = 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -46,13 +50,89 @@ public:
|
|||
|
||||
/**
|
||||
* @brief Loads a CADSTAR PCB Archive file into the KiCad BOARD object given
|
||||
* @param aBoard
|
||||
* @param aSchematic Schematic to add the design onto
|
||||
* @param aRootSheet Root sheet to add the design onto
|
||||
*/
|
||||
void Load( ::SCHEMATIC* aSchematic );
|
||||
void Load( ::SCHEMATIC* aSchematic, ::SCH_SHEET* aRootSheet );
|
||||
|
||||
|
||||
private:
|
||||
::SCHEMATIC* mSchematic;
|
||||
::SCH_SHEET* mRootSheet;
|
||||
wxPoint mDesignCenter; ///< Used for calculating the required
|
||||
///< offset to apply to the Cadstar design
|
||||
///< so that it fits in KiCad canvas
|
||||
std::set<HATCHCODE_ID> mHatchcodesTested; ///< Used by checkAndLogHatchCode() to
|
||||
///< avoid multiple duplicate warnings
|
||||
std::map<LAYER_ID, SCH_SHEET*> mSheetMap; ///< Map between Cadstar and KiCad
|
||||
|
||||
void loadSheets();
|
||||
|
||||
//Helper Functions for loading
|
||||
void loadSheetAndChildSheets( LAYER_ID aCadstarSheetID, wxPoint aPosition, wxSize aSheetSize,
|
||||
SCH_SHEET* aParentSheet );
|
||||
void loadChildSheets( LAYER_ID aCadstarSheetID );
|
||||
std::vector<LAYER_ID> findOrphanSheets();
|
||||
int getSheetNumber( LAYER_ID aCadstarSheetID );
|
||||
|
||||
void checkAndLogHatchCode( const HATCHCODE_ID& aCadstarHatchcodeID );
|
||||
|
||||
//Helper Functions for obtaining CADSTAR elements in the parsed structures
|
||||
int getLineThickness( const LINECODE_ID& aCadstarLineCodeID );
|
||||
HATCHCODE getHatchCode( const HATCHCODE_ID& aCadstarHatchcodeID );
|
||||
PART getPart( const PART_ID& aCadstarPartID );
|
||||
ROUTECODE getRouteCode( const ROUTECODE_ID& aCadstarRouteCodeID );
|
||||
TEXTCODE getTextCode( const TEXTCODE_ID& aCadstarTextCodeID );
|
||||
wxString getAttributeName( const ATTRIBUTE_ID& aCadstarAttributeID );
|
||||
wxString getAttributeValue( const ATTRIBUTE_ID& aCadstarAttributeID,
|
||||
const std::map<ATTRIBUTE_ID, ATTRIBUTE_VALUE>& aCadstarAttributeMap );
|
||||
|
||||
// Helper Functions for obtaining individual elements as KiCad elements:
|
||||
double getHatchCodeAngleDegrees( const HATCHCODE_ID& aCadstarHatchcodeID );
|
||||
int getKiCadHatchCodeThickness( const HATCHCODE_ID& aCadstarHatchcodeID );
|
||||
int getKiCadHatchCodeGap( const HATCHCODE_ID& aCadstarHatchcodeID );
|
||||
|
||||
|
||||
void applyTextSettings( const TEXTCODE_ID& aCadstarTextCodeID,
|
||||
const ALIGNMENT& aCadstarAlignment, const JUSTIFICATION& aCadstarJustification,
|
||||
EDA_TEXT* aKiCadTextItem );
|
||||
|
||||
std::pair<wxPoint, wxSize> getFigureExtentsKiCad( const FIGURE& aCadstarFigure );
|
||||
|
||||
wxPoint getKiCadPoint( wxPoint aCadstarPoint );
|
||||
|
||||
|
||||
int getKiCadLength( long long aCadstarLength )
|
||||
{
|
||||
return aCadstarLength * KiCadUnitMultiplier;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* @param aCadstarAngle
|
||||
* @return
|
||||
*/
|
||||
double getAngleTenthDegree( const long long& aCadstarAngle )
|
||||
{
|
||||
return (double) aCadstarAngle / 100.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* @param aCadstarAngle
|
||||
* @return
|
||||
*/
|
||||
double getAngleDegrees( const long long& aCadstarAngle )
|
||||
{
|
||||
return (double) aCadstarAngle / 1000.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* @param aPoint
|
||||
* @return Angle in decidegrees of the polar representation of the point, scaled 0..360
|
||||
*/
|
||||
double getPolarAngle( wxPoint aPoint );
|
||||
|
||||
}; // CADSTAR_SCH_ARCHIVE_LOADER
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
* @brief Reads in a CADSTAR Schematic Archive (*.csa) file
|
||||
*/
|
||||
|
||||
#include <convert_to_biu.h> // SCH_IU_PER_MM
|
||||
#include <sch_plugins/cadstar/cadstar_sch_archive_parser.h>
|
||||
|
||||
|
||||
|
@ -44,7 +45,7 @@ void CADSTAR_SCH_ARCHIVE_PARSER::Parse()
|
|||
switch( Header.Resolution )
|
||||
{
|
||||
case RESOLUTION::HUNDREDTH_MICRON:
|
||||
KiCadUnitMultiplier = 100;
|
||||
KiCadUnitMultiplier = SCH_IU_PER_MM / 1e5;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -147,14 +148,26 @@ void CADSTAR_SCH_ARCHIVE_PARSER::TERMINAL_SHAPE::Parse( XNODE* aNode )
|
|||
|
||||
case TERMINAL_SHAPE_TYPE::ROUNDED_RECT:
|
||||
InternalFeature = GetXmlAttributeIDLong( aNode, 3 );
|
||||
//Fall through
|
||||
KI_FALLTHROUGH;
|
||||
|
||||
case TERMINAL_SHAPE_TYPE::BULLET:
|
||||
case TERMINAL_SHAPE_TYPE::FINGER:
|
||||
case TERMINAL_SHAPE_TYPE::POINTER:
|
||||
case TERMINAL_SHAPE_TYPE::RECTANGLE:
|
||||
case TERMINAL_SHAPE_TYPE::TRIANGLE:
|
||||
RightLength = GetXmlAttributeIDLong( aNode, 2 );
|
||||
LeftLength = GetXmlAttributeIDLong( aNode, 1 );
|
||||
LeftLength = GetXmlAttributeIDLong( aNode, 1 );
|
||||
break;
|
||||
|
||||
case TERMINAL_SHAPE_TYPE::CIRCLE:
|
||||
case TERMINAL_SHAPE_TYPE::DIAMOND:
|
||||
case TERMINAL_SHAPE_TYPE::OCTAGON:
|
||||
case TERMINAL_SHAPE_TYPE::SQUARE:
|
||||
KI_FALLTHROUGH; //don't do anything
|
||||
break;
|
||||
|
||||
case TERMINAL_SHAPE_TYPE::UNDEFINED:
|
||||
wxASSERT_MSG( false, "Unknown terminal shape type" );
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -285,7 +298,7 @@ void CADSTAR_SCH_ARCHIVE_PARSER::TERMINAL::Parse( XNODE* aNode )
|
|||
void CADSTAR_SCH_ARCHIVE_PARSER::PIN_NUM_LABEL_LOC::Parse( XNODE* aNode )
|
||||
{
|
||||
wxCHECK( aNode->GetName() == wxT( "PINLABELLOC" )
|
||||
|| aNode->GetName() == wxT( "PINNUMNAMELOC" ), );
|
||||
|| aNode->GetName() == wxT( "PINNUMNAMELOC" ), );
|
||||
|
||||
TerminalID = GetXmlAttributeIDLong( aNode, 0 );
|
||||
TextCodeID = GetXmlAttributeIDString( aNode, 1 );
|
||||
|
@ -385,7 +398,8 @@ void CADSTAR_SCH_ARCHIVE_PARSER::SHEETS::Parse( XNODE* aNode )
|
|||
{
|
||||
LAYER_ID id = GetXmlAttributeIDString( cNode, 0 );
|
||||
SHEET_NAME name = GetXmlAttributeIDString( cNode, 1 );
|
||||
Sheets.insert( std::make_pair( id, name ) );
|
||||
SheetNames.insert( std::make_pair( id, name ) );
|
||||
SheetOrder.push_back( id );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -480,7 +494,7 @@ void CADSTAR_SCH_ARCHIVE_PARSER::SYMBOLVARIANT::Parse( XNODE* aNode )
|
|||
}
|
||||
else if( cNodeName == wxT( "GLOBALSIGNAL" ) )
|
||||
{
|
||||
Type = TYPE::GLOBALSIGNAL;
|
||||
Type = TYPE::GLOBALSIGNAL;
|
||||
Reference = GetXmlAttributeIDString( cNode, 0 );
|
||||
}
|
||||
else
|
||||
|
@ -517,7 +531,7 @@ void CADSTAR_SCH_ARCHIVE_PARSER::SIGNALREFERENCELINK::Parse( XNODE* aNode )
|
|||
void CADSTAR_SCH_ARCHIVE_PARSER::SYMBOL::Parse( XNODE* aNode )
|
||||
{
|
||||
wxCHECK( aNode->GetName() == wxT( "SYMBOL" ), );
|
||||
|
||||
|
||||
ID = GetXmlAttributeIDString( aNode, 0 );
|
||||
SymdefID = GetXmlAttributeIDString( aNode, 1 );
|
||||
LayerID = GetXmlAttributeIDString( aNode, 2 );
|
||||
|
@ -550,7 +564,7 @@ void CADSTAR_SCH_ARCHIVE_PARSER::SYMBOL::Parse( XNODE* aNode )
|
|||
else if( cNodeName == wxT( "VSYMMASTER" ) )
|
||||
{
|
||||
VariantParentSymbolID = GetXmlAttributeIDString( aNode, 0 );
|
||||
VariantID = GetXmlAttributeIDString( aNode, 1 );
|
||||
VariantID = GetXmlAttributeIDString( aNode, 1 );
|
||||
}
|
||||
else if( cNodeName == wxT( "GROUPREF" ) )
|
||||
GroupID = GetXmlAttributeIDString( cNode, 0 );
|
||||
|
@ -654,7 +668,7 @@ void CADSTAR_SCH_ARCHIVE_PARSER::BUS::Parse( XNODE* aNode )
|
|||
|
||||
if( subNode )
|
||||
{
|
||||
if(subNode->GetName() == wxT("SIGLOC"))
|
||||
if( subNode->GetName() == wxT( "SIGLOC" ) )
|
||||
{
|
||||
BusLabel.Parse( subNode );
|
||||
HasBusLabel = true;
|
||||
|
@ -673,8 +687,8 @@ void CADSTAR_SCH_ARCHIVE_PARSER::BLOCK::Parse( XNODE* aNode )
|
|||
{
|
||||
wxCHECK( aNode->GetName() == wxT( "BLOCK" ), );
|
||||
|
||||
ID = GetXmlAttributeIDString( aNode, 0 );
|
||||
LayerID = GetXmlAttributeIDString( aNode, 2 );
|
||||
ID = GetXmlAttributeIDString( aNode, 0 );
|
||||
LayerID = GetXmlAttributeIDString( aNode, 2 );
|
||||
|
||||
XNODE* cNode = aNode->GetChildren();
|
||||
|
||||
|
@ -682,7 +696,7 @@ void CADSTAR_SCH_ARCHIVE_PARSER::BLOCK::Parse( XNODE* aNode )
|
|||
{
|
||||
wxString cNodeName = cNode->GetName();
|
||||
|
||||
|
||||
|
||||
if( cNodeName == wxT( "CLONE" ) )
|
||||
Type = TYPE::CLONE;
|
||||
else if( cNodeName == wxT( "PARENT" ) )
|
||||
|
@ -736,7 +750,7 @@ void CADSTAR_SCH_ARCHIVE_PARSER::NET_SCH::SYM_TERM::Parse( XNODE* aNode )
|
|||
ID = GetXmlAttributeIDString( aNode, 0 );
|
||||
SymbolID = GetXmlAttributeIDString( aNode, 1 );
|
||||
TerminalID = GetXmlAttributeIDLong( aNode, 2 );
|
||||
|
||||
|
||||
|
||||
XNODE* cNode = aNode->GetChildren();
|
||||
|
||||
|
@ -759,12 +773,12 @@ void CADSTAR_SCH_ARCHIVE_PARSER::NET_SCH::BUS_TERM::Parse( XNODE* aNode )
|
|||
{
|
||||
wxASSERT( aNode->GetName() == wxT( "BUSTERM" ) );
|
||||
|
||||
ID = GetXmlAttributeIDString( aNode, 0 );
|
||||
BusID = GetXmlAttributeIDString( aNode, 1 );
|
||||
|
||||
ID = GetXmlAttributeIDString( aNode, 0 );
|
||||
BusID = GetXmlAttributeIDString( aNode, 1 );
|
||||
|
||||
XNODE* cNode = aNode->GetChildren();
|
||||
bool firstPointParsed = false;
|
||||
|
||||
XNODE* cNode = aNode->GetChildren();
|
||||
bool firstPointParsed = false;
|
||||
bool secondPointParsed = false;
|
||||
|
||||
for( ; cNode; cNode = cNode->GetNext() )
|
||||
|
@ -789,8 +803,9 @@ void CADSTAR_SCH_ARCHIVE_PARSER::NET_SCH::BUS_TERM::Parse( XNODE* aNode )
|
|||
secondPointParsed = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
|
||||
|
@ -831,7 +846,7 @@ void CADSTAR_SCH_ARCHIVE_PARSER::NET_SCH::CONNECTION_SCH::Parse( XNODE* aNode )
|
|||
ParseIdentifiers( aNode );
|
||||
LayerID = GetXmlAttributeIDString( aNode, 3 );
|
||||
|
||||
XNODE* cNode = aNode->GetChildren();
|
||||
XNODE* cNode = aNode->GetChildren();
|
||||
|
||||
for( ; cNode; cNode = cNode->GetNext() )
|
||||
{
|
||||
|
@ -895,7 +910,9 @@ void CADSTAR_SCH_ARCHIVE_PARSER::NET_SCH::Parse( XNODE* aNode )
|
|||
Connections.push_back( conn );
|
||||
}
|
||||
else
|
||||
{
|
||||
THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, wxT( "NET" ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -904,9 +921,7 @@ void CADSTAR_SCH_ARCHIVE_PARSER::SCHEMATIC::Parse( XNODE* aNode )
|
|||
{
|
||||
wxCHECK( aNode->GetName() == wxT( "SCHEMATIC" ), );
|
||||
|
||||
XNODE* cNode = aNode->GetChildren();
|
||||
bool netSynchParsed = false;
|
||||
bool dimensionsParsed = false;
|
||||
XNODE* cNode = aNode->GetChildren();
|
||||
|
||||
for( ; cNode; cNode = cNode->GetNext() )
|
||||
{
|
||||
|
@ -975,4 +990,4 @@ void CADSTAR_SCH_ARCHIVE_PARSER::SCHEMATIC::Parse( XNODE* aNode )
|
|||
THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,9 +36,8 @@ class CADSTAR_SCH_ARCHIVE_PARSER : public CADSTAR_ARCHIVE_PARSER
|
|||
{
|
||||
public:
|
||||
explicit CADSTAR_SCH_ARCHIVE_PARSER( wxString aFilename )
|
||||
: Filename( aFilename ), CADSTAR_ARCHIVE_PARSER()
|
||||
: CADSTAR_ARCHIVE_PARSER(), Filename( aFilename ), KiCadUnitMultiplier( 0.1 )
|
||||
{
|
||||
// KiCadUnitMultiplier = 10; // assume hundredth micron
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -48,7 +47,7 @@ public:
|
|||
*/
|
||||
void Parse();
|
||||
|
||||
|
||||
|
||||
typedef wxString TERMINALCODE_ID;
|
||||
typedef wxString SYMBOL_ID;
|
||||
typedef wxString BUS_ID;
|
||||
|
@ -113,11 +112,11 @@ public:
|
|||
|
||||
struct ASSIGNMENTS_SCM
|
||||
{
|
||||
CODEDEFS_SCM Codedefs;
|
||||
GRIDS Grids;
|
||||
SETTINGS Settings;
|
||||
bool NetclassEditAttributeSettings = false; //< Unclear what this does
|
||||
bool SpacingclassEditAttributeSettings = false; //< Unclear what this does
|
||||
CODEDEFS_SCM Codedefs;
|
||||
GRIDS Grids;
|
||||
SETTINGS Settings;
|
||||
bool NetclassEditAttributeSettings = false; //< Unclear what this does
|
||||
bool SpacingclassEditAttributeSettings = false; //< Unclear what this does
|
||||
|
||||
void Parse( XNODE* aNode );
|
||||
};
|
||||
|
@ -141,10 +140,10 @@ public:
|
|||
void Parse( XNODE* aNode ) override;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct SYMDEF_SCM : CADSTAR_ARCHIVE_PARSER::SYMDEF
|
||||
{
|
||||
std::map<TERMINAL_ID, TERMINAL> Terminals;
|
||||
std::map<TERMINAL_ID, TERMINAL> Terminals;
|
||||
std::map<TERMINAL_ID, PIN_NUM_LABEL_LOC> PinLabelLocations;
|
||||
std::map<TERMINAL_ID, PIN_NUM_LABEL_LOC> PinNumberLocations;
|
||||
|
||||
|
@ -163,7 +162,9 @@ public:
|
|||
|
||||
struct SHEETS
|
||||
{
|
||||
std::map<LAYER_ID, SHEET_NAME> Sheets;
|
||||
std::map<LAYER_ID, SHEET_NAME> SheetNames;
|
||||
std::vector<LAYER_ID> SheetOrder; ///< A vector to also store the order in which
|
||||
///< sheets are to be displayed
|
||||
|
||||
void Parse( XNODE* aNode );
|
||||
};
|
||||
|
@ -194,7 +195,7 @@ public:
|
|||
struct SYMPINNAME_LABEL
|
||||
{
|
||||
TERMINAL_ID TerminalID;
|
||||
wxString NameOrLabel;
|
||||
wxString NameOrLabel;
|
||||
bool HasLocation = false;
|
||||
ATTRIBUTE_LOCATION AttrLoc;
|
||||
|
||||
|
@ -209,9 +210,9 @@ public:
|
|||
GLOBALSIGNAL,
|
||||
SIGNALREF
|
||||
//TODO: there might be others
|
||||
};
|
||||
};
|
||||
|
||||
TYPE Type;
|
||||
TYPE Type;
|
||||
wxString Reference;
|
||||
|
||||
void Parse( XNODE* aNode );
|
||||
|
@ -223,7 +224,7 @@ public:
|
|||
wxString Text; ///< This contains the numbers of the other sheets where the
|
||||
///< signal reference is present separated by commas
|
||||
|
||||
void Parse( XNODE* aNode );
|
||||
void Parse( XNODE* aNode ) override;
|
||||
};
|
||||
|
||||
|
||||
|
@ -247,10 +248,10 @@ public:
|
|||
bool PartNameVisible = true;
|
||||
GATE_ID GateID; ///< The gate this symbol represents within the associated Part
|
||||
|
||||
bool IsSymbolVariant = false;
|
||||
SYMBOLVARIANT SymbolVariant;
|
||||
bool IsSymbolVariant = false;
|
||||
SYMBOLVARIANT SymbolVariant;
|
||||
SIGNALREFERENCELINK SigRefLink; ///< Signal References (a special form of global signal)
|
||||
///< have annotations showing the location of all the
|
||||
///< have annotations showing the location of all the
|
||||
///< other sheets where the signal is present
|
||||
|
||||
SYMBOL_ID VariantParentSymbolID = wxEmptyString;
|
||||
|
@ -263,13 +264,13 @@ public:
|
|||
void Parse( XNODE* aNode );
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Net name or bus name label
|
||||
*/
|
||||
struct SIGLOC : CADSTAR_ARCHIVE_PARSER::ATTRIBUTE_LOCATION
|
||||
{
|
||||
void Parse( XNODE* aNode );
|
||||
void Parse( XNODE* aNode ) override;
|
||||
};
|
||||
|
||||
|
||||
|
@ -291,17 +292,17 @@ public:
|
|||
{
|
||||
enum class TYPE
|
||||
{
|
||||
CLONE,
|
||||
CLONE, ///< the block is referring to the sheet it is on.
|
||||
PARENT,
|
||||
CHILD
|
||||
};
|
||||
|
||||
BLOCK_ID ID;
|
||||
TYPE Type;
|
||||
LAYER_ID LayerID = wxEmptyString; ///< The sheet block is on (TODO: verify this is true)
|
||||
LAYER_ID AssocLayerID = wxEmptyString; ///< Parent or Child linked sheet
|
||||
wxString Name = wxEmptyString;
|
||||
bool HasBlockLabel = false;
|
||||
BLOCK_ID ID;
|
||||
TYPE Type; ///< Determines what the associated layer is, whether parent, child or clone
|
||||
LAYER_ID LayerID = wxEmptyString; ///< The sheet block is on (TODO: verify this is true)
|
||||
LAYER_ID AssocLayerID = wxEmptyString; ///< Parent or Child linked sheet
|
||||
wxString Name = wxEmptyString;
|
||||
bool HasBlockLabel = false;
|
||||
ATTRIBUTE_LOCATION BlockLabel;
|
||||
|
||||
std::map<TERMINAL_ID, TERMINAL> Terminals;
|
||||
|
@ -364,7 +365,7 @@ public:
|
|||
std::map<NETELEMENT_ID, BLOCK_TERM> BlockTerminals;
|
||||
std::vector<CONNECTION_SCH> Connections;
|
||||
|
||||
void Parse( XNODE* aNode );
|
||||
void Parse( XNODE* aNode ) override;
|
||||
};
|
||||
|
||||
|
||||
|
@ -394,7 +395,7 @@ public:
|
|||
SHEETS Sheets;
|
||||
SCHEMATIC Schematic;
|
||||
|
||||
int KiCadUnitMultiplier; ///<Use this value to convert units in this CSA file to KiCad units
|
||||
double KiCadUnitMultiplier; ///<Use this value to convert units in this CSA file to KiCad units
|
||||
|
||||
}; //CADSTAR_SCH_ARCHIVE_PARSER
|
||||
|
||||
|
|
|
@ -65,9 +65,6 @@ SCH_SHEET* CADSTAR_SCH_ARCHIVE_PLUGIN::Load( const wxString& aFileName, SCHEMATI
|
|||
mProperties = aProperties;
|
||||
mSchematic = aSchematic;
|
||||
|
||||
// Delete on exception, if I own m_rootSheet, according to aAppendToMe
|
||||
std::unique_ptr<SCH_SHEET> deleter( aAppendToMe ? nullptr : mRootSheet );
|
||||
|
||||
if( aAppendToMe )
|
||||
{
|
||||
wxCHECK_MSG( aSchematic->IsValid(), nullptr, "Can't append to a schematic with no root!" );
|
||||
|
@ -87,10 +84,8 @@ SCH_SHEET* CADSTAR_SCH_ARCHIVE_PLUGIN::Load( const wxString& aFileName, SCHEMATI
|
|||
}
|
||||
|
||||
|
||||
//TEMP TESTING CODE - REMOVE
|
||||
CADSTAR_SCH_ARCHIVE_PARSER parser( aFileName );
|
||||
parser.Parse();
|
||||
//TEMP TESTING CODE - REMOVE
|
||||
CADSTAR_SCH_ARCHIVE_LOADER csaFile( aFileName );
|
||||
csaFile.Load( mSchematic, mRootSheet );
|
||||
|
||||
return mRootSheet;
|
||||
}
|
||||
|
@ -98,6 +93,7 @@ SCH_SHEET* CADSTAR_SCH_ARCHIVE_PLUGIN::Load( const wxString& aFileName, SCHEMATI
|
|||
|
||||
bool CADSTAR_SCH_ARCHIVE_PLUGIN::CheckHeader( const wxString& aFileName )
|
||||
{
|
||||
//TODO
|
||||
// TODO: write a parser for the cpa header. For now assume it is valid
|
||||
// and throw exceptions when parsing
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -36,9 +36,8 @@ class SCH_SCREEN;
|
|||
class CADSTAR_SCH_ARCHIVE_PLUGIN : public SCH_PLUGIN
|
||||
{
|
||||
public:
|
||||
|
||||
//-----<PUBLIC SCH_PLUGIN API>-------------------------------------------------
|
||||
|
||||
|
||||
const wxString GetName() const override;
|
||||
|
||||
const wxString GetFileExtension() const override;
|
||||
|
|
|
@ -115,13 +115,13 @@ void CADSTAR_PCB_ARCHIVE_LOADER::logBoardStackupWarning(
|
|||
|
||||
void CADSTAR_PCB_ARCHIVE_LOADER::loadBoardStackup()
|
||||
{
|
||||
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;
|
||||
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;
|
||||
int lastElectricalLayerIndex = 0;
|
||||
int dielectricSublayer = 0;
|
||||
int numDielectricLayers = 0;
|
||||
|
@ -164,8 +164,8 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadBoardStackup()
|
|||
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 ) );
|
||||
THROW_IO_ERROR( wxString::Format(
|
||||
_( "Unexpected layer '%s' in layer stack." ), curLayer.Name ) );
|
||||
|
||||
case LAYER_TYPE::JUMPERLAYER:
|
||||
copperType = LAYER_T::LT_JUMPER;
|
||||
|
@ -435,9 +435,10 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadDesignRules()
|
|||
|
||||
applyNetClassRule( "T_T", ds.GetDefault(), &::NETCLASS::SetClearance );
|
||||
|
||||
wxLogWarning( _( "KiCad design rules are different from CADSTAR ones. Only the compatible "
|
||||
"design rules were imported. It is recommended that you review the design "
|
||||
"rules that have been applied." ) );
|
||||
wxLogWarning(
|
||||
_( "KiCad design rules are different from CADSTAR ones. Only the compatible "
|
||||
"design rules were imported. It is recommended that you review the design "
|
||||
"rules that have been applied." ) );
|
||||
wxLogWarning(
|
||||
_( "KiCad design rules are different from CADSTAR ones. Only the compatible "
|
||||
"design rules were imported. It is recommended that you review the design "
|
||||
|
@ -686,13 +687,13 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadLibraryPads( const SYMDEF_PCB& aComponent,
|
|||
if( csPadcode.SlotLength != UNDEFINED_VALUE )
|
||||
{
|
||||
pad->SetDrillSize( { getKiCadLength( csPadcode.DrillDiameter ),
|
||||
getKiCadLength( (long long) csPadcode.DrillOversize
|
||||
+ (long long) csPadcode.DrillDiameter ) } );
|
||||
getKiCadLength( (long long) csPadcode.DrillOversize
|
||||
+ (long long) csPadcode.DrillDiameter ) } );
|
||||
}
|
||||
else
|
||||
{
|
||||
pad->SetDrillSize( { getKiCadLength( csPadcode.DrillDiameter ),
|
||||
getKiCadLength( csPadcode.DrillDiameter ) } );
|
||||
getKiCadLength( csPadcode.DrillDiameter ) } );
|
||||
}
|
||||
}
|
||||
//TODO handle csPadcode.Reassigns when KiCad supports full padstacks
|
||||
|
@ -1105,7 +1106,7 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadTemplates()
|
|||
{
|
||||
zone->SetThermalReliefGap( getKiCadLength( csTemplate.Pouring.ClearanceWidth ) );
|
||||
zone->SetThermalReliefSpokeWidth( getKiCadLength(
|
||||
getCopperCode( csTemplate.Pouring.ReliefCopperCodeID ).CopperWidth ));
|
||||
getCopperCode( csTemplate.Pouring.ReliefCopperCodeID ).CopperWidth ) );
|
||||
zone->SetPadConnection( ZONE_CONNECTION::THERMAL );
|
||||
}
|
||||
else
|
||||
|
|
|
@ -52,7 +52,7 @@ void CADSTAR_PCB_ARCHIVE_PARSER::Parse()
|
|||
wxASSERT_MSG( true, wxT( "Unknown File Resolution" ) );
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if( Header.Format.Type != wxT( "LAYOUT" ) )
|
||||
if( Header.Format.Type == wxT( "LIBRARY" ) )
|
||||
THROW_IO_ERROR(
|
||||
|
@ -62,7 +62,6 @@ void CADSTAR_PCB_ARCHIVE_PARSER::Parse()
|
|||
THROW_IO_ERROR(
|
||||
"The selected file is an unknown CADSTAR format so cannot be "
|
||||
"imported into KiCad." );
|
||||
|
||||
}
|
||||
else if( cNode->GetName() == wxT( "ASSIGNMENTS" ) )
|
||||
{
|
||||
|
@ -911,7 +910,6 @@ void CADSTAR_PCB_ARCHIVE_PARSER::TECHNOLOGY_SECTION::Parse( XNODE* aNode )
|
|||
if( ParseSubNode( cNode ) ) //CADSTAR_ARCHIVE_PARSER::SETTINGS
|
||||
{
|
||||
}
|
||||
}
|
||||
else if( cNodeName == wxT( "MINROUTEWIDTH" ) )
|
||||
{
|
||||
MinRouteWidth = GetXmlAttributeIDLong( cNode, 0 );
|
||||
|
@ -943,6 +941,7 @@ void CADSTAR_PCB_ARCHIVE_PARSER::TECHNOLOGY_SECTION::Parse( XNODE* aNode )
|
|||
else if( cNodeName == wxT( "VIAGRID" ) )
|
||||
{
|
||||
ViaGrid = GetXmlAttributeIDLong( cNode, 0 );
|
||||
}
|
||||
else if( cNodeName == wxT( "BACKOFFJCTS" ) )
|
||||
{
|
||||
BackOffJunctions = true;
|
||||
|
|
|
@ -898,10 +898,10 @@ public:
|
|||
GROUP_ID GroupID = wxEmptyString; ///< If not empty, this component is part of a group
|
||||
REUSEBLOCKREF ReuseBlockRef;
|
||||
COMPONENT_ID VariantParentComponentID = wxEmptyString;
|
||||
VARIANT_ID VariantID = wxEmptyString;
|
||||
long OrientAngle = 0;
|
||||
bool TestPoint = false; ///< Indicates whether this component should be treated
|
||||
///< as a testpoint. See SYMDEF_TYPE::TESTPOINT
|
||||
VARIANT_ID VariantID = wxEmptyString;
|
||||
long OrientAngle = 0;
|
||||
bool TestPoint = false; ///< Indicates whether this component should be treated
|
||||
///< as a testpoint. See SYMDEF_TYPE::TESTPOINT
|
||||
bool Mirror = false;
|
||||
bool Fixed = false;
|
||||
READABILITY Readability = READABILITY::BOTTOM_TO_TOP;
|
||||
|
@ -1098,9 +1098,9 @@ public:
|
|||
void Parse( XNODE* aNode );
|
||||
};
|
||||
|
||||
NET_ID NetID = wxEmptyString;
|
||||
NET_ID NetID = wxEmptyString;
|
||||
std::map<COPPER_TERM_ID, COPPER_TERM> CopperTerminals;
|
||||
bool Fixed = false;
|
||||
bool Fixed = false;
|
||||
|
||||
void Parse( XNODE* aNode );
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue