31#include <wx/translation.h>
45 std::vector<wxString> subNodeChildrenToCount = { wxT(
"LIBRARY" ), wxT(
"PARTS" ),
59 for( ; cNode; cNode = cNode->
GetNext() )
61 if( cNode->GetName() == wxT(
"HEADER" ) )
65 switch(
Header.Resolution )
72 wxASSERT_MSG(
true, wxT(
"Unknown File Resolution" ) );
76 if( aLibrary &&
Header.Format.Type != wxT(
"LIBRARY" ) )
78 THROW_IO_ERROR( wxT(
"The selected file is not a valid CADSTAR library file." ) );
80 else if( !aLibrary &&
Header.Format.Type != wxT(
"LAYOUT" ) )
82 if(
Header.Format.Type == wxT(
"LIBRARY" ) )
84 THROW_IO_ERROR( wxT(
"The selected file is a CADSTAR library file (as opposed to a layout file). "
85 "You can import this library by adding it to the library table." ) );
89 THROW_IO_ERROR( wxT(
"The selected file is an unknown CADSTAR format so cannot be imported into "
94 else if( cNode->GetName() == wxT(
"ASSIGNMENTS" ) )
98 else if( cNode->GetName() == wxT(
"LIBRARY" ) )
102 else if( cNode->GetName() == wxT(
"DEFAULTS" ) )
108 else if( cNode->GetName() == wxT(
"PARTS" ) )
112 else if( cNode->GetName() == wxT(
"LAYOUT" ) )
116 else if( cNode->GetName() == wxT(
"DISPLAY" ) )
137 wxASSERT( aNode->GetName() == wxT(
"ASSIGNMENTS" ) );
144 for( ; cNode; cNode = cNode->
GetNext() )
146 if( cNode->GetName() == wxT(
"LAYERDEFS" ) )
148 else if( cNode->GetName() == wxT(
"CODEDEFS" ) )
150 else if( cNode->GetName() == wxT(
"TECHNOLOGY" ) )
152 else if( cNode->GetName() == wxT(
"GRIDS" ) )
153 Grids.Parse( cNode, aContext );
154 else if( cNode->GetName() == wxT(
"NETCLASSEDITATTRIBSETTINGS" ) )
156 else if( cNode->GetName() == wxT(
"SPCCLASSEDITATTRIBSETTINGS" ) )
166 wxASSERT( aNode->GetName() == wxT(
"LAYERDEFS" ) );
168 wxXmlAttribute* xmlAttribute =
nullptr;
175 for( ; cNode; cNode = cNode->
GetNext() )
177 wxString
nodeName = cNode->GetName();
179 if(
nodeName == wxT(
"LAYERSTACK" ) )
181 xmlAttribute = cNode->GetAttributes();
183 for( ; xmlAttribute; xmlAttribute = xmlAttribute->GetNext() )
193 else if(
nodeName == wxT(
"MATERIAL" ) )
196 material.
Parse( cNode, aContext );
197 Materials.insert( std::make_pair( material.
ID, material ) );
199 else if(
nodeName == wxT(
"LAYER" ) )
202 layer.
Parse( cNode, aContext );
203 Layers.insert( std::make_pair( layer.
ID, layer ) );
205 else if(
nodeName == wxT(
"SWAPPAIR" ) )
210 Layers[layerId].SwapLayerID = swapLayerId;
222 wxASSERT( aNode->GetName() == wxT(
"RULESET" ) );
229 for( ; cNode; cNode = cNode->
GetNext() )
231 wxString
nodeName = cNode->GetName();
233 if(
nodeName == wxT(
"ROUCODEREF" ) )
237 else if(
nodeName == wxT(
"VIACODEREF" ) )
241 else if(
nodeName == wxT(
"SPACINGCODE" ) )
244 spacingcode.
Parse( cNode, aContext );
245 SpacingCodes.insert( std::make_pair( spacingcode.
ID, spacingcode ) );
257 wxASSERT( aNode->GetName() == wxT(
"CODEDEFS" ) );
261 for( ; cNode; cNode = cNode->
GetNext() )
263 wxString
nodeName = cNode->GetName();
268 else if(
nodeName == wxT(
"COPPERCODE" ) )
271 coppercode.
Parse( cNode, aContext );
272 CopperCodes.insert( std::make_pair( coppercode.
ID, coppercode ) );
274 else if(
nodeName == wxT(
"SPACINGCODE" ) )
277 spacingcode.
Parse( cNode, aContext );
278 SpacingCodes.insert( std::make_pair( spacingcode.
ID, spacingcode ) );
280 else if(
nodeName == wxT(
"RULESET" ) )
283 ruleset.
Parse( cNode, aContext );
284 Rulesets.insert( std::make_pair( ruleset.
ID, ruleset ) );
286 else if(
nodeName == wxT(
"PADCODE" ) )
289 padcode.
Parse( cNode, aContext );
290 PadCodes.insert( std::make_pair( padcode.
ID, padcode ) );
292 else if(
nodeName == wxT(
"VIACODE" ) )
295 viacode.
Parse( cNode, aContext );
296 ViaCodes.insert( std::make_pair( viacode.
ID, viacode ) );
298 else if(
nodeName == wxT(
"LAYERPAIR" ) )
301 layerpair.
Parse( cNode, aContext );
302 LayerPairs.insert( std::make_pair( layerpair.
ID, layerpair ) );
304 else if(
nodeName == wxT(
"SPCCLASSSPACE" ) )
307 spcclassspace.
Parse( cNode, aContext );
320 wxASSERT( aNode->GetName() == wxT(
"MATERIAL" ) );
327 if( sType == wxT(
"CONSTRUCTION" ) )
331 else if( sType == wxT(
"ELECTRICAL" ) )
335 else if( sType == wxT(
"NONELEC" ) )
349 wxString::Format( wxT(
"MATERIAL %s" ),
Name ) );
352 for( ; iNode; iNode = iNode->
GetNext() )
354 wxString
nodeName = iNode->GetName();
356 if(
nodeName == wxT(
"RELPERMIT" ) )
360 else if(
nodeName == wxT(
"LOSSTANGENT" ) )
364 else if(
nodeName == wxT(
"RESISTIVITY" ) )
378 wxASSERT( aNode->GetName() == wxT(
"LAYER" ) );
384 auto processLayerMaterialDetails = [&]() {
386 for( ; tempNode; tempNode = tempNode->
GetNext() )
388 wxString tempNodeName = tempNode->GetName();
390 if( tempNodeName == wxT(
"MAKE" ) || tempNodeName == wxT(
"LAYERHEIGHT" ) )
392 if( tempNodeName == wxT(
"LAYERHEIGHT" ) )
404 if( childOfTempNode )
406 if( childOfTempNode->GetName() == wxT(
"EMBEDS" ) )
410 if( embedsValue == wxT(
"UPWARDS" ) )
414 else if( embedsValue == wxT(
"DOWNWARDS" ) )
421 wxString::Format( wxT(
"LAYER %s -> EMBEDS" ),
428 wxString::Format( wxT(
"LAYER %s->MAKE" ),
433 else if( tempNodeName == wxT(
"BIAS" ) )
437 if( bias == wxT(
"X_BIASED" ) )
441 else if( bias == wxT(
"Y_BIASED" ) )
445 else if( bias == wxT(
"ANTITRACK" ) )
449 else if( bias == wxT(
"OBSTACLE" ) )
453 else if( bias == wxT(
"UNBIASED" ) )
460 wxString::Format( wxT(
"LAYER %s -> BIAS" ),
472 for( ; cNode; cNode = cNode->
GetNext() )
474 wxString cNodeName = cNode->GetName();
476 if( cNodeName == wxT(
"ALLDOC" ) )
480 else if( cNodeName == wxT(
"ALLELEC" ) )
484 else if( cNodeName == wxT(
"ALLLAYER" ) )
488 else if( cNodeName == wxT(
"ASSCOMPCOPP" ) )
492 else if( cNodeName == wxT(
"JUMPERLAYER" ) )
496 else if( cNodeName == wxT(
"NOLAYER" ) )
500 else if( cNodeName == wxT(
"POWER" ) )
504 processLayerMaterialDetails();
506 else if( cNodeName == wxT(
"DOC" ) )
510 else if( cNodeName == wxT(
"CONSTRUCTION" ) )
513 processLayerMaterialDetails();
515 else if( cNodeName == wxT(
"ELEC" ) )
519 processLayerMaterialDetails();
521 else if( cNodeName == wxT(
"NONELEC" ) )
525 processLayerMaterialDetails();
527 else if( cNodeName == wxT(
"DESCRIPTION" ) )
531 else if( cNodeName == wxT(
"REFPLANE" ) )
535 else if( cNodeName == wxT(
"VLAYER" ) )
539 else if( cNodeName == wxT(
"LASUBTYP" ) )
544 if( sSubType == wxT(
"LAYERSUBTYPE_ASSEMBLY" ) )
548 else if( sSubType == wxT(
"LAYERSUBTYPE_PASTE" ) )
552 else if( sSubType == wxT(
"LAYERSUBTYPE_PLACEMENT" ) )
556 else if( sSubType == wxT(
"LAYERSUBTYPE_SILKSCREEN" ) )
560 else if( sSubType == wxT(
"LAYERSUBTYPE_SOLDERRESIST" ) )
564 else if( sSubType == wxT(
"LAYERSUBTYPE_CLEARANCE" ) )
568 else if( sSubType == wxT(
"LAYERSUBTYPE_ROUT" ) )
588 wxASSERT( aNode->GetName() == wxT(
"COPREASSIGN" ) );
598 wxASSERT( aNode->GetName() == wxT(
"COPPERCODE" ) );
607 for( ; cNode; cNode = cNode->
GetNext() )
609 if( cNode->GetName() == wxT(
"COPREASSIGN" ) )
612 reassign.
Parse( cNode, aContext );
626 wxASSERT( aNode->GetName() == wxT(
"SPACEREASSIGN" ) );
637 wxASSERT( aNode->GetName() == wxT(
"SPACINGCODE" ) );
644 for( ; cNode; cNode = cNode->
GetNext() )
646 wxString cNodeName = cNode->GetName();
648 if( cNodeName == wxT(
"SPACEREASSIGN" ) )
651 reassign.
Parse( cNode, aContext );
667 wxString aNodeName = aNode->GetName();
669 if( aNodeName == wxT(
"ANNULUS" ) || aNodeName == wxT(
"BULLET" ) || aNodeName == wxT(
"ROUND" )
670 || aNodeName == wxT(
"DIAMOND" ) || aNodeName == wxT(
"FINGER" )
671 || aNodeName == wxT(
"OCTAGON" ) || aNodeName == wxT(
"RECTANGLE" )
672 || aNodeName == wxT(
"ROUNDED" ) || aNodeName == wxT(
"SQUARE" ) )
687 wxString aNodeName = aNode->GetName();
689 if( aNodeName == wxT(
"ANNULUS" ) )
691 else if( aNodeName == wxT(
"BULLET" ) )
693 else if( aNodeName == wxT(
"ROUND" ) )
695 else if( aNodeName == wxT(
"DIAMOND" ) )
697 else if( aNodeName == wxT(
"FINGER" ) )
699 else if( aNodeName == wxT(
"OCTAGON" ) )
701 else if( aNodeName == wxT(
"RECTANGLE" ) )
703 else if( aNodeName == wxT(
"ROUNDED" ) )
705 else if( aNodeName == wxT(
"SQUARE" ) )
733 if( aNode->
GetChildren()->GetName() == wxT(
"ORIENT" ) )
755 wxASSERT( aNode->GetName() == wxT(
"PADREASSIGN" ) );
763 Shape.Parse( shapeNode, aContext );
768 wxString found = shapeNode ? shapeNode->GetName() : wxString(
"(empty)" );
778 wxASSERT( aNode->GetName() == wxT(
"PADCODE" ) );
784 wxString
location = wxString::Format( wxT(
"PADCODE -> %s" ),
Name );
786 for( ; cNode; cNode = cNode->
GetNext() )
788 wxString cNodeName = cNode->GetName();
792 Shape.Parse( cNode, aContext );
794 else if( cNodeName == wxT(
"CLEARANCE" ) )
798 else if( cNodeName == wxT(
"RELIEFWIDTH" ) )
802 else if( cNodeName == wxT(
"DRILL" ) )
807 for( ; subNode; subNode = subNode->
GetNext() )
809 wxString subNodeName = subNode->GetName();
811 if( subNodeName == wxT(
"NONPLATED" ) )
813 else if( subNodeName == wxT(
"OVERSIZE" ) )
819 else if( cNodeName == wxT(
"DRILLLENGTH" ) )
823 else if( cNodeName == wxT(
"DRILLORIENTATION" ) )
827 else if( cNodeName == wxT(
"DRILLXOFFSET" ) )
831 else if( cNodeName == wxT(
"DRILLYOFFSET" ) )
835 else if( cNodeName == wxT(
"PADREASSIGN" ) )
838 reassign.
Parse( cNode, aContext );
853 wxASSERT( aNode->GetName() == wxT(
"VIAREASSIGN" ) );
861 Shape.Parse( shapeNode, aContext );
866 wxString found = shapeNode ? shapeNode->GetName() : wxString(
"(empty)" );
876 wxASSERT( aNode->GetName() == wxT(
"VIACODE" ) );
882 wxString
location = wxString::Format( wxT(
"VIACODE -> %s" ),
Name );
884 for( ; cNode; cNode = cNode->
GetNext() )
886 wxString cNodeName = cNode->GetName();
890 Shape.Parse( cNode, aContext );
892 else if( cNodeName == wxT(
"CLEARANCE" ) )
896 else if( cNodeName == wxT(
"RELIEFWIDTH" ) )
900 else if( cNodeName == wxT(
"DRILL" ) )
905 for( ; subNode; subNode = subNode->
GetNext() )
907 wxString subNodeName = subNode->GetName();
909 if( subNodeName == wxT(
"OVERSIZE" ) )
915 else if( cNodeName == wxT(
"VIAREASSIGN" ) )
918 reassign.
Parse( cNode, aContext );
933 wxASSERT( aNode->GetName() == wxT(
"LAYERPAIR" ) );
941 wxString
location = wxString::Format( wxT(
"LAYERPAIR -> %s" ),
Name );
945 if( aNode->
GetChildren()->GetName() == wxT(
"VIACODEREF" ) )
961 wxASSERT( aNode->GetName() == wxT(
"SPCCLASSSPACE" ) );
972 wxASSERT( aNode->GetName() == wxT(
"TECHNOLOGY" ) );
976 for( ; cNode; cNode = cNode->
GetNext() )
978 wxString cNodeName = cNode->GetName();
983 else if( cNodeName == wxT(
"MINROUTEWIDTH" ) )
987 else if( cNodeName == wxT(
"MINNECKED" ) )
991 else if( cNodeName == wxT(
"MINUNNECKED" ) )
995 else if( cNodeName == wxT(
"MINMITER" ) )
999 else if( cNodeName == wxT(
"MAXMITER" ) )
1003 else if( cNodeName == wxT(
"MAXPHYSLAYER" ) )
1007 else if( cNodeName == wxT(
"TRACKGRID" ) )
1011 else if( cNodeName == wxT(
"VIAGRID" ) )
1015 else if( cNodeName == wxT(
"BACKOFFJCTS" ) )
1019 else if( cNodeName == wxT(
"BCKOFFWIDCHANGE" ) )
1032 const wxString& aPadSideString )
1034 if( aPadSideString == wxT(
"THRU" ) )
1036 else if( aPadSideString == wxT(
"BOTTOM" ) )
1038 else if( aPadSideString == wxT(
"TOP" ) )
1047 wxASSERT( aNode->GetName() == wxT(
"COMPCOPPER" ) );
1053 bool shapeIsInitialised =
false;
1054 wxString
location = wxT(
"COMPCOPPER" );
1059 for( ; cNode; cNode = cNode->
GetNext() )
1061 wxString cNodeName = cNode->GetName();
1063 if( !shapeIsInitialised &&
Shape.IsShape( cNode ) )
1065 Shape.Parse( cNode, aContext );
1066 shapeIsInitialised =
true;
1068 else if( cNodeName == wxT(
"SWAPRULE" ) )
1072 else if( cNodeName == wxT(
"ASSOCPIN" ) )
1074 wxXmlAttribute* xmlAttribute = cNode->GetAttributes();
1076 for( ; xmlAttribute; xmlAttribute = xmlAttribute->GetNext() )
1083 if( !xmlAttribute->GetValue().ToLong( &padId ) )
1101 wxASSERT( aNode->GetName() == wxT(
"COMPAREA" ) );
1108 bool shapeIsInitialised =
false;
1109 wxString
location = wxString::Format( wxT(
"COMPAREA %s" ),
ID );
1114 for( ; cNode; cNode = cNode->
GetNext() )
1116 wxString cNodeName = cNode->GetName();
1118 if( !shapeIsInitialised && SHAPE::IsShape( cNode ) )
1120 Shape.Parse( cNode, aContext );
1121 shapeIsInitialised =
true;
1123 else if( cNodeName == wxT(
"SWAPRULE" ) )
1127 else if( cNodeName == wxT(
"USAGE" ) )
1129 wxXmlAttribute* xmlAttribute = cNode->GetAttributes();
1131 for( ; xmlAttribute; xmlAttribute = xmlAttribute->GetNext() )
1136 if( xmlAttribute->GetValue() == wxT(
"NO_TRACKS" ) )
1138 else if( xmlAttribute->GetValue() == wxT(
"NO_VIAS" ) )
1156 wxASSERT( aNode->GetName() == wxT(
"EXITS" ) );
1158 wxXmlAttribute* xmlAttribute = aNode->GetAttributes();
1160 for( ; xmlAttribute; xmlAttribute = xmlAttribute->GetNext() )
1165 if( xmlAttribute->GetValue() == wxT(
"FREE" ) )
1167 else if( xmlAttribute->GetValue() == wxT(
"N" ) )
1169 else if( xmlAttribute->GetValue() == wxT(
"S" ) )
1171 else if( xmlAttribute->GetValue() == wxT(
"E" ) )
1173 else if( xmlAttribute->GetValue() == wxT(
"W" ) )
1175 else if( xmlAttribute->GetValue() == wxT(
"NE" ) )
1177 else if( xmlAttribute->GetValue() == wxT(
"NW" ) )
1179 else if( xmlAttribute->GetValue() == wxT(
"SE" ) )
1181 else if( xmlAttribute->GetValue() == wxT(
"SW" ) )
1193 wxASSERT( aNode->GetName() == wxT(
"PAD" ) );
1200 wxString
location = wxString::Format( wxT(
"PAD %ld" ),
ID );
1205 for( ; cNode; cNode = cNode->
GetNext() )
1207 wxString cNodeName = cNode->GetName();
1209 if( cNodeName == wxT(
"ORIENT" ) )
1211 else if( cNodeName == wxT(
"FIRSTPAD" ) )
1213 else if( cNodeName == wxT(
"EXITS" ) )
1214 Exits.Parse( cNode, aContext );
1215 else if( cNodeName == wxT(
"PADIDENTIFIER" ) )
1217 else if( cNodeName == wxT(
"PCBONLYPAD" ) )
1219 else if( cNodeName == wxT(
"PT" ) )
1229 wxASSERT( aNode->GetName() == wxT(
"DIMARROW" ) );
1230 bool arrowStyleInitialised =
false;
1231 bool upperAngleInitialised =
false;
1232 bool lowerAngleInitialised =
false;
1239 for( ; cNode; cNode = cNode->
GetNext() )
1241 wxString cNodeName = cNode->GetName();
1243 if( cNodeName == wxT(
"ARROWSTYLE" ) )
1246 arrowStyleInitialised =
true;
1248 if( arrowStyleStr == wxT(
"DIMENSION_ARROWOPEN" ) )
1250 else if( arrowStyleStr == wxT(
"DIMENSION_ARROWCLOSED" ) )
1252 else if( arrowStyleStr == wxT(
"DIMENSION_ARROWCLEAR" ) )
1254 else if( arrowStyleStr == wxT(
"DIMENSION_ARROWCLOSEDFILLED" ) )
1259 else if( cNodeName == wxT(
"ARROWANGLEA" ) )
1262 upperAngleInitialised =
true;
1264 else if( cNodeName == wxT(
"ARROWANGLEB" ) )
1267 lowerAngleInitialised =
true;
1275 if( !arrowStyleInitialised )
1278 if( !upperAngleInitialised )
1281 if( !lowerAngleInitialised )
1289 wxASSERT( aNode->GetName() == wxT(
"DIMTEXT" ) );
1302 if( cNode->GetName() != wxT(
"TXTSTYLE" ) )
1310 if( styleStr == wxT(
"DIMENSION_INTERNAL" ) )
1312 else if( styleStr == wxT(
"DIMENSION_EXTERNAL" ) )
1324 wxASSERT( aNode->GetName() == wxT(
"EXTLINE" ) );
1333 for( ; cNode; cNode = cNode->
GetNext() )
1335 wxString cNodeName = cNode->GetName();
1337 if( noOfPoints < 2 && cNodeName == wxT(
"PT" ) )
1341 if( noOfPoints == 1 )
1342 Start.Parse( cNode, aContext );
1344 End.Parse( cNode, aContext );
1346 else if( cNodeName == wxT(
"SUPPRESSFIRST" ) )
1356 if( noOfPoints != 2 )
1363 if( aNode->GetName() == wxT(
"LEADERLINE" ) || aNode->GetName() == wxT(
"LINEARLINE" )
1364 || aNode->GetName() == wxT(
"ANGULARLINE" ) )
1377 wxASSERT(
IsLine( aNode ) );
1379 if( aNode->GetName() == wxT(
"LINEARLINE" ) )
1380 Type = TYPE::LINEARLINE;
1381 else if( aNode->GetName() == wxT(
"LEADERLINE" ) )
1382 Type = TYPE::LEADERLINE;
1383 else if( aNode->GetName() == wxT(
"ANGULARLINE" ) )
1384 Type = TYPE::ANGULARLINE;
1386 wxASSERT_MSG(
true, wxT(
"Not a valid type. What happened to the node Name?" ) );
1390 if(
Type == TYPE::LEADERLINE )
1398 int requiredNoOfPoints = 2;
1400 if(
Type == TYPE::ANGULARLINE )
1401 requiredNoOfPoints = 3;
1403 for( ; cNode; cNode = cNode->
GetNext() )
1405 wxString cNodeName = cNode->GetName();
1407 if( cNodeName == wxT(
"DIMLINETYPE" ) )
1411 if( styleStr == wxT(
"DIMENSION_INTERNAL" ) )
1413 else if( styleStr == wxT(
"DIMENSION_EXTERNAL" ) )
1418 else if( noOfPoints < requiredNoOfPoints && cNodeName == wxT(
"PT" ) )
1422 if( noOfPoints == 1 )
1423 Start.Parse( cNode, aContext );
1424 else if( noOfPoints == 2 )
1425 End.Parse( cNode, aContext );
1427 Centre.Parse( cNode, aContext );
1429 else if(
Type == TYPE::LEADERLINE && cNodeName == wxT(
"LEADERANG" ) )
1439 if( noOfPoints != requiredNoOfPoints )
1446 if( aNode->GetName() == wxT(
"LINEARDIM" ) || aNode->GetName() == wxT(
"LEADERDIM" )
1447 || aNode->GetName() == wxT(
"ANGLEDIM" ) )
1462 std::map<wxString, TYPE> typeMap = { { wxT(
"LINEARDIM" ), TYPE::LINEARDIM },
1463 { wxT(
"LEADERDIM" ), TYPE::LEADERDIM }, { wxT(
"ANGLEDIM" ), TYPE::ANGLEDIM } };
1466 wxASSERT_MSG( typeMap.find( aNode->GetName() ) != typeMap.end(),
1467 wxT(
"Not a valid type. What happened to the node Name?" ) );
1469 Type = typeMap[aNode->GetName()];
1473 std::map<wxString, SUBTYPE> subTypeMap = {
1481 if( subTypeMap.find( subTypeStr ) == subTypeMap.end() )
1488 Subtype = subTypeMap[subTypeStr];
1494 bool idParsed =
false;
1495 bool unitsParsed =
false;
1496 bool arrowParsed =
false;
1497 bool textFormatParsed =
false;
1498 bool extLineParsed =
false;
1499 bool lineParsed =
false;
1500 bool textParsed =
false;
1502 for( ; cNode; cNode = cNode->
GetNext() )
1504 wxString cNodeName = cNode->GetName();
1506 if( !idParsed && cNodeName == wxT(
"DIMREF" ) )
1511 else if( !unitsParsed && cNodeName == wxT(
"UNITS" ) )
1516 else if( !unitsParsed && cNodeName == wxT(
"ANGUNITS" ) )
1521 else if( !arrowParsed && cNodeName == wxT(
"DIMARROW" ) )
1523 Arrow.Parse( cNode, aContext );
1526 else if( !textFormatParsed && cNodeName == wxT(
"DIMTEXT" ) )
1529 textFormatParsed =
true;
1531 else if( !extLineParsed && cNodeName == wxT(
"EXTLINE" ) )
1534 extLineParsed =
true;
1538 Line.Parse( cNode, aContext );
1541 else if( !textParsed && cNodeName == wxT(
"TEXT" ) )
1544 Text.Parse( cNode, aContext,
false );
1547 else if( cNodeName == wxT(
"FIX" ) )
1551 else if( cNodeName == wxT(
"GROUPREF" ) )
1555 else if( cNodeName == wxT(
"REUSEBLOCKREF" ) )
1569 wxASSERT( aNode->GetName() == wxT(
"SYMDEF" ) );
1577 else if(
ReferenceName.StartsWith( wxT(
"STARPOINTNF" ), &rest ) )
1586 for( ; cNode; cNode = cNode->
GetNext() )
1588 wxString cNodeName = cNode->GetName();
1594 else if( cNodeName == wxT(
"SYMHEIGHT" ) )
1598 else if( cNodeName == wxT(
"COMPCOPPER" ) )
1601 compcopper.
Parse( cNode, aContext );
1604 else if( cNodeName == wxT(
"COMPAREA" ) )
1607 area.
Parse( cNode, aContext );
1610 else if( cNodeName == wxT(
"PAD" ) )
1613 pad.Parse( cNode, aContext );
1616 else if( cNodeName == wxT(
"DIMENSIONS" ) )
1620 for( ; dimensionNode; dimensionNode = dimensionNode->
GetNext() )
1625 dim.
Parse( dimensionNode, aContext );
1647 wxASSERT( aNode->GetName() == wxT(
"LIBRARY" ) );
1651 for( ; cNode; cNode = cNode->
GetNext() )
1653 wxString cNodeName = cNode->GetName();
1655 if( cNodeName == wxT(
"SYMDEF" ) )
1658 symdef.
Parse( cNode, aContext );
1661 else if( cNodeName == wxT(
"HIERARCHY" ) )
1681 wxASSERT( aNode->GetName() == wxT(
"BOARD" ) );
1687 bool shapeIsInitialised =
false;
1688 wxString
location = wxString::Format( wxT(
"BOARD %s" ),
ID );
1693 for( ; cNode; cNode = cNode->
GetNext() )
1695 wxString cNodeName = cNode->GetName();
1697 if( !shapeIsInitialised && SHAPE::IsShape( cNode ) )
1699 Shape.Parse( cNode, aContext );
1700 shapeIsInitialised =
true;
1702 else if( cNodeName == wxT(
"ATTR" ) )
1705 attr.
Parse( cNode, aContext );
1708 else if( cNodeName == wxT(
"FIX" ) )
1712 else if( cNodeName == wxT(
"GROUPREF" ) )
1716 else if( cNodeName == wxT(
"REUSEBLOCKREF" ) )
1730 wxASSERT( aNode->GetName() == wxT(
"AREA" ) );
1738 bool shapeIsInitialised =
false;
1739 wxString
location = wxString::Format( wxT(
"AREA %s" ),
ID );
1744 for( ; cNode; cNode = cNode->
GetNext() )
1746 wxString cNodeName = cNode->GetName();
1748 if( !shapeIsInitialised && SHAPE::IsShape( cNode ) )
1750 Shape.Parse( cNode, aContext );
1751 shapeIsInitialised =
true;
1753 else if( cNodeName == wxT(
"FIX" ) )
1757 else if( cNodeName == wxT(
"USAGE" ) )
1759 wxXmlAttribute* xmlAttribute = cNode->GetAttributes();
1761 for( ; xmlAttribute; xmlAttribute = xmlAttribute->GetNext() )
1766 if( xmlAttribute->GetValue() == wxT(
"PLACEMENT" ) )
1768 else if( xmlAttribute->GetValue() == wxT(
"ROUTING" ) )
1770 else if( xmlAttribute->GetValue() == wxT(
"KEEPOUT" ) )
1772 else if( xmlAttribute->GetValue() == wxT(
"NO_TRACKS" ) )
1774 else if( xmlAttribute->GetValue() == wxT(
"NO_VIAS" ) )
1782 else if( cNodeName == wxT(
"AREAHEIGHT" ) )
1786 else if( cNodeName == wxT(
"GROUPREF" ) )
1790 else if( cNodeName == wxT(
"REUSEBLOCKREF" ) )
1794 else if( cNodeName == wxT(
"ATTR" ) )
1797 attr.
Parse( cNode, aContext );
1810 wxASSERT( aNode->GetName() == wxT(
"PINATTR" ) );
1816 for( ; cNode; cNode = cNode->
GetNext() )
1818 wxString cNodeName = cNode->GetName();
1820 if( cNodeName == wxT(
"ATTR" ) )
1823 attrVal.
Parse( cNode, aContext );
1826 else if( cNodeName == wxT(
"TESTLAND" ) )
1840 wxASSERT( aNode->GetName() == wxT(
"PADEXCEPTION" ) );
1846 for( ; cNode; cNode = cNode->
GetNext() )
1848 wxString cNodeName = cNode->GetName();
1850 if( cNodeName == wxT(
"PADCODEREF" ) )
1854 else if( cNodeName == wxT(
"EXITS" ) )
1857 Exits.Parse( cNode, aContext );
1859 else if( cNodeName == wxT(
"SIDE" ) )
1864 else if( cNodeName == wxT(
"ORIENT" ) )
1879 wxASSERT( aNode->GetName() == wxT(
"COMP" ) );
1887 bool originParsed =
false;
1889 for( ; cNode; cNode = cNode->
GetNext() )
1891 wxString cNodeName = cNode->GetName();
1893 if( !originParsed && cNodeName == wxT(
"PT" ) )
1895 Origin.Parse( cNode, aContext );
1896 originParsed =
true;
1898 else if( cNodeName == wxT(
"GROUPREF" ) )
1902 else if( cNodeName == wxT(
"REUSEBLOCKREF" ) )
1906 else if( cNodeName == wxT(
"TESTPOINT" ) )
1910 else if( cNodeName == wxT(
"FIX" ) )
1914 else if( cNodeName == wxT(
"MIRROR" ) )
1918 else if( cNodeName == wxT(
"READABILITY" ) )
1922 else if( cNodeName == wxT(
"ORIENT" ) )
1926 else if( cNodeName == wxT(
"VCOMPMASTER" ) )
1931 else if( cNodeName == wxT(
"TEXTLOC" ) )
1934 textloc.
Parse( cNode, aContext );
1937 else if( cNodeName == wxT(
"ATTR" ) )
1940 attrVal.
Parse( cNode, aContext );
1943 else if( cNodeName == wxT(
"PINATTR" ) )
1946 pinAttr.
Parse( cNode, aContext );
1949 else if( cNodeName == wxT(
"COMPPINLABEL" ) )
1953 PinLabels.insert( std::make_pair( pinID, pinLabel ) );
1955 else if( cNodeName == wxT(
"PADEXCEPTION" ) )
1958 padExcept.
Parse( cNode, aContext );
1975 wxASSERT( aNode->GetName() == wxT(
"TESTLAND" ) );
1979 if( side == wxT(
"MIN_SIDE" ) )
1981 else if( side == wxT(
"MAX_SIDE" ) )
1983 else if( side == wxT(
"BOTH_SIDES" ) )
1994 wxASSERT( aNode->GetName() == wxT(
"TRUNK" ) );
2003 wxASSERT( aNode->GetName() == wxT(
"PIN" ) );
2018 for( ; cNode; cNode = cNode->
GetNext() )
2022 else if( cNode->GetName() == wxT(
"TRUNKREF" ) )
2032 wxASSERT( aNode->GetName() == wxT(
"VIA" ) );
2040 for( ; cNode; cNode = cNode->
GetNext() )
2042 wxString cNodeName = cNode->GetName();
2044 if( cNodeName == wxT(
"PT" ) )
2046 else if( cNodeName == wxT(
"FIX" ) )
2048 else if( cNodeName == wxT(
"GROUPREF" ) )
2050 else if( cNodeName == wxT(
"REUSEBLOCKREF" ) )
2052 else if( cNodeName == wxT(
"TESTLAND" ) )
2054 else if( cNode->GetName() == wxT(
"TRUNKREF" ) )
2065 wxASSERT( aNode->GetName() == wxT(
"COPTERM" ) );
2076 XNODE* prevNode = aNode;
2078 bool vertexParsed =
false;
2080 if( aNode->GetName() == wxT(
"ROUTEWIDTH" ) )
2088 wxASSERT( VERTEX::IsVertex( aNode ) );
2090 Vertex.Parse( aNode, aContext );
2091 vertexParsed =
true;
2094 for( ; nextNode; nextNode = nextNode->
GetNext() )
2096 if( nextNode->GetName() == wxT(
"FIX" ) )
2100 else if( nextNode->GetName() == wxT(
"TDROPATSTART" ) )
2105 else if( nextNode->GetName() == wxT(
"TDROPATEND" ) )
2110 else if( VERTEX::IsVertex( nextNode ) )
2117 Vertex.Parse( nextNode, aContext );
2118 vertexParsed =
true;
2120 else if( nextNode->GetName() == wxT(
"ROUTEWIDTH" ) )
2129 prevNode = nextNode;
2138 wxASSERT( aNode->GetName() == wxT(
"ROUTE" ) );
2144 bool startPointParsed =
false;
2146 for( ; cNode; cNode = cNode->
GetNext() )
2148 wxString cNodeName = cNode->GetName();
2150 if( !startPointParsed && cNodeName == wxT(
"PT" ) )
2152 startPointParsed =
true;
2155 else if( cNodeName == wxT(
"ROUTEWIDTH" ) || VERTEX::IsVertex( cNode ) )
2161 cNode = rtVert.
Parse( cNode, aContext );
2164 assert( cNode !=
nullptr );
2181 bool routeParsed =
false;
2183 for( ; cNode; cNode = cNode->
GetNext() )
2185 wxString cNodeName = cNode->GetName();
2191 else if( !
Unrouted && !routeParsed && cNodeName == wxT(
"ROUTE" ) )
2193 Route.Parse( cNode, aContext );
2196 else if( !routeParsed && cNodeName == wxT(
"UNROUTE" ) )
2201 else if( cNode->GetName() == wxT(
"TRUNKREF" ) )
2220 for( ; cNode; cNode = cNode->
GetNext() )
2222 wxString cNodeName = cNode->GetName();
2224 if( cNodeName == wxT(
"JPT" ) )
2227 jpt.
Parse( cNode, aContext );
2228 Junctions.insert( std::make_pair( jpt.
ID, jpt ) );
2234 else if( cNodeName == wxT(
"PIN" ) )
2237 pin.Parse( cNode, aContext );
2238 Pins.insert( std::make_pair(
pin.ID,
pin ) );
2240 else if( cNodeName == wxT(
"VIA" ) )
2243 via.Parse( cNode, aContext );
2244 Vias.insert( std::make_pair(
via.ID,
via ) );
2246 else if( cNodeName == wxT(
"COPTERM" ) )
2249 cterm.
Parse( cNode, aContext );
2252 else if( cNodeName == wxT(
"CONN" ) )
2255 conn.
Parse( cNode, aContext );
2268 wxASSERT( aNode->GetName() == wxT(
"POURING" ) );
2280 if( MinIsolCopStr == wxT(
"NONE" ) )
2287 if( MinDisjCopStr == wxT(
"NONE" ) )
2294 for( ; cNode; cNode = cNode->
GetNext() )
2296 wxString cNodeName = cNode->GetName();
2298 if( cNodeName == wxT(
"NOPINRELIEF" ) )
2302 else if( cNodeName == wxT(
"NOVIARELIEF" ) )
2306 else if( cNodeName == wxT(
"IGNORETRN" ) )
2310 else if( cNodeName == wxT(
"BOXPINS" ) )
2314 else if( cNodeName == wxT(
"REGENERATE" ) )
2318 else if( cNodeName == wxT(
"AUTOROUTETARGET" ) )
2322 else if( cNodeName == wxT(
"THERMALCUTOUT" ) )
2326 else if( cNodeName == wxT(
"FILLED" ) )
2330 else if( cNodeName == wxT(
"HATCHCODEREF" ) )
2345 wxASSERT( aNode->GetName() == wxT(
"TEMPLATE" ) );
2354 bool shapeParsed =
false;
2355 bool pouringParsed =
false;
2357 for( ; cNode; cNode = cNode->
GetNext() )
2359 wxString cNodeName = cNode->GetName();
2361 if( !shapeParsed && SHAPE::IsShape( cNode ) )
2363 Shape.Parse( cNode, aContext );
2366 else if( !pouringParsed && cNodeName == wxT(
"POURING" ) )
2368 Pouring.Parse( cNode, aContext );
2369 pouringParsed =
true;
2371 else if( cNodeName == wxT(
"FIX" ) )
2375 else if( cNodeName == wxT(
"GROUPREF" ) )
2379 else if( cNodeName == wxT(
"REUSEBLOCKREF" ) )
2383 else if( cNodeName == wxT(
"ATTR" ) )
2386 attr.
Parse( cNode, aContext );
2400 wxASSERT( aNode->GetName() == wxT(
"TERM" ) );
2405 bool locationParsed =
false;
2407 for( ; cNode; cNode = cNode->
GetNext() )
2409 wxString cNodeName = cNode->GetName();
2411 if( !locationParsed && cNodeName == wxT(
"PT" ) )
2414 locationParsed =
true;
2416 else if( cNodeName == wxT(
"FIX" ) )
2430 wxASSERT( aNode->GetName() == wxT(
"NETREF" ) );
2436 for( ; cNode; cNode = cNode->
GetNext() )
2438 wxString cNodeName = cNode->GetName();
2440 if( cNodeName == wxT(
"TERM" ) )
2443 term.
Parse( cNode, aContext );
2446 else if( cNodeName == wxT(
"FIX" ) )
2460 wxASSERT( aNode->GetName() == wxT(
"COPPER" ) );
2467 bool shapeParsed =
false;
2468 bool netRefParsed =
false;
2470 for( ; cNode; cNode = cNode->
GetNext() )
2472 wxString cNodeName = cNode->GetName();
2474 if( !shapeParsed && SHAPE::IsShape( cNode ) )
2476 Shape.Parse( cNode, aContext );
2479 else if( !netRefParsed && cNodeName == wxT(
"NETREF" ) )
2481 NetRef.Parse( cNode, aContext );
2482 netRefParsed =
true;
2484 else if( cNodeName == wxT(
"FIX" ) )
2488 else if( cNodeName == wxT(
"GROUPREF" ) )
2492 else if( cNodeName == wxT(
"REUSEBLOCKREF" ) )
2496 else if( cNodeName == wxT(
"POURED" ) )
2500 else if( cNodeName == wxT(
"ATTR" ) )
2503 attr.
Parse( cNode, aContext );
2516 wxASSERT( aNode->GetName() == wxT(
"DRILLTABLE" ) );
2522 bool positionParsed =
false;
2524 for( ; cNode; cNode = cNode->
GetNext() )
2526 wxString cNodeName = cNode->GetName();
2528 if( !positionParsed && cNodeName == wxT(
"PT" ) )
2531 positionParsed =
true;
2533 else if( cNodeName == wxT(
"ORIENT" ) )
2537 else if( cNodeName == wxT(
"MIRROR" ) )
2541 else if( cNodeName == wxT(
"FIX" ) )
2545 else if( cNodeName == wxT(
"READABILITY" ) )
2549 else if( cNodeName == wxT(
"GROUPREF" ) )
2553 else if( cNodeName == wxT(
"REUSEBLOCKREF" ) )
2567 wxASSERT( aNode->GetName() == wxT(
"LAYOUT" ) );
2570 bool netSynchParsed =
false;
2571 bool dimensionsParsed =
false;
2573 for( ; cNode; cNode = cNode->
GetNext() )
2575 wxString cNodeName = cNode->GetName();
2577 if( !netSynchParsed && cNodeName == wxT(
"NETSYNCH" ) )
2579 std::map<wxString, NETSYNCH> netSynchMap = { { wxT(
"WARNING" ),
NETSYNCH::WARNING },
2584 if( netSynchMap.find( nsString ) == netSynchMap.end() )
2593 netSynchParsed =
true;
2595 else if( cNodeName == wxT(
"GROUP" ) )
2598 group.Parse( cNode, aContext );
2601 else if( cNodeName == wxT(
"REUSEBLOCK" ) )
2604 reuseblock.
Parse( cNode, aContext );
2605 ReuseBlocks.insert( std::make_pair( reuseblock.
ID, reuseblock ) );
2607 else if( cNodeName == wxT(
"BOARD" ) )
2610 board.
Parse( cNode, aContext );
2611 Boards.insert( std::make_pair( board.
ID, board ) );
2613 else if( cNodeName == wxT(
"FIGURE" ) )
2616 figure.
Parse( cNode, aContext );
2617 Figures.insert( std::make_pair( figure.
ID, figure ) );
2619 else if( cNodeName == wxT(
"AREA" ) )
2622 area.
Parse( cNode, aContext );
2623 Areas.insert( std::make_pair( area.
ID, area ) );
2625 else if( cNodeName == wxT(
"COMP" ) )
2628 comp.Parse( cNode, aContext );
2631 else if( cNodeName == wxT(
"TRUNK" ) )
2634 trunk.
Parse( cNode, aContext );
2635 Trunks.insert( std::make_pair( trunk.
ID, trunk ) );
2637 else if( cNodeName == wxT(
"NET" ) )
2640 net.
Parse( cNode, aContext );
2641 Nets.insert( std::make_pair( net.
ID, net ) );
2643 else if( cNodeName == wxT(
"TEMPLATE" ) )
2646 temp.
Parse( cNode, aContext );
2647 Templates.insert( std::make_pair( temp.
ID, temp ) );
2649 else if( cNodeName == wxT(
"COPPER" ) )
2652 copper.
Parse( cNode, aContext );
2653 Coppers.insert( std::make_pair( copper.
ID, copper ) );
2655 else if( cNodeName == wxT(
"TEXT" ) )
2658 txt.
Parse( cNode, aContext );
2659 Texts.insert( std::make_pair( txt.
ID, txt ) );
2661 else if( cNodeName == wxT(
"DOCSYMBOL" ) )
2664 docsym.
Parse( cNode, aContext );
2667 else if( !dimensionsParsed && cNodeName == wxT(
"DIMENSIONS" ) )
2671 for( ; dimensionNode; dimensionNode = dimensionNode->
GetNext() )
2676 dim.
Parse( dimensionNode, aContext );
2685 dimensionsParsed =
true;
2687 else if( cNodeName == wxT(
"DRILLTABLE" ) )
2690 drilltable.
Parse( cNode, aContext );
2691 DrillTables.insert( std::make_pair( drilltable.
ID, drilltable ) );
2693 else if( cNodeName == wxT(
"VHIERARCHY" ) )
2697 else if( cNodeName == wxT(
"ERRORMARK" ) )
constexpr double PCB_IU_PER_MM
Pcbnew IU is 1 nanometer.
#define WARN_UNKNOWN_NODE_IO_ERROR(nodename, location)
#define THROW_MISSING_NODE_IO_ERROR(nodename, location)
#define WARN_UNKNOWN_PARAMETER_IO_ERROR(param, location)
#define THROW_MISSING_PARAMETER_IO_ERROR(param, location)
#define THROW_PARSING_IO_ERROR(param, location)
static UNITS ParseUnits(XNODE *aNode)
static SWAP_RULE ParseSwapRule(XNODE *aNode)
static const long UNDEFINED_VALUE
static void CheckNoNextNodes(XNODE *aNode)
static XNODE * LoadArchiveFile(const wxString &aFileName, const wxString &aFileTypeIdentifier, PROGRESS_REPORTER *aProgressReporter=nullptr)
Reads a CADSTAR Archive file (S-parameter format).
wxString LAYER_ID
ID of a Sheet (if schematic) or board Layer (if PCB)
static ANGUNITS ParseAngunits(XNODE *aNode)
long PART_DEFINITION_PIN_ID
Pin identifier in the part definition.
static wxString GetXmlAttributeIDString(XNODE *aNode, unsigned int aID, bool aIsRequired=true)
void checkPoint()
Updates m_progressReporter or throws if user canceled.
static bool IsValidAttribute(wxXmlAttribute *aAttribute)
static READABILITY ParseReadability(XNODE *aNode)
static void CheckNoChildNodes(XNODE *aNode)
static long GetXmlAttributeIDLong(XNODE *aNode, unsigned int aID, bool aIsRequired=true)
static void ParseChildEValue(XNODE *aNode, PARSER_CONTEXT *aContext, EVALUE &aValueToParse)
static long GetNumberOfStepsForReporting(XNODE *aRootNode, std::vector< wxString > aSubNodeChildrenToCount)
PROGRESS_REPORTER * m_progressReporter
static TESTLAND_SIDE ParseTestlandSide(XNODE *aNode)
@ STARPOINT
From CADSTAR Help: "Starpoints are special symbols/components that can be used to electrically connec...
@ JUMPER
From CADSTAR Help: "Jumpers are components used primarily for the purpose of routing.
@ COMPONENT
Standard PCB Component definition.
@ TESTPOINT
From CADSTAR Help: "A testpoint is an area of copper connected to a net.
@ ANTI_ROUTE
Keyword "ANTITRACK".
@ OBSTACLE
Keyword "OBSTACLE".
@ UNBIASED
Keyword "UNBIASED" (default)
long PAD_ID
Pad identifier (pin) in the PCB.
@ LAYERSUBTYPE_SOLDERRESIST
@ LAYERSUBTYPE_SILKSCREEN
void Parse(bool aLibrary=false)
Parses the file.
int KiCadUnitMultiplier
Use this value to convert units in this CPA file to KiCad units.
@ ALLELEC
Inbuilt layer type (cannot be assigned to user layers)
@ ALLDOC
Inbuilt layer type (cannot be assigned to user layers)
@ NONELEC
This type has subtypes.
@ NOLAYER
Inbuilt layer type (cannot be assigned to user layers)
@ JUMPERLAYER
Inbuilt layer type (cannot be assigned to user layers)
@ ALLLAYER
Inbuilt layer type (cannot be assigned to user layers)
@ ASSCOMPCOPP
Inbuilt layer type (cannot be assigned to user layers)
@ ROUNDED_RECT
Keyword "ROUNDED".
@ MAX
The highest PHYSICAL_LAYER_ID currently defined (i.e. back / bottom side).
@ MIN
The lowest PHYSICAL_LAYER_ID currently defined (i.e. front / top side).
static PAD_SIDE GetPadSide(const wxString &aPadSideString)
PAD_SIDE
From CADSTAR Help: "This parameter indicates the physical layers on which the selected pad is placed.
@ MAXIMUM
The highest PHYSICAL_LAYER_ID currently defined (i.e.
@ MINIMUM
PHYSICAL_LAYER_ID 1 (i.e.
@ THROUGH_HOLE
All physical layers currently defined.
An extension of wxXmlNode that can format its contents as KiCad-style s-expressions.
XNODE * GetChildren() const
#define THROW_IO_ERROR(msg)
macro which captures the "call site" values of FILE_, __FUNCTION & LINE
This file contains miscellaneous commonly used macros and functions.
#define KI_FALLTHROUGH
The KI_FALLTHROUGH macro is to be used when switch statement cases should purposely fallthrough from ...
static wxString nodeName(const wxString &aSymbolPin)
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
bool ParseSubNode(XNODE *aChildNode, PARSER_CONTEXT *aContext)
DOCUMENTATION_SYMBOL_ID ID
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void ParseIdentifiers(XNODE *aNode, PARSER_CONTEXT *aContext)
bool ParseSubNode(XNODE *aChildNode, PARSER_CONTEXT *aContext)
bool ParseSubNode(XNODE *aChildNode, PARSER_CONTEXT *aContext)
void ParseIdentifiers(XNODE *aNode, PARSER_CONTEXT *aContext)
NETELEMENT_ID ID
First character is "J".
bool ParseSubNode(XNODE *aChildNode, PARSER_CONTEXT *aContext)
void ParseIdentifiers(XNODE *aNode, PARSER_CONTEXT *aContext)
std::function< void()> CheckPointCallback
Callback function to report progress.
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
bool ParseSubNode(XNODE *aChildNode, PARSER_CONTEXT *aContext)
POINT Origin
Origin of the component (this is used as the reference point when placing the component in the design...
bool ParseSubNode(XNODE *aChildNode, PARSER_CONTEXT *aContext)
bool Stub
When the CADSTAR Archive file is exported without the component library, if components on the board a...
wxString ReferenceName
This is the name which identifies the symbol in the library Multiple components may exist with the sa...
void ParseIdentifiers(XNODE *aNode, PARSER_CONTEXT *aContext)
Corresponds to CADSTAR "origin".
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
From CADSTAR Help: "Area is for creating areas within which, and nowhere else, certain operations are...
GROUP_ID GroupID
If not empty, this AREA is part of a group.
bool Keepout
From CADSTAR Help: "Auto Placement cannot place components within this area.
bool Placement
From CADSTAR Help: "Auto Placement can place components within this area.
bool NoVias
From CADSTAR Help: "No vias will be placed within this area by the automatic router.
REUSEBLOCKREF ReuseBlockRef
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
long AreaHeight
From CADSTAR Help: "The Height value specified for the PCB component is checked against the Height va...
bool Routing
From CADSTAR Help: "Area can be used to place routes during Automatic Routing.
std::map< ATTRIBUTE_ID, ATTRIBUTE_VALUE > AttributeValues
bool NoTracks
From CADSTAR Help: "Area cannot be used to place routes during automatic routing.
TECHNOLOGY_SECTION Technology
bool SpacingclassEditAttributeSettings
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
bool NetclassEditAttributeSettings
GROUP_ID GroupID
Normally CADSTAR_BOARD cannot be part of a reuseblock, but included for completeness.
bool Fixed
If not empty, this CADSTAR_BOARD is part of a group.
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
REUSEBLOCKREF ReuseBlockRef
std::map< ATTRIBUTE_ID, ATTRIBUTE_VALUE > AttributeValues
long OrientAngle
1/1000 of a Degree
static bool IsPadShape(XNODE *aNode)
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
std::map< COPPERCODE_ID, COPPERCODE > CopperCodes
std::map< PADCODE_ID, PADCODE > PadCodes
std::map< RULESET_ID, RULESET > Rulesets
Used for area design rules.
std::vector< SPCCLASSSPACE > SpacingClasses
std::map< VIACODE_ID, VIACODE > ViaCodes
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
std::map< SPACINGCODE_ID, SPACINGCODE > SpacingCodes
Spacing Design Rules.
std::map< LAYERPAIR_ID, LAYERPAIR > LayerPairs
Default vias to use between pairs of layers.
From CADSTAR Help: "Area is for creating areas within which, and nowhere else, certain operations are...
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
bool NoVias
From CADSTAR Help: "Check this button to specify that any area created by the Rectangle,...
bool NoTracks
From CADSTAR Help: "Check this button to specify that any area created by the Rectangle,...
A shape of copper in the component footprint.
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
std::vector< PAD_ID > AssociatedPadIDs
COPPERCODE_ID CopperCodeID
bool PCBonlyPad
From CADSTAR Help: "The PCB Only Pad property can be used to stop ECO Update, Back Annotation,...
PAD_EXITS Exits
See PAD_EXITS.
POINT Position
Pad position within the component's coordinate frame.
wxString Identifier
This is an identifier that is displayed to the user.
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
PAD_SIDE Side
See PAD_SIDE.
bool FirstPad
From CADSTAR Help: "Only one pad can have this property; if an existing pad in the design already has...
wxString Name
Designator e.g. "C1", "R1", etc.
POINT Origin
Origin of the component (this is used as the reference point when placing the component in the design...
bool TestPoint
Indicates whether this component should be treated as a testpoint.
std::map< ATTRIBUTE_ID, ATTRIBUTE_VALUE > AttributeValues
std::map< PAD_ID, PADEXCEPTION > PadExceptions
Override pad definitions for this instance.
std::map< ATTRIBUTE_ID, TEXT_LOCATION > TextLocations
This contains location of any attributes, including designator position.
std::map< PART_DEFINITION_PIN_ID, PIN_ATTRIBUTE > PinAttributes
REUSEBLOCKREF ReuseBlockRef
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
GROUP_ID GroupID
If not empty, this component is part of a group.
COMPONENT_ID VariantParentComponentID
std::map< PART_DEFINITION_PIN_ID, wxString > PinLabels
This is inherited from the PARTS library but is allowed to be out of sync.
std::vector< COPREASSIGN > Reassigns
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
std::map< COPPER_TERM_ID, COPPER_TERM > CopperTerminals
GROUP_ID GroupID
If not empty, this COPPER is part of a group.
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
REUSEBLOCKREF ReuseBlockRef
COPPERCODE_ID CopperCodeID
TEMPLATE_ID PouredTemplateID
If not empty, it means this COPPER is part of a poured template.
std::map< ATTRIBUTE_ID, ATTRIBUTE_VALUE > AttributeValues
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
@ CLOSED
The arrow head is made up of two angled lines either side of main line plus two other lines perpendic...
@ CLEAR
Same as closed but the main line finishes at the start of the perpendicular lines.
@ CLOSED_FILLED
The same as CLOSED or CLEAR arrows, but with a solid fill "DIMENSION_ARROWCLOSEDFILLED".
@ OPEN
The arrow head is made up of two angled lines either side of main line.
long ArrowLength
The length of the angled lines that make up the arrow head.
STYLE ArrowStyle
Subnode="ARROWSTYLE".
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
long LowerAngle
token="ARROWANGLEB"
long UpperAngle
token="ARROWANGLEA"
long Offset
Offset from the measurement point.
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
bool SuppressFirst
If true, excludes the first extension line (only shows extension line at end)
long Overshoot
Overshoot of the extension line past the arrow line.
@ INTERNAL
The lines are placed inside the measurement token=DIMENSION_INTERNAL.
@ EXTERNAL
The lines are placed outside the measurement (typically used when limited space) token=DIMENSION_EXTE...
long LeaderLineExtensionLength
Only for TYPE=LEADERLINE Length of the horizontal part of the leader line [param6].
LINECODE_ID LineCodeID
param0
static bool IsLine(XNODE *aNode)
long LeaderLineLength
Only for TYPE=LEADERLINE Length of the angled part of the leader line [param5].
long LeaderAngle
Only for TYPE=LEADERLINE subnode "LEADERANG".
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
POINT Centre
Only for TYPE=ANGULARLINE [point3].
STYLE Style
Subnode="DIMLINETYPE".
long TextGap
Specifies the gap between the text and the end of the line.
long TextOffset
Specifies how far above the line the text is (doesn't have an effect on actual position!...
@ INSIDE
Embedded with the line (the Gap parameter specifies the gap between the text and the end of the line)...
@ OUTSIDE
Above the line (the Offset parameter specifies how far above the line the text is) DIMENSION_EXTERNAL...
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
Linear, leader (radius/diameter) or angular dimension.
LAYER_ID LayerID
ID on which to draw this [param1].
static bool IsDimension(XNODE *aNode)
@ DIAMETER
token=DIMENSION_DIAMETER
@ DIRECT
A linear dimension parallel to measurement with perpendicular extension lines token=DIMENSION_DIRECT.
@ ANGULAR
token=DIMENSION_ANGULAR
@ RADIUS
token=DIMENSION_RADIUS
@ ORTHOGONAL
An orthogonal dimension (either x or y measurement) token=DIMENSION_ORTHOGONAL.
@ ANGLED
A linear dimension parallel to measurement but with orthogonal extension lines (i....
GROUP_ID GroupID
If not empty, this DIMENSION is part of a group.
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
EXTENSION_LINE ExtensionLineParams
Not applicable to TYPE=LEADERDIM.
DIMENSION_ID ID
Some ID (doesn't seem to be used) subnode="DIMREF".
REUSEBLOCKREF ReuseBlockRef
long Precision
Number of decimal points to display in the measurement [param3].
ANGUNITS AngularUnits
Only Applicable to TYPE=ANGLEDIM.
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
GROUP_ID GroupID
If not empty, this DRILL_TABLE is part of a group.
REUSEBLOCKREF ReuseBlockRef
std::vector< LAYER_ID > LayerStack
std::map< MATERIAL_ID, MATERIAL > Materials
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
std::map< LAYER_ID, LAYER > Layers
PHYSICAL_LAYER_ID PhysicalLayerStart
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
PHYSICAL_LAYER_ID PhysicalLayerEnd
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
PHYSICAL_LAYER_ID PhysicalLayer
If UNDEFINED, no physical layer is assigned (e.g.
long Thickness
Note: Units of length are defined in file header.
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
std::map< TEMPLATE_ID, TEMPLATE > Templates
std::map< BOARD_ID, CADSTAR_BOARD > Boards
Normally CADSTAR only allows one board but.
std::map< TEXT_ID, TEXT > Texts
std::map< NET_ID, NET_PCB > Nets
Contains tracks and vias.
std::map< FIGURE_ID, FIGURE > Figures
VARIANT_HIERARCHY VariantHierarchy
std::map< COMPONENT_ID, COMPONENT > Components
std::map< COPPER_ID, COPPER > Coppers
std::map< DOCUMENTATION_SYMBOL_ID, DOCUMENTATION_SYMBOL > DocumentationSymbols
std::map< TRUNK_ID, TRUNK > Trunks
std::map< DIMENSION_ID, DIMENSION > Dimensions
std::map< REUSEBLOCK_ID, REUSEBLOCK > ReuseBlocks
std::map< AREA_ID, AREA > Areas
std::map< DRILL_TABLE_ID, DRILL_TABLE > DrillTables
std::map< GROUP_ID, GROUP > Groups
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
std::map< SYMDEF_ID, SYMDEF_PCB > ComponentDefinitions
EVALUE Resistivity
x10^-8 ohm*metre
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
LAYER_ID UnrouteLayerID
See Unrouted member variable.
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
TRUNK_ID TrunkID
TRUNKREF Statements.
bool Unrouted
Instead of a ROUTE, the CONNECTION might have an "UNROUTE" token.
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
COPPER_TERM_ID CopperTermNum
NETELEMENT_ID ID
First two character are "CT".
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
TRUNK_ID TrunkID
TRUNKREF Statements.
< "PIN" nodename (represents a PAD in a PCB component)
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
NETELEMENT_ID ID
First character is "P".
< Two sibbling nodes: first node being "ROUTEWIDTH" and next node being a VERTEX (e....
XNODE * Parse(XNODE *aNode, PARSER_CONTEXT *aContext)
bool RouteWidthIsExplicit
False if ROUTEWIDTH was not specified in file.
long TeardropAtStartAngle
VERTEX Vertex
Returns a pointer to the last node.
std::vector< ROUTE_VERTEX > RouteVertices
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
TESTLAND_SIDE TestlandSide
REUSEBLOCKREF ReuseBlockRef
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
GROUP_ID GroupID
If not empty, this VIA is part of a group.
TRUNK_ID TrunkID
TRUNKREF Statements.
NETELEMENT_ID ID
First character is "V".
std::vector< CONNECTION_PCB > Connections
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
std::map< NETELEMENT_ID, COPPER_TERMINAL > CopperTerminals
std::map< NETELEMENT_ID, VIA > Vias
std::map< NETELEMENT_ID, PIN > Pins
std::map< NETELEMENT_ID, JUNCTION_PCB > Junctions
long ReliefWidth
if undefined inherits from design
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
std::map< LAYER_ID, CADSTAR_PAD_SHAPE > Reassigns
long ReliefClearance
if undefined inherits from design
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
PADCODE_ID PadCode
If not empty, override padcode.
bool HasShape
False when the shape node was unknown and skipped.
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
std::map< ATTRIBUTE_ID, ATTRIBUTE_VALUE > AttributeValues
TESTLAND_SIDE TestlandSide
PART_DEFINITION_PIN_ID Pin
ROUTECODE_ID AreaRouteCodeID
For assigning a net route code to a rule set.
VIACODE_ID AreaViaCodeID
For assigning a via code to a rule set.
std::map< SPACINGCODE_ID, SPACINGCODE > SpacingCodes
Overrides these spacing rules in the specific area.
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
std::vector< REASSIGN > Reassigns
Can have different spacings on different layers.
SPACINGCODE_ID ID
Possible spacing rules:
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
SPACING_CLASS_ID SpacingClassID1
LAYER_ID LayerID
Normally LAY0, which corresponds to (All Layers)
SPACING_CLASS_ID SpacingClassID2
std::map< PAD_ID, COMPONENT_PAD > ComponentPads
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
std::map< DIMENSION_ID, DIMENSION > Dimensions
inside "DIMENSIONS" subnode
std::vector< COMPONENT_COPPER > ComponentCoppers
long SymHeight
The Height of the component (3D height in z direction)
std::map< COMP_AREA_ID, COMPONENT_AREA > ComponentAreas
long MinRouteWidth
Manufacturing Design Rule. Corresponds to "Thin Route Width".
long TrackGrid
Grid for Routes (equal X and Y steps)
long MinNeckedLength
Manufacturing Design Rule.
long MaxPhysicalLayer
Should equal number of copper layers.
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
long MinUnneckedLength
Manufacturing Design Rule.
long MaxMitre
Manufacturing Design Rule. Corresponds to "Maximum Mitre".
long ViaGrid
Grid for Vias (equal X and Y steps)
long MinMitre
Manufacturing Design Rule. Corresponds to "Minimum Mitre".
long AdditionalIsolation
This is the gap to apply in routes and pads in addition to the existing pad-to-copper or route-to-cop...
bool TargetForAutorouting
true when subnode "AUTOROUTETARGET" is present
bool ThermalReliefOnVias
false when subnode "NOVIARELIEF" is present
@ CUTOUTS
This method uses four cutouts in the copper to leave the reliefs required.
HATCHCODE_ID HatchCodeID
Only for FillType = HATCHED.
bool ThermalReliefOnPads
false when subnode "NOPINRELIEF" is present
long ThermalReliefPadsAngle
Orientation for the thermal reliefs.
@ HATCHED
This is a user defined HATCHCODE_ID.
long MinDisjointCopper
The value is the length of one side of a notional square.
bool AutomaticRepour
true when subnode "REGENERATE" is present
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
bool AllowInNoRouting
true when subnode "IGNORETRN" is present
bool BoxIsolatedPins
true when subnode "BOXPINS" is present
long ClearanceWidth
Specifies the space around pads when pouring (i.e.
COPPERCODE_ID ReliefCopperCodeID
From CADSTAR Help: "Relief Copper Code is forselecting the width of line used to draw thethermal reli...
COPPER_FILL_TYPE FillType
Assume solid fill.
RELIEF_TYPE ReliefType
See RELIEF_TYPE.
COPPERCODE_ID CopperCodeID
From CADSTAR Help: "Copper Code is for selecting the width of the line used to draw the outline and f...
long ThermalReliefViasAngle
Disabled when !ThermalReliefOnVias (param6)
long MinIsolatedCopper
The value is the length of one side of a notional square.
long SliverWidth
Minimum width of copper that may be created.
Templates are CADSTAR's equivalent to a "filled zone".
std::map< ATTRIBUTE_ID, ATTRIBUTE_VALUE > AttributeValues
POURING Pouring
Copper pour settings (e.g. relief / hatching /etc.)
REUSEBLOCKREF ReuseBlockRef
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
GROUP_ID GroupID
If not empty, this TEMPLATE is part of a group.
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
long ReliefClearance
if undefined inherits from design
long ReliefWidth
if undefined inherits from design
std::map< LAYER_ID, CADSTAR_PAD_SHAPE > Reassigns
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
bool HasShape
False when the shape node was unknown and skipped.
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override