CADSTAR Schematic Archive Importer: Load Busses and fix minor import bugs

Fixed missing tokens that weren't parsed before:
- Danglers (in NET_SCH)
- Pin numbers (in SYMBOL)
- HidePinNames in both PART and PART::DEFINITION, defaulting it to false
This commit is contained in:
Roberto Fernandez Bautista 2020-09-26 14:27:03 +01:00
parent 2d85fc8c91
commit 40c5795c03
6 changed files with 262 additions and 26 deletions

View File

@ -1516,7 +1516,13 @@ void CADSTAR_ARCHIVE_PARSER::PART::Parse( XNODE* aNode )
wxString cNodeName = cNode->GetName();
if( cNodeName == wxT( "VERSION" ) )
{
Version = GetXmlAttributeIDLong( cNode, 0 );
}
else if( cNodeName == wxT( "HIDEPINNAMES" ) )
{
HidePinNames = true;
}
else if( cNodeName == wxT( "PARTDEFINITION" ) )
{
Definition.Parse( cNode );

View File

@ -944,11 +944,12 @@ public:
void Parse( XNODE* aNode );
};
wxString Name; ///< This name can be different to the PART name
bool HidePinNames; ///< Specifies whether to display the pin names/indentifier in
///< the schematic symbol or not. E.g. it is useful to display
///< pin name information for integrated circuits but less so
///< for resistors and capacitors. (subnode HIDEPINNAMES)
wxString Name; ///< This name can be different to the PART name
bool HidePinNames =
false; ///< Specifies whether to display the pin names/indentifier in
///< the schematic symbol or not. E.g. it is useful to display
///< pin name information for integrated circuits but less so
///< for resistors and capacitors. (subnode HIDEPINNAMES)
long MaxPinCount =
UNDEFINED_VALUE; ///< Optional parameter which is used for specifying the number
@ -992,6 +993,8 @@ public:
///< Therefore, PART_PIN is only included for
///< completeness of the parser, but won't be used
bool HidePinNames = false; ///< This seems to be a dupplicate of DEFINITION::HidePinNames
///< Possibly only used in older file formats?
std::map<ATTRIBUTE_ID, ATTRIBUTE_VALUE> AttributeValues; ///< Some attributes are defined
///< within the part definition,

View File

@ -29,6 +29,7 @@
#include <lib_arc.h>
#include <lib_polyline.h>
#include <lib_text.h>
#include <sch_bus_entry.h>
#include <sch_edit_frame.h> //COMPONENT_ORIENTATION_T
#include <sch_io_mgr.h>
#include <sch_junction.h>
@ -81,6 +82,7 @@ void CADSTAR_SCH_ARCHIVE_LOADER::Load( ::SCHEMATIC* aSchematic, ::SCH_SHEET* aRo
loadHierarchicalSheetPins();
loadPartsLibrary();
loadSchematicSymbolInstances();
loadBusses();
loadNets();
// TODO Load other elements!
@ -416,12 +418,48 @@ void CADSTAR_SCH_ARCHIVE_LOADER::loadSchematicSymbolInstances()
}
void CADSTAR_SCH_ARCHIVE_LOADER::loadBusses()
{
for( std::pair<BUS_ID, BUS> busPair : Schematic.Buses )
{
BUS bus = busPair.second;
bool firstPt = true;
VERTEX last;
for( const VERTEX& cur : bus.Shape.Vertices )
{
if( firstPt )
{
last = cur;
firstPt = false;
continue;
}
if( bus.LayerID != wxT( "NO_SHEET" ) )
{
SCH_LINE* kiBus = new SCH_LINE();
kiBus->SetStartPoint( getKiCadPoint( last.End ) );
kiBus->SetEndPoint( getKiCadPoint( cur.End ) );
kiBus->SetLayer( LAYER_BUS );
kiBus->SetLineWidth( getLineThickness( bus.LineCodeID ) );
last = cur;
mSheetMap.at( bus.LayerID )->GetScreen()->Append( kiBus );
}
}
}
}
void CADSTAR_SCH_ARCHIVE_LOADER::loadNets()
{
for( std::pair<NET_ID, NET_SCH> netPair : Schematic.Nets )
{
NET_SCH net = netPair.second;
wxString netName = net.Name;
NET_SCH net = netPair.second;
wxString netName = net.Name;
std::map<NETELEMENT_ID, SCH_LABEL*> netlabels;
if( netName.IsEmpty() )
netName = wxString::Format( "$%d", net.SignalNum );
@ -452,7 +490,7 @@ void CADSTAR_SCH_ARCHIVE_LOADER::loadNets()
}
}
//Add net name to all hierarchical pins (block terminals in CADSTAR)
for( std::pair<NETELEMENT_ID, NET_SCH::BLOCK_TERM> blockPair : net.BlockTerminals )
{
NET_SCH::BLOCK_TERM blockTerm = blockPair.second;
@ -462,6 +500,50 @@ void CADSTAR_SCH_ARCHIVE_LOADER::loadNets()
mSheetPinMap.at( blockPinID )->SetText( netName );
}
// Load all bus entries and add net label if required
for( std::pair<NETELEMENT_ID, NET_SCH::BUS_TERM> busPair : net.BusTerminals )
{
NET_SCH::BUS_TERM busTerm = busPair.second;
BUS bus = Schematic.Buses.at( busTerm.BusID );
SCH_BUS_WIRE_ENTRY* busEntry =
new SCH_BUS_WIRE_ENTRY( getKiCadPoint( busTerm.FirstPoint ), false );
wxPoint size =
getKiCadPoint( busTerm.SecondPoint ) - getKiCadPoint( busTerm.FirstPoint );
busEntry->SetSize( wxSize( size.x, size.y ) );
mSheetMap.at( bus.LayerID )->GetScreen()->Append( busEntry );
if( busTerm.HasNetLabel )
{
SCH_LABEL* label = new SCH_LABEL();
applyTextSettings( busTerm.NetLabel.TextCodeID, busTerm.NetLabel.Alignment,
busTerm.NetLabel.Justification, label );
label->SetText( netName );
label->SetPosition( getKiCadPoint( busTerm.SecondPoint ) );
label->SetVisible( true );
netlabels.insert( { busTerm.ID, label } );
mSheetMap.at( bus.LayerID )->GetScreen()->Append( label );
}
}
for( std::pair<NETELEMENT_ID, NET_SCH::DANGLER> danglerPair : net.Danglers )
{
NET_SCH::DANGLER dangler = danglerPair.second;
SCH_LABEL* label = new SCH_LABEL();
label->SetText( netName );
label->SetPosition( getKiCadPoint( dangler.Position ) );
label->SetVisible( true );
netlabels.insert( { dangler.ID, label } );
mSheetMap.at( dangler.LayerID )->GetScreen()->Append( label );
}
for( NET_SCH::CONNECTION_SCH conn : net.Connections )
{
@ -479,31 +561,61 @@ void CADSTAR_SCH_ARCHIVE_LOADER::loadNets()
conn.Path.push_back( end );
}
bool firstPt = true;
POINT last;
bool firstPt = true;
bool secondPt = false;
POINT last;
SCH_LINE* wire = nullptr;
for( POINT pt : conn.Path )
{
if( firstPt )
{
last = pt;
firstPt = false;
last = pt;
firstPt = false;
secondPt = true;
continue;
}
if( secondPt )
{
secondPt = false;
if( netlabels.find( conn.StartNode ) != netlabels.end() )
{
wxPoint kiLast = getKiCadPoint( last );
wxPoint kiCurrent = getKiCadPoint( pt );
double wireangleDeciDeg = getPolarAngle( kiCurrent - kiLast );
LABEL_SPIN_STYLE spin = getSpinStyleDeciDeg( wireangleDeciDeg );
netlabels.at( conn.StartNode )->SetLabelSpinStyle( spin );
}
}
if( conn.LayerID != wxT( "NO_SHEET" ) )
{
SCH_LINE* wire = new SCH_LINE();
wire = new SCH_LINE();
wire->SetStartPoint( getKiCadPoint( last ) );
wire->SetEndPoint( getKiCadPoint( pt ) );
wire->SetLayer( LAYER_WIRE );
if( !conn.ConnectionLineCode.IsEmpty() )
wire->SetLineWidth( getLineThickness( conn.ConnectionLineCode ) );
last = pt;
mSheetMap.at( conn.LayerID )->GetScreen()->Append( wire );
}
}
if( wire && netlabels.find( conn.EndNode ) != netlabels.end() )
{
wxPoint kiLast = wire->GetEndPoint();
wxPoint kiCurrent = wire->GetStartPoint();
double wireangleDeciDeg = getPolarAngle( kiCurrent - kiLast );
LABEL_SPIN_STYLE spin = getSpinStyleDeciDeg( wireangleDeciDeg );
netlabels.at( conn.EndNode )->SetLabelSpinStyle( spin );
}
}
@ -571,10 +683,7 @@ void CADSTAR_SCH_ARCHIVE_LOADER::loadSymDefIntoLibrary( const SYMDEF_ID& aSymdef
pin->SetUnit( gateNumber );
pin->SetNumber( pinNum );
if( !aCadstarPart )
pin->SetName( pinName );
else if( !aCadstarPart->Definition.HidePinNames )
pin->SetName( pinName );
pin->SetName( pinName );
int oDeg = (int) NormalizeAngle180( getAngleTenthDegree( term.OrientAngle ) );
@ -638,6 +747,12 @@ void CADSTAR_SCH_ARCHIVE_LOADER::loadSymDefIntoLibrary( const SYMDEF_ID& aSymdef
field->SetUnit( gateNumber );
}
if( aCadstarPart && aCadstarPart->Definition.HidePinNames )
{
aPart->SetShowPinNames( false );
aPart->SetShowPinNumbers( false );
}
}
@ -905,6 +1020,13 @@ CADSTAR_SCH_ARCHIVE_LOADER::POINT CADSTAR_SCH_ARCHIVE_LOADER::getLocationOfNetEl
return Schematic.Blocks.at( blockid ).Terminals.at( termid ).Position;
}
else if( aNetElementID.Contains( "D" ) ) // Dangler
{
if( aNet.Danglers.find( aNetElementID ) == aNet.Danglers.end() )
return logUnknownNetElementError();
return aNet.Danglers.at( aNetElementID ).Position;
}
else
{
return logUnknownNetElementError();
@ -1180,9 +1302,26 @@ int CADSTAR_SCH_ARCHIVE_LOADER::getKiCadUnitNumberFromGate( const GATE_ID& aCads
LABEL_SPIN_STYLE CADSTAR_SCH_ARCHIVE_LOADER::getSpinStyle(
const long long& aCadstarOrientation, bool aMirror )
{
double orientationDeciDegree = getAngleTenthDegree( aCadstarOrientation );
LABEL_SPIN_STYLE spinStyle = getSpinStyleDeciDeg( orientationDeciDegree );
if( aMirror )
{
spinStyle = spinStyle.RotateCCW();
spinStyle = spinStyle.RotateCCW();
}
return spinStyle;
}
LABEL_SPIN_STYLE CADSTAR_SCH_ARCHIVE_LOADER::getSpinStyleDeciDeg(
const double& aOrientationDeciDeg )
{
LABEL_SPIN_STYLE spinStyle = LABEL_SPIN_STYLE::LEFT;
int oDeg = (int) NormalizeAngle180( getAngleTenthDegree( aCadstarOrientation ) );
int oDeg = (int) NormalizeAngle180( aOrientationDeciDeg );
if( oDeg >= -450 && oDeg <= 450 )
spinStyle = LABEL_SPIN_STYLE::RIGHT; // 0deg
@ -1193,13 +1332,6 @@ LABEL_SPIN_STYLE CADSTAR_SCH_ARCHIVE_LOADER::getSpinStyle(
else
spinStyle = LABEL_SPIN_STYLE::UP; // 270deg
if( aMirror )
{
spinStyle = spinStyle.RotateCCW();
spinStyle = spinStyle.RotateCCW();
}
return spinStyle;
}

View File

@ -95,6 +95,7 @@ private:
void loadHierarchicalSheetPins();
void loadPartsLibrary();
void loadSchematicSymbolInstances();
void loadBusses();
void loadNets();
//Helper Functions for loading sheets
@ -140,6 +141,7 @@ private:
// Helper Functions for obtaining individual elements as KiCad elements:
int getKiCadUnitNumberFromGate( const GATE_ID& aCadstarGateID );
LABEL_SPIN_STYLE getSpinStyle( const long long& aCadstarOrientation, bool aMirror );
LABEL_SPIN_STYLE getSpinStyleDeciDeg( const double& aOrientationDeciDeg );
void applyTextSettings( const TEXTCODE_ID& aCadstarTextCodeID,
const ALIGNMENT& aCadstarAlignment, const JUSTIFICATION& aCadstarJustification,

View File

@ -477,6 +477,28 @@ void CADSTAR_SCH_ARCHIVE_PARSER::SYMPINNAME_LABEL::Parse( XNODE* aNode )
}
void CADSTAR_SCH_ARCHIVE_PARSER::SYMBOL::PIN_NUM::Parse( XNODE* aNode )
{
wxCHECK( aNode->GetName() == wxT( "PINNUM" ), );
TerminalID = GetXmlAttributeIDLong( aNode, 0 );
PinNum = GetXmlAttributeIDLong( aNode, 1 );
XNODE* cNode = aNode->GetChildren();
for( ; cNode; cNode = cNode->GetNext() )
{
if( cNode->GetName() == wxT( "ATTRLOC" ) )
{
AttrLoc.Parse( cNode );
HasLocation = true;
}
else
THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), wxT( "ATTR" ) );
}
}
void CADSTAR_SCH_ARCHIVE_PARSER::SYMBOLVARIANT::Parse( XNODE* aNode )
{
wxCHECK( aNode->GetName() == wxT( "SYMBOLVARIANT" ), );
@ -603,6 +625,12 @@ void CADSTAR_SCH_ARCHIVE_PARSER::SYMBOL::Parse( XNODE* aNode )
sympinname.Parse( cNode );
PinNames.insert( std::make_pair( sympinname.TerminalID, sympinname ) );
}
else if( cNodeName == wxT( "PINNUM" ) )
{
PIN_NUM pinNum;
pinNum.Parse( cNode );
PinNumbers.insert( std::make_pair( pinNum.TerminalID, pinNum ) );
}
else if( cNodeName == wxT( "ATTR" ) )
{
ATTRIBUTE_VALUE attrVal;
@ -799,7 +827,7 @@ void CADSTAR_SCH_ARCHIVE_PARSER::NET_SCH::BUS_TERM::Parse( XNODE* aNode )
}
else if( !secondPointParsed )
{
FirstPoint.Parse( cNode );
SecondPoint.Parse( cNode );
secondPointParsed = true;
}
else
@ -909,6 +937,12 @@ void CADSTAR_SCH_ARCHIVE_PARSER::NET_SCH::Parse( XNODE* aNode )
bt.Parse( cNode );
BlockTerminals.insert( std::make_pair( bt.ID, bt ) );
}
else if( cNodeName == wxT( "DANGLER" ) )
{
DANGLER dang;
dang.Parse( cNode );
Danglers.insert( std::make_pair( dang.ID, dang ) );
}
else if( cNodeName == wxT( "CONN" ) )
{
CONNECTION_SCH conn;
@ -998,6 +1032,7 @@ void CADSTAR_SCH_ARCHIVE_PARSER::SCHEMATIC::Parse( XNODE* aNode )
}
}
void CADSTAR_SCH_ARCHIVE_PARSER::NET_SCH::JUNCTION_SCH::Parse( XNODE* aNode )
{
CADSTAR_ARCHIVE_PARSER::NET::JUNCTION::Parse( aNode );
@ -1005,3 +1040,36 @@ void CADSTAR_SCH_ARCHIVE_PARSER::NET_SCH::JUNCTION_SCH::Parse( XNODE* aNode )
TerminalCodeID = GetXmlAttributeIDString( aNode, 1 );
LayerID = GetXmlAttributeIDString( aNode, 2 );
}
void CADSTAR_SCH_ARCHIVE_PARSER::NET_SCH::DANGLER::Parse( XNODE* aNode )
{
wxASSERT( aNode->GetName() == wxT( "DANGLER" ) );
ID = GetXmlAttributeIDString( aNode, 0 );
TerminalCodeID = GetXmlAttributeIDString( aNode, 1 );
LayerID = GetXmlAttributeIDString( aNode, 2 );
XNODE* cNode = aNode->GetChildren();
bool positionParsed = false;
for( ; cNode; cNode = cNode->GetNext() )
{
wxString cNodeName = cNode->GetName();
if( cNodeName == wxT( "SIGLOC" ) )
{
NetLabel.Parse( cNode );
HasNetLabel = true;
}
else if( !positionParsed && cNodeName == wxT( "PT" ) )
{
Position.Parse( cNode );
positionParsed = true;
}
else
{
THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
}
}
}

View File

@ -230,6 +230,16 @@ public:
struct SYMBOL
{
struct PIN_NUM
{
TERMINAL_ID TerminalID;
long PinNum;
bool HasLocation = false;
ATTRIBUTE_LOCATION AttrLoc;
void Parse( XNODE* aNode );
};
SYMBOL_ID ID;
SYMDEF_ID SymdefID;
LAYER_ID LayerID; ///< Sheet on which symbol is located
@ -259,6 +269,7 @@ public:
std::map<TERMINAL_ID, SYMPINNAME_LABEL> PinLabels;
std::map<TERMINAL_ID, SYMPINNAME_LABEL> PinNames;
std::map<TERMINAL_ID, PIN_NUM> PinNumbers;
std::map<ATTRIBUTE_ID, ATTRIBUTE_VALUE> AttributeValues;
void Parse( XNODE* aNode );
@ -355,6 +366,19 @@ public:
void Parse( XNODE* aNode );
};
struct DANGLER ///< "DANGLER" nodename (represents a dangling wire)
{
NETELEMENT_ID ID; ///< First character "D"
TERMINALCODE_ID TerminalCodeID;
LAYER_ID LayerID;
POINT Position;
bool HasNetLabel = false;
SIGLOC NetLabel;
void Parse( XNODE* aNode );
};
struct CONNECTION_SCH : CADSTAR_ARCHIVE_PARSER::NET::CONNECTION ///< "CONN" nodename
{
LAYER_ID LayerID; ///< Sheet on which the connection is drawn
@ -370,6 +394,7 @@ public:
std::map<NETELEMENT_ID, SYM_TERM> Terminals;
std::map<NETELEMENT_ID, BUS_TERM> BusTerminals;
std::map<NETELEMENT_ID, BLOCK_TERM> BlockTerminals;
std::map<NETELEMENT_ID, DANGLER> Danglers;
std::vector<CONNECTION_SCH> Connections;
void Parse( XNODE* aNode ) override;