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" ) )
85 wxT(
"The selected file is a CADSTAR library file (as opposed "
86 "to a layout file). You can import this library by adding it "
87 "to the library table." ) );
91 THROW_IO_ERROR( wxT(
"The selected file is an unknown CADSTAR format so "
92 "cannot be imported into KiCad." ) );
96 else if( cNode->GetName() == wxT(
"ASSIGNMENTS" ) )
100 else if( cNode->GetName() == wxT(
"LIBRARY" ) )
104 else if( cNode->GetName() == wxT(
"DEFAULTS" ) )
110 else if( cNode->GetName() == wxT(
"PARTS" ) )
114 else if( cNode->GetName() == wxT(
"LAYOUT" ) )
118 else if( cNode->GetName() == wxT(
"DISPLAY" ) )
139 wxASSERT( aNode->GetName() == wxT(
"ASSIGNMENTS" ) );
146 for( ; cNode; cNode = cNode->
GetNext() )
148 if( cNode->GetName() == wxT(
"LAYERDEFS" ) )
150 else if( cNode->GetName() == wxT(
"CODEDEFS" ) )
152 else if( cNode->GetName() == wxT(
"TECHNOLOGY" ) )
154 else if( cNode->GetName() == wxT(
"GRIDS" ) )
155 Grids.Parse( cNode, aContext );
156 else if( cNode->GetName() == wxT(
"NETCLASSEDITATTRIBSETTINGS" ) )
158 else if( cNode->GetName() == wxT(
"SPCCLASSEDITATTRIBSETTINGS" ) )
168 wxASSERT( aNode->GetName() == wxT(
"LAYERDEFS" ) );
170 wxXmlAttribute* xmlAttribute =
nullptr;
177 for( ; cNode; cNode = cNode->
GetNext() )
179 wxString
nodeName = cNode->GetName();
181 if(
nodeName == wxT(
"LAYERSTACK" ) )
183 xmlAttribute = cNode->GetAttributes();
185 for( ; xmlAttribute; xmlAttribute = xmlAttribute->GetNext() )
195 else if(
nodeName == wxT(
"MATERIAL" ) )
198 material.
Parse( cNode, aContext );
199 Materials.insert( std::make_pair( material.
ID, material ) );
201 else if(
nodeName == wxT(
"LAYER" ) )
204 layer.
Parse( cNode, aContext );
205 Layers.insert( std::make_pair( layer.
ID, layer ) );
207 else if(
nodeName == wxT(
"SWAPPAIR" ) )
212 Layers[layerId].SwapLayerID = swapLayerId;
224 wxASSERT( aNode->GetName() == wxT(
"RULESET" ) );
231 for( ; cNode; cNode = cNode->
GetNext() )
233 wxString
nodeName = cNode->GetName();
235 if(
nodeName == wxT(
"ROUCODEREF" ) )
239 else if(
nodeName == wxT(
"VIACODEREF" ) )
243 else if(
nodeName == wxT(
"SPACINGCODE" ) )
246 spacingcode.
Parse( cNode, aContext );
247 SpacingCodes.insert( std::make_pair( spacingcode.
ID, spacingcode ) );
259 wxASSERT( aNode->GetName() == wxT(
"CODEDEFS" ) );
263 for( ; cNode; cNode = cNode->
GetNext() )
265 wxString
nodeName = cNode->GetName();
270 else if(
nodeName == wxT(
"COPPERCODE" ) )
273 coppercode.
Parse( cNode, aContext );
274 CopperCodes.insert( std::make_pair( coppercode.
ID, coppercode ) );
276 else if(
nodeName == wxT(
"SPACINGCODE" ) )
279 spacingcode.
Parse( cNode, aContext );
280 SpacingCodes.insert( std::make_pair( spacingcode.
ID, spacingcode ) );
282 else if(
nodeName == wxT(
"RULESET" ) )
285 ruleset.
Parse( cNode, aContext );
286 Rulesets.insert( std::make_pair( ruleset.
ID, ruleset ) );
288 else if(
nodeName == wxT(
"PADCODE" ) )
291 padcode.
Parse( cNode, aContext );
292 PadCodes.insert( std::make_pair( padcode.
ID, padcode ) );
294 else if(
nodeName == wxT(
"VIACODE" ) )
297 viacode.
Parse( cNode, aContext );
298 ViaCodes.insert( std::make_pair( viacode.
ID, viacode ) );
300 else if(
nodeName == wxT(
"LAYERPAIR" ) )
303 layerpair.
Parse( cNode, aContext );
304 LayerPairs.insert( std::make_pair( layerpair.
ID, layerpair ) );
306 else if(
nodeName == wxT(
"SPCCLASSSPACE" ) )
309 spcclassspace.
Parse( cNode, aContext );
322 wxASSERT( aNode->GetName() == wxT(
"MATERIAL" ) );
329 if( sType == wxT(
"CONSTRUCTION" ) )
333 else if( sType == wxT(
"ELECTRICAL" ) )
337 else if( sType == wxT(
"NONELEC" ) )
351 wxString::Format( wxT(
"MATERIAL %s" ),
Name ) );
354 for( ; iNode; iNode = iNode->
GetNext() )
356 wxString
nodeName = iNode->GetName();
358 if(
nodeName == wxT(
"RELPERMIT" ) )
362 else if(
nodeName == wxT(
"LOSSTANGENT" ) )
366 else if(
nodeName == wxT(
"RESISTIVITY" ) )
380 wxASSERT( aNode->GetName() == wxT(
"LAYER" ) );
386 auto processLayerMaterialDetails = [&]() {
388 for( ; tempNode; tempNode = tempNode->
GetNext() )
390 wxString tempNodeName = tempNode->GetName();
392 if( tempNodeName == wxT(
"MAKE" ) || tempNodeName == wxT(
"LAYERHEIGHT" ) )
394 if( tempNodeName == wxT(
"LAYERHEIGHT" ) )
406 if( childOfTempNode )
408 if( childOfTempNode->GetName() == wxT(
"EMBEDS" ) )
412 if( embedsValue == wxT(
"UPWARDS" ) )
416 else if( embedsValue == wxT(
"DOWNWARDS" ) )
423 wxString::Format( wxT(
"LAYER %s -> EMBEDS" ),
430 wxString::Format( wxT(
"LAYER %s->MAKE" ),
435 else if( tempNodeName == wxT(
"BIAS" ) )
439 if( bias == wxT(
"X_BIASED" ) )
443 else if( bias == wxT(
"Y_BIASED" ) )
447 else if( bias == wxT(
"ANTITRACK" ) )
451 else if( bias == wxT(
"OBSTACLE" ) )
455 else if( bias == wxT(
"UNBIASED" ) )
462 wxString::Format( wxT(
"LAYER %s -> BIAS" ),
474 for( ; cNode; cNode = cNode->
GetNext() )
476 wxString cNodeName = cNode->GetName();
478 if( cNodeName == wxT(
"ALLDOC" ) )
482 else if( cNodeName == wxT(
"ALLELEC" ) )
486 else if( cNodeName == wxT(
"ALLLAYER" ) )
490 else if( cNodeName == wxT(
"ASSCOMPCOPP" ) )
494 else if( cNodeName == wxT(
"JUMPERLAYER" ) )
498 else if( cNodeName == wxT(
"NOLAYER" ) )
502 else if( cNodeName == wxT(
"POWER" ) )
506 processLayerMaterialDetails();
508 else if( cNodeName == wxT(
"DOC" ) )
512 else if( cNodeName == wxT(
"CONSTRUCTION" ) )
515 processLayerMaterialDetails();
517 else if( cNodeName == wxT(
"ELEC" ) )
521 processLayerMaterialDetails();
523 else if( cNodeName == wxT(
"NONELEC" ) )
527 processLayerMaterialDetails();
529 else if( cNodeName == wxT(
"DESCRIPTION" ) )
533 else if( cNodeName == wxT(
"REFPLANE" ) )
537 else if( cNodeName == wxT(
"VLAYER" ) )
541 else if( cNodeName == wxT(
"LASUBTYP" ) )
546 if( sSubType == wxT(
"LAYERSUBTYPE_ASSEMBLY" ) )
550 else if( sSubType == wxT(
"LAYERSUBTYPE_PASTE" ) )
554 else if( sSubType == wxT(
"LAYERSUBTYPE_PLACEMENT" ) )
558 else if( sSubType == wxT(
"LAYERSUBTYPE_SILKSCREEN" ) )
562 else if( sSubType == wxT(
"LAYERSUBTYPE_SOLDERRESIST" ) )
566 else if( sSubType == wxT(
"LAYERSUBTYPE_CLEARANCE" ) )
570 else if( sSubType == wxT(
"LAYERSUBTYPE_ROUT" ) )
590 wxASSERT( aNode->GetName() == wxT(
"COPREASSIGN" ) );
600 wxASSERT( aNode->GetName() == wxT(
"COPPERCODE" ) );
609 for( ; cNode; cNode = cNode->
GetNext() )
611 if( cNode->GetName() == wxT(
"COPREASSIGN" ) )
614 reassign.
Parse( cNode, aContext );
628 wxASSERT( aNode->GetName() == wxT(
"SPACEREASSIGN" ) );
639 wxASSERT( aNode->GetName() == wxT(
"SPACINGCODE" ) );
646 for( ; cNode; cNode = cNode->
GetNext() )
648 wxString cNodeName = cNode->GetName();
650 if( cNodeName == wxT(
"SPACEREASSIGN" ) )
653 reassign.
Parse( cNode, aContext );
669 wxString aNodeName = aNode->GetName();
671 if( aNodeName == wxT(
"ANNULUS" ) || aNodeName == wxT(
"BULLET" ) || aNodeName == wxT(
"ROUND" )
672 || aNodeName == wxT(
"DIAMOND" ) || aNodeName == wxT(
"FINGER" )
673 || aNodeName == wxT(
"OCTAGON" ) || aNodeName == wxT(
"RECTANGLE" )
674 || aNodeName == wxT(
"ROUNDED" ) || aNodeName == wxT(
"SQUARE" ) )
689 wxString aNodeName = aNode->GetName();
691 if( aNodeName == wxT(
"ANNULUS" ) )
693 else if( aNodeName == wxT(
"BULLET" ) )
695 else if( aNodeName == wxT(
"ROUND" ) )
697 else if( aNodeName == wxT(
"DIAMOND" ) )
699 else if( aNodeName == wxT(
"FINGER" ) )
701 else if( aNodeName == wxT(
"OCTAGON" ) )
703 else if( aNodeName == wxT(
"RECTANGLE" ) )
705 else if( aNodeName == wxT(
"ROUNDED" ) )
707 else if( aNodeName == wxT(
"SQUARE" ) )
735 if( aNode->
GetChildren()->GetName() == wxT(
"ORIENT" ) )
757 wxASSERT( aNode->GetName() == wxT(
"PADREASSIGN" ) );
765 Shape.Parse( shapeNode, aContext );
770 wxString found = shapeNode ? shapeNode->GetName() : wxString(
"(empty)" );
780 wxASSERT( aNode->GetName() == wxT(
"PADCODE" ) );
786 wxString
location = wxString::Format( wxT(
"PADCODE -> %s" ),
Name );
788 for( ; cNode; cNode = cNode->
GetNext() )
790 wxString cNodeName = cNode->GetName();
794 Shape.Parse( cNode, aContext );
796 else if( cNodeName == wxT(
"CLEARANCE" ) )
800 else if( cNodeName == wxT(
"RELIEFWIDTH" ) )
804 else if( cNodeName == wxT(
"DRILL" ) )
809 for( ; subNode; subNode = subNode->
GetNext() )
811 wxString subNodeName = subNode->GetName();
813 if( subNodeName == wxT(
"NONPLATED" ) )
815 else if( subNodeName == wxT(
"OVERSIZE" ) )
821 else if( cNodeName == wxT(
"DRILLLENGTH" ) )
825 else if( cNodeName == wxT(
"DRILLORIENTATION" ) )
829 else if( cNodeName == wxT(
"DRILLXOFFSET" ) )
833 else if( cNodeName == wxT(
"DRILLYOFFSET" ) )
837 else if( cNodeName == wxT(
"PADREASSIGN" ) )
840 reassign.
Parse( cNode, aContext );
855 wxASSERT( aNode->GetName() == wxT(
"VIAREASSIGN" ) );
863 Shape.Parse( shapeNode, aContext );
868 wxString found = shapeNode ? shapeNode->GetName() : wxString(
"(empty)" );
878 wxASSERT( aNode->GetName() == wxT(
"VIACODE" ) );
884 wxString
location = wxString::Format( wxT(
"VIACODE -> %s" ),
Name );
886 for( ; cNode; cNode = cNode->
GetNext() )
888 wxString cNodeName = cNode->GetName();
892 Shape.Parse( cNode, aContext );
894 else if( cNodeName == wxT(
"CLEARANCE" ) )
898 else if( cNodeName == wxT(
"RELIEFWIDTH" ) )
902 else if( cNodeName == wxT(
"DRILL" ) )
907 for( ; subNode; subNode = subNode->
GetNext() )
909 wxString subNodeName = subNode->GetName();
911 if( subNodeName == wxT(
"OVERSIZE" ) )
917 else if( cNodeName == wxT(
"VIAREASSIGN" ) )
920 reassign.
Parse( cNode, aContext );
935 wxASSERT( aNode->GetName() == wxT(
"LAYERPAIR" ) );
943 wxString
location = wxString::Format( wxT(
"LAYERPAIR -> %s" ),
Name );
947 if( aNode->
GetChildren()->GetName() == wxT(
"VIACODEREF" ) )
963 wxASSERT( aNode->GetName() == wxT(
"SPCCLASSSPACE" ) );
974 wxASSERT( aNode->GetName() == wxT(
"TECHNOLOGY" ) );
978 for( ; cNode; cNode = cNode->
GetNext() )
980 wxString cNodeName = cNode->GetName();
985 else if( cNodeName == wxT(
"MINROUTEWIDTH" ) )
989 else if( cNodeName == wxT(
"MINNECKED" ) )
993 else if( cNodeName == wxT(
"MINUNNECKED" ) )
997 else if( cNodeName == wxT(
"MINMITER" ) )
1001 else if( cNodeName == wxT(
"MAXMITER" ) )
1005 else if( cNodeName == wxT(
"MAXPHYSLAYER" ) )
1009 else if( cNodeName == wxT(
"TRACKGRID" ) )
1013 else if( cNodeName == wxT(
"VIAGRID" ) )
1017 else if( cNodeName == wxT(
"BACKOFFJCTS" ) )
1021 else if( cNodeName == wxT(
"BCKOFFWIDCHANGE" ) )
1034 const wxString& aPadSideString )
1036 if( aPadSideString == wxT(
"THRU" ) )
1038 else if( aPadSideString == wxT(
"BOTTOM" ) )
1040 else if( aPadSideString == wxT(
"TOP" ) )
1049 wxASSERT( aNode->GetName() == wxT(
"COMPCOPPER" ) );
1055 bool shapeIsInitialised =
false;
1056 wxString
location = wxT(
"COMPCOPPER" );
1061 for( ; cNode; cNode = cNode->
GetNext() )
1063 wxString cNodeName = cNode->GetName();
1065 if( !shapeIsInitialised &&
Shape.IsShape( cNode ) )
1067 Shape.Parse( cNode, aContext );
1068 shapeIsInitialised =
true;
1070 else if( cNodeName == wxT(
"SWAPRULE" ) )
1074 else if( cNodeName == wxT(
"ASSOCPIN" ) )
1076 wxXmlAttribute* xmlAttribute = cNode->GetAttributes();
1078 for( ; xmlAttribute; xmlAttribute = xmlAttribute->GetNext() )
1085 if( !xmlAttribute->GetValue().ToLong( &padId ) )
1103 wxASSERT( aNode->GetName() == wxT(
"COMPAREA" ) );
1110 bool shapeIsInitialised =
false;
1111 wxString
location = wxString::Format( wxT(
"COMPAREA %s" ),
ID );
1116 for( ; cNode; cNode = cNode->
GetNext() )
1118 wxString cNodeName = cNode->GetName();
1120 if( !shapeIsInitialised && SHAPE::IsShape( cNode ) )
1122 Shape.Parse( cNode, aContext );
1123 shapeIsInitialised =
true;
1125 else if( cNodeName == wxT(
"SWAPRULE" ) )
1129 else if( cNodeName == wxT(
"USAGE" ) )
1131 wxXmlAttribute* xmlAttribute = cNode->GetAttributes();
1133 for( ; xmlAttribute; xmlAttribute = xmlAttribute->GetNext() )
1138 if( xmlAttribute->GetValue() == wxT(
"NO_TRACKS" ) )
1140 else if( xmlAttribute->GetValue() == wxT(
"NO_VIAS" ) )
1158 wxASSERT( aNode->GetName() == wxT(
"EXITS" ) );
1160 wxXmlAttribute* xmlAttribute = aNode->GetAttributes();
1162 for( ; xmlAttribute; xmlAttribute = xmlAttribute->GetNext() )
1167 if( xmlAttribute->GetValue() == wxT(
"FREE" ) )
1169 else if( xmlAttribute->GetValue() == wxT(
"N" ) )
1171 else if( xmlAttribute->GetValue() == wxT(
"S" ) )
1173 else if( xmlAttribute->GetValue() == wxT(
"E" ) )
1175 else if( xmlAttribute->GetValue() == wxT(
"W" ) )
1177 else if( xmlAttribute->GetValue() == wxT(
"NE" ) )
1179 else if( xmlAttribute->GetValue() == wxT(
"NW" ) )
1181 else if( xmlAttribute->GetValue() == wxT(
"SE" ) )
1183 else if( xmlAttribute->GetValue() == wxT(
"SW" ) )
1195 wxASSERT( aNode->GetName() == wxT(
"PAD" ) );
1202 wxString
location = wxString::Format( wxT(
"PAD %ld" ),
ID );
1207 for( ; cNode; cNode = cNode->
GetNext() )
1209 wxString cNodeName = cNode->GetName();
1211 if( cNodeName == wxT(
"ORIENT" ) )
1213 else if( cNodeName == wxT(
"FIRSTPAD" ) )
1215 else if( cNodeName == wxT(
"EXITS" ) )
1216 Exits.Parse( cNode, aContext );
1217 else if( cNodeName == wxT(
"PADIDENTIFIER" ) )
1219 else if( cNodeName == wxT(
"PCBONLYPAD" ) )
1221 else if( cNodeName == wxT(
"PT" ) )
1231 wxASSERT( aNode->GetName() == wxT(
"DIMARROW" ) );
1232 bool arrowStyleInitialised =
false;
1233 bool upperAngleInitialised =
false;
1234 bool lowerAngleInitialised =
false;
1241 for( ; cNode; cNode = cNode->
GetNext() )
1243 wxString cNodeName = cNode->GetName();
1245 if( cNodeName == wxT(
"ARROWSTYLE" ) )
1248 arrowStyleInitialised =
true;
1250 if( arrowStyleStr == wxT(
"DIMENSION_ARROWOPEN" ) )
1252 else if( arrowStyleStr == wxT(
"DIMENSION_ARROWCLOSED" ) )
1254 else if( arrowStyleStr == wxT(
"DIMENSION_ARROWCLEAR" ) )
1256 else if( arrowStyleStr == wxT(
"DIMENSION_ARROWCLOSEDFILLED" ) )
1261 else if( cNodeName == wxT(
"ARROWANGLEA" ) )
1264 upperAngleInitialised =
true;
1266 else if( cNodeName == wxT(
"ARROWANGLEB" ) )
1269 lowerAngleInitialised =
true;
1277 if( !arrowStyleInitialised )
1280 if( !upperAngleInitialised )
1283 if( !lowerAngleInitialised )
1291 wxASSERT( aNode->GetName() == wxT(
"DIMTEXT" ) );
1304 if( cNode->GetName() != wxT(
"TXTSTYLE" ) )
1312 if( styleStr == wxT(
"DIMENSION_INTERNAL" ) )
1314 else if( styleStr == wxT(
"DIMENSION_EXTERNAL" ) )
1326 wxASSERT( aNode->GetName() == wxT(
"EXTLINE" ) );
1335 for( ; cNode; cNode = cNode->
GetNext() )
1337 wxString cNodeName = cNode->GetName();
1339 if( noOfPoints < 2 && cNodeName == wxT(
"PT" ) )
1343 if( noOfPoints == 1 )
1344 Start.Parse( cNode, aContext );
1346 End.Parse( cNode, aContext );
1348 else if( cNodeName == wxT(
"SUPPRESSFIRST" ) )
1358 if( noOfPoints != 2 )
1365 if( aNode->GetName() == wxT(
"LEADERLINE" ) || aNode->GetName() == wxT(
"LINEARLINE" )
1366 || aNode->GetName() == wxT(
"ANGULARLINE" ) )
1379 wxASSERT(
IsLine( aNode ) );
1381 if( aNode->GetName() == wxT(
"LINEARLINE" ) )
1382 Type = TYPE::LINEARLINE;
1383 else if( aNode->GetName() == wxT(
"LEADERLINE" ) )
1384 Type = TYPE::LEADERLINE;
1385 else if( aNode->GetName() == wxT(
"ANGULARLINE" ) )
1386 Type = TYPE::ANGULARLINE;
1388 wxASSERT_MSG(
true, wxT(
"Not a valid type. What happened to the node Name?" ) );
1392 if(
Type == TYPE::LEADERLINE )
1400 int requiredNoOfPoints = 2;
1402 if(
Type == TYPE::ANGULARLINE )
1403 requiredNoOfPoints = 3;
1405 for( ; cNode; cNode = cNode->
GetNext() )
1407 wxString cNodeName = cNode->GetName();
1409 if( cNodeName == wxT(
"DIMLINETYPE" ) )
1413 if( styleStr == wxT(
"DIMENSION_INTERNAL" ) )
1415 else if( styleStr == wxT(
"DIMENSION_EXTERNAL" ) )
1420 else if( noOfPoints < requiredNoOfPoints && cNodeName == wxT(
"PT" ) )
1424 if( noOfPoints == 1 )
1425 Start.Parse( cNode, aContext );
1426 else if( noOfPoints == 2 )
1427 End.Parse( cNode, aContext );
1429 Centre.Parse( cNode, aContext );
1431 else if(
Type == TYPE::LEADERLINE && cNodeName == wxT(
"LEADERANG" ) )
1441 if( noOfPoints != requiredNoOfPoints )
1448 if( aNode->GetName() == wxT(
"LINEARDIM" ) || aNode->GetName() == wxT(
"LEADERDIM" )
1449 || aNode->GetName() == wxT(
"ANGLEDIM" ) )
1464 std::map<wxString, TYPE> typeMap = { { wxT(
"LINEARDIM" ), TYPE::LINEARDIM },
1465 { wxT(
"LEADERDIM" ), TYPE::LEADERDIM }, { wxT(
"ANGLEDIM" ), TYPE::ANGLEDIM } };
1468 wxASSERT_MSG( typeMap.find( aNode->GetName() ) != typeMap.end(),
1469 wxT(
"Not a valid type. What happened to the node Name?" ) );
1471 Type = typeMap[aNode->GetName()];
1475 std::map<wxString, SUBTYPE> subTypeMap = {
1483 if( subTypeMap.find( subTypeStr ) == subTypeMap.end() )
1490 Subtype = subTypeMap[subTypeStr];
1496 bool idParsed =
false;
1497 bool unitsParsed =
false;
1498 bool arrowParsed =
false;
1499 bool textFormatParsed =
false;
1500 bool extLineParsed =
false;
1501 bool lineParsed =
false;
1502 bool textParsed =
false;
1504 for( ; cNode; cNode = cNode->
GetNext() )
1506 wxString cNodeName = cNode->GetName();
1508 if( !idParsed && cNodeName == wxT(
"DIMREF" ) )
1513 else if( !unitsParsed && cNodeName == wxT(
"UNITS" ) )
1518 else if( !unitsParsed && cNodeName == wxT(
"ANGUNITS" ) )
1523 else if( !arrowParsed && cNodeName == wxT(
"DIMARROW" ) )
1525 Arrow.Parse( cNode, aContext );
1528 else if( !textFormatParsed && cNodeName == wxT(
"DIMTEXT" ) )
1531 textFormatParsed =
true;
1533 else if( !extLineParsed && cNodeName == wxT(
"EXTLINE" ) )
1536 extLineParsed =
true;
1540 Line.Parse( cNode, aContext );
1543 else if( !textParsed && cNodeName == wxT(
"TEXT" ) )
1546 Text.Parse( cNode, aContext,
false );
1549 else if( cNodeName == wxT(
"FIX" ) )
1553 else if( cNodeName == wxT(
"GROUPREF" ) )
1557 else if( cNodeName == wxT(
"REUSEBLOCKREF" ) )
1571 wxASSERT( aNode->GetName() == wxT(
"SYMDEF" ) );
1579 else if(
ReferenceName.StartsWith( wxT(
"STARPOINTNF" ), &rest ) )
1588 for( ; cNode; cNode = cNode->
GetNext() )
1590 wxString cNodeName = cNode->GetName();
1596 else if( cNodeName == wxT(
"SYMHEIGHT" ) )
1600 else if( cNodeName == wxT(
"COMPCOPPER" ) )
1603 compcopper.
Parse( cNode, aContext );
1606 else if( cNodeName == wxT(
"COMPAREA" ) )
1609 area.
Parse( cNode, aContext );
1612 else if( cNodeName == wxT(
"PAD" ) )
1615 pad.Parse( cNode, aContext );
1618 else if( cNodeName == wxT(
"DIMENSIONS" ) )
1622 for( ; dimensionNode; dimensionNode = dimensionNode->
GetNext() )
1627 dim.
Parse( dimensionNode, aContext );
1649 wxASSERT( aNode->GetName() == wxT(
"LIBRARY" ) );
1653 for( ; cNode; cNode = cNode->
GetNext() )
1655 wxString cNodeName = cNode->GetName();
1657 if( cNodeName == wxT(
"SYMDEF" ) )
1660 symdef.
Parse( cNode, aContext );
1663 else if( cNodeName == wxT(
"HIERARCHY" ) )
1683 wxASSERT( aNode->GetName() == wxT(
"BOARD" ) );
1689 bool shapeIsInitialised =
false;
1690 wxString
location = wxString::Format( wxT(
"BOARD %s" ),
ID );
1695 for( ; cNode; cNode = cNode->
GetNext() )
1697 wxString cNodeName = cNode->GetName();
1699 if( !shapeIsInitialised && SHAPE::IsShape( cNode ) )
1701 Shape.Parse( cNode, aContext );
1702 shapeIsInitialised =
true;
1704 else if( cNodeName == wxT(
"ATTR" ) )
1707 attr.
Parse( cNode, aContext );
1710 else if( cNodeName == wxT(
"FIX" ) )
1714 else if( cNodeName == wxT(
"GROUPREF" ) )
1718 else if( cNodeName == wxT(
"REUSEBLOCKREF" ) )
1732 wxASSERT( aNode->GetName() == wxT(
"AREA" ) );
1740 bool shapeIsInitialised =
false;
1741 wxString
location = wxString::Format( wxT(
"AREA %s" ),
ID );
1746 for( ; cNode; cNode = cNode->
GetNext() )
1748 wxString cNodeName = cNode->GetName();
1750 if( !shapeIsInitialised && SHAPE::IsShape( cNode ) )
1752 Shape.Parse( cNode, aContext );
1753 shapeIsInitialised =
true;
1755 else if( cNodeName == wxT(
"FIX" ) )
1759 else if( cNodeName == wxT(
"USAGE" ) )
1761 wxXmlAttribute* xmlAttribute = cNode->GetAttributes();
1763 for( ; xmlAttribute; xmlAttribute = xmlAttribute->GetNext() )
1768 if( xmlAttribute->GetValue() == wxT(
"PLACEMENT" ) )
1770 else if( xmlAttribute->GetValue() == wxT(
"ROUTING" ) )
1772 else if( xmlAttribute->GetValue() == wxT(
"KEEPOUT" ) )
1774 else if( xmlAttribute->GetValue() == wxT(
"NO_TRACKS" ) )
1776 else if( xmlAttribute->GetValue() == wxT(
"NO_VIAS" ) )
1784 else if( cNodeName == wxT(
"AREAHEIGHT" ) )
1788 else if( cNodeName == wxT(
"GROUPREF" ) )
1792 else if( cNodeName == wxT(
"REUSEBLOCKREF" ) )
1796 else if( cNodeName == wxT(
"ATTR" ) )
1799 attr.
Parse( cNode, aContext );
1812 wxASSERT( aNode->GetName() == wxT(
"PINATTR" ) );
1818 for( ; cNode; cNode = cNode->
GetNext() )
1820 wxString cNodeName = cNode->GetName();
1822 if( cNodeName == wxT(
"ATTR" ) )
1825 attrVal.
Parse( cNode, aContext );
1828 else if( cNodeName == wxT(
"TESTLAND" ) )
1842 wxASSERT( aNode->GetName() == wxT(
"PADEXCEPTION" ) );
1848 for( ; cNode; cNode = cNode->
GetNext() )
1850 wxString cNodeName = cNode->GetName();
1852 if( cNodeName == wxT(
"PADCODEREF" ) )
1856 else if( cNodeName == wxT(
"EXITS" ) )
1859 Exits.Parse( cNode, aContext );
1861 else if( cNodeName == wxT(
"SIDE" ) )
1866 else if( cNodeName == wxT(
"ORIENT" ) )
1881 wxASSERT( aNode->GetName() == wxT(
"COMP" ) );
1889 bool originParsed =
false;
1891 for( ; cNode; cNode = cNode->
GetNext() )
1893 wxString cNodeName = cNode->GetName();
1895 if( !originParsed && cNodeName == wxT(
"PT" ) )
1897 Origin.Parse( cNode, aContext );
1898 originParsed =
true;
1900 else if( cNodeName == wxT(
"GROUPREF" ) )
1904 else if( cNodeName == wxT(
"REUSEBLOCKREF" ) )
1908 else if( cNodeName == wxT(
"TESTPOINT" ) )
1912 else if( cNodeName == wxT(
"FIX" ) )
1916 else if( cNodeName == wxT(
"MIRROR" ) )
1920 else if( cNodeName == wxT(
"READABILITY" ) )
1924 else if( cNodeName == wxT(
"ORIENT" ) )
1928 else if( cNodeName == wxT(
"VCOMPMASTER" ) )
1933 else if( cNodeName == wxT(
"TEXTLOC" ) )
1936 textloc.
Parse( cNode, aContext );
1939 else if( cNodeName == wxT(
"ATTR" ) )
1942 attrVal.
Parse( cNode, aContext );
1945 else if( cNodeName == wxT(
"PINATTR" ) )
1948 pinAttr.
Parse( cNode, aContext );
1951 else if( cNodeName == wxT(
"COMPPINLABEL" ) )
1955 PinLabels.insert( std::make_pair( pinID, pinLabel ) );
1957 else if( cNodeName == wxT(
"PADEXCEPTION" ) )
1960 padExcept.
Parse( cNode, aContext );
1977 wxASSERT( aNode->GetName() == wxT(
"TESTLAND" ) );
1981 if( side == wxT(
"MIN_SIDE" ) )
1983 else if( side == wxT(
"MAX_SIDE" ) )
1985 else if( side == wxT(
"BOTH_SIDES" ) )
1996 wxASSERT( aNode->GetName() == wxT(
"TRUNK" ) );
2005 wxASSERT( aNode->GetName() == wxT(
"PIN" ) );
2020 for( ; cNode; cNode = cNode->
GetNext() )
2024 else if( cNode->GetName() == wxT(
"TRUNKREF" ) )
2034 wxASSERT( aNode->GetName() == wxT(
"VIA" ) );
2042 for( ; cNode; cNode = cNode->
GetNext() )
2044 wxString cNodeName = cNode->GetName();
2046 if( cNodeName == wxT(
"PT" ) )
2048 else if( cNodeName == wxT(
"FIX" ) )
2050 else if( cNodeName == wxT(
"GROUPREF" ) )
2052 else if( cNodeName == wxT(
"REUSEBLOCKREF" ) )
2054 else if( cNodeName == wxT(
"TESTLAND" ) )
2056 else if( cNode->GetName() == wxT(
"TRUNKREF" ) )
2067 wxASSERT( aNode->GetName() == wxT(
"COPTERM" ) );
2078 XNODE* prevNode = aNode;
2080 bool vertexParsed =
false;
2082 if( aNode->GetName() == wxT(
"ROUTEWIDTH" ) )
2090 wxASSERT( VERTEX::IsVertex( aNode ) );
2092 Vertex.Parse( aNode, aContext );
2093 vertexParsed =
true;
2096 for( ; nextNode; nextNode = nextNode->
GetNext() )
2098 if( nextNode->GetName() == wxT(
"FIX" ) )
2102 else if( nextNode->GetName() == wxT(
"TDROPATSTART" ) )
2107 else if( nextNode->GetName() == wxT(
"TDROPATEND" ) )
2112 else if( VERTEX::IsVertex( nextNode ) )
2119 Vertex.Parse( nextNode, aContext );
2120 vertexParsed =
true;
2122 else if( nextNode->GetName() == wxT(
"ROUTEWIDTH" ) )
2131 prevNode = nextNode;
2140 wxASSERT( aNode->GetName() == wxT(
"ROUTE" ) );
2146 bool startPointParsed =
false;
2148 for( ; cNode; cNode = cNode->
GetNext() )
2150 wxString cNodeName = cNode->GetName();
2152 if( !startPointParsed && cNodeName == wxT(
"PT" ) )
2154 startPointParsed =
true;
2157 else if( cNodeName == wxT(
"ROUTEWIDTH" ) || VERTEX::IsVertex( cNode ) )
2163 cNode = rtVert.
Parse( cNode, aContext );
2166 assert( cNode !=
nullptr );
2183 bool routeParsed =
false;
2185 for( ; cNode; cNode = cNode->
GetNext() )
2187 wxString cNodeName = cNode->GetName();
2193 else if( !
Unrouted && !routeParsed && cNodeName == wxT(
"ROUTE" ) )
2195 Route.Parse( cNode, aContext );
2198 else if( !routeParsed && cNodeName == wxT(
"UNROUTE" ) )
2203 else if( cNode->GetName() == wxT(
"TRUNKREF" ) )
2222 for( ; cNode; cNode = cNode->
GetNext() )
2224 wxString cNodeName = cNode->GetName();
2226 if( cNodeName == wxT(
"JPT" ) )
2229 jpt.
Parse( cNode, aContext );
2230 Junctions.insert( std::make_pair( jpt.
ID, jpt ) );
2236 else if( cNodeName == wxT(
"PIN" ) )
2239 pin.Parse( cNode, aContext );
2240 Pins.insert( std::make_pair(
pin.ID,
pin ) );
2242 else if( cNodeName == wxT(
"VIA" ) )
2245 via.Parse( cNode, aContext );
2246 Vias.insert( std::make_pair(
via.ID,
via ) );
2248 else if( cNodeName == wxT(
"COPTERM" ) )
2251 cterm.
Parse( cNode, aContext );
2254 else if( cNodeName == wxT(
"CONN" ) )
2257 conn.
Parse( cNode, aContext );
2270 wxASSERT( aNode->GetName() == wxT(
"POURING" ) );
2282 if( MinIsolCopStr == wxT(
"NONE" ) )
2289 if( MinDisjCopStr == wxT(
"NONE" ) )
2296 for( ; cNode; cNode = cNode->
GetNext() )
2298 wxString cNodeName = cNode->GetName();
2300 if( cNodeName == wxT(
"NOPINRELIEF" ) )
2304 else if( cNodeName == wxT(
"NOVIARELIEF" ) )
2308 else if( cNodeName == wxT(
"IGNORETRN" ) )
2312 else if( cNodeName == wxT(
"BOXPINS" ) )
2316 else if( cNodeName == wxT(
"REGENERATE" ) )
2320 else if( cNodeName == wxT(
"AUTOROUTETARGET" ) )
2324 else if( cNodeName == wxT(
"THERMALCUTOUT" ) )
2328 else if( cNodeName == wxT(
"FILLED" ) )
2332 else if( cNodeName == wxT(
"HATCHCODEREF" ) )
2347 wxASSERT( aNode->GetName() == wxT(
"TEMPLATE" ) );
2356 bool shapeParsed =
false;
2357 bool pouringParsed =
false;
2359 for( ; cNode; cNode = cNode->
GetNext() )
2361 wxString cNodeName = cNode->GetName();
2363 if( !shapeParsed && SHAPE::IsShape( cNode ) )
2365 Shape.Parse( cNode, aContext );
2368 else if( !pouringParsed && cNodeName == wxT(
"POURING" ) )
2370 Pouring.Parse( cNode, aContext );
2371 pouringParsed =
true;
2373 else if( cNodeName == wxT(
"FIX" ) )
2377 else if( cNodeName == wxT(
"GROUPREF" ) )
2381 else if( cNodeName == wxT(
"REUSEBLOCKREF" ) )
2385 else if( cNodeName == wxT(
"ATTR" ) )
2388 attr.
Parse( cNode, aContext );
2402 wxASSERT( aNode->GetName() == wxT(
"TERM" ) );
2407 bool locationParsed =
false;
2409 for( ; cNode; cNode = cNode->
GetNext() )
2411 wxString cNodeName = cNode->GetName();
2413 if( !locationParsed && cNodeName == wxT(
"PT" ) )
2416 locationParsed =
true;
2418 else if( cNodeName == wxT(
"FIX" ) )
2432 wxASSERT( aNode->GetName() == wxT(
"NETREF" ) );
2438 for( ; cNode; cNode = cNode->
GetNext() )
2440 wxString cNodeName = cNode->GetName();
2442 if( cNodeName == wxT(
"TERM" ) )
2445 term.
Parse( cNode, aContext );
2448 else if( cNodeName == wxT(
"FIX" ) )
2462 wxASSERT( aNode->GetName() == wxT(
"COPPER" ) );
2469 bool shapeParsed =
false;
2470 bool netRefParsed =
false;
2472 for( ; cNode; cNode = cNode->
GetNext() )
2474 wxString cNodeName = cNode->GetName();
2476 if( !shapeParsed && SHAPE::IsShape( cNode ) )
2478 Shape.Parse( cNode, aContext );
2481 else if( !netRefParsed && cNodeName == wxT(
"NETREF" ) )
2483 NetRef.Parse( cNode, aContext );
2484 netRefParsed =
true;
2486 else if( cNodeName == wxT(
"FIX" ) )
2490 else if( cNodeName == wxT(
"GROUPREF" ) )
2494 else if( cNodeName == wxT(
"REUSEBLOCKREF" ) )
2498 else if( cNodeName == wxT(
"POURED" ) )
2502 else if( cNodeName == wxT(
"ATTR" ) )
2505 attr.
Parse( cNode, aContext );
2518 wxASSERT( aNode->GetName() == wxT(
"DRILLTABLE" ) );
2524 bool positionParsed =
false;
2526 for( ; cNode; cNode = cNode->
GetNext() )
2528 wxString cNodeName = cNode->GetName();
2530 if( !positionParsed && cNodeName == wxT(
"PT" ) )
2533 positionParsed =
true;
2535 else if( cNodeName == wxT(
"ORIENT" ) )
2539 else if( cNodeName == wxT(
"MIRROR" ) )
2543 else if( cNodeName == wxT(
"FIX" ) )
2547 else if( cNodeName == wxT(
"READABILITY" ) )
2551 else if( cNodeName == wxT(
"GROUPREF" ) )
2555 else if( cNodeName == wxT(
"REUSEBLOCKREF" ) )
2569 wxASSERT( aNode->GetName() == wxT(
"LAYOUT" ) );
2572 bool netSynchParsed =
false;
2573 bool dimensionsParsed =
false;
2575 for( ; cNode; cNode = cNode->
GetNext() )
2577 wxString cNodeName = cNode->GetName();
2579 if( !netSynchParsed && cNodeName == wxT(
"NETSYNCH" ) )
2581 std::map<wxString, NETSYNCH> netSynchMap = { { wxT(
"WARNING" ),
NETSYNCH::WARNING },
2586 if( netSynchMap.find( nsString ) == netSynchMap.end() )
2595 netSynchParsed =
true;
2597 else if( cNodeName == wxT(
"GROUP" ) )
2600 group.Parse( cNode, aContext );
2603 else if( cNodeName == wxT(
"REUSEBLOCK" ) )
2606 reuseblock.
Parse( cNode, aContext );
2607 ReuseBlocks.insert( std::make_pair( reuseblock.
ID, reuseblock ) );
2609 else if( cNodeName == wxT(
"BOARD" ) )
2612 board.
Parse( cNode, aContext );
2613 Boards.insert( std::make_pair( board.
ID, board ) );
2615 else if( cNodeName == wxT(
"FIGURE" ) )
2618 figure.
Parse( cNode, aContext );
2619 Figures.insert( std::make_pair( figure.
ID, figure ) );
2621 else if( cNodeName == wxT(
"AREA" ) )
2624 area.
Parse( cNode, aContext );
2625 Areas.insert( std::make_pair( area.
ID, area ) );
2627 else if( cNodeName == wxT(
"COMP" ) )
2630 comp.Parse( cNode, aContext );
2633 else if( cNodeName == wxT(
"TRUNK" ) )
2636 trunk.
Parse( cNode, aContext );
2637 Trunks.insert( std::make_pair( trunk.
ID, trunk ) );
2639 else if( cNodeName == wxT(
"NET" ) )
2642 net.
Parse( cNode, aContext );
2643 Nets.insert( std::make_pair( net.
ID, net ) );
2645 else if( cNodeName == wxT(
"TEMPLATE" ) )
2648 temp.
Parse( cNode, aContext );
2649 Templates.insert( std::make_pair( temp.
ID, temp ) );
2651 else if( cNodeName == wxT(
"COPPER" ) )
2654 copper.
Parse( cNode, aContext );
2655 Coppers.insert( std::make_pair( copper.
ID, copper ) );
2657 else if( cNodeName == wxT(
"TEXT" ) )
2660 txt.
Parse( cNode, aContext );
2661 Texts.insert( std::make_pair( txt.
ID, txt ) );
2663 else if( cNodeName == wxT(
"DOCSYMBOL" ) )
2666 docsym.
Parse( cNode, aContext );
2669 else if( !dimensionsParsed && cNodeName == wxT(
"DIMENSIONS" ) )
2673 for( ; dimensionNode; dimensionNode = dimensionNode->
GetNext() )
2678 dim.
Parse( dimensionNode, aContext );
2687 dimensionsParsed =
true;
2689 else if( cNodeName == wxT(
"DRILLTABLE" ) )
2692 drilltable.
Parse( cNode, aContext );
2693 DrillTables.insert( std::make_pair( drilltable.
ID, drilltable ) );
2695 else if( cNodeName == wxT(
"VHIERARCHY" ) )
2699 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