30#include <wx/translation.h>
44 std::vector<wxString> subNodeChildrenToCount = { wxT(
"LIBRARY" ), wxT(
"PARTS" ),
58 for( ; cNode; cNode = cNode->
GetNext() )
60 if( cNode->GetName() == wxT(
"HEADER" ) )
64 switch(
Header.Resolution )
71 wxASSERT_MSG(
true, wxT(
"Unknown File Resolution" ) );
75 if( aLibrary &&
Header.Format.Type != wxT(
"LIBRARY" ) )
77 THROW_IO_ERROR( wxT(
"The selected file is not a valid CADSTAR library file." ) );
79 else if( !aLibrary &&
Header.Format.Type != wxT(
"LAYOUT" ) )
81 if(
Header.Format.Type == wxT(
"LIBRARY" ) )
84 wxT(
"The selected file is a CADSTAR library file (as opposed "
85 "to a layout file). You can import this library by adding it "
86 "to the library table." ) );
90 THROW_IO_ERROR( wxT(
"The selected file is an unknown CADSTAR format so "
91 "cannot be imported into KiCad." ) );
95 else if( cNode->GetName() == wxT(
"ASSIGNMENTS" ) )
99 else if( cNode->GetName() == wxT(
"LIBRARY" ) )
103 else if( cNode->GetName() == wxT(
"DEFAULTS" ) )
109 else if( cNode->GetName() == wxT(
"PARTS" ) )
113 else if( cNode->GetName() == wxT(
"LAYOUT" ) )
117 else if( cNode->GetName() == wxT(
"DISPLAY" ) )
138 wxASSERT( aNode->GetName() == wxT(
"ASSIGNMENTS" ) );
145 for( ; cNode; cNode = cNode->
GetNext() )
147 if( cNode->GetName() == wxT(
"LAYERDEFS" ) )
149 else if( cNode->GetName() == wxT(
"CODEDEFS" ) )
151 else if( cNode->GetName() == wxT(
"TECHNOLOGY" ) )
153 else if( cNode->GetName() == wxT(
"GRIDS" ) )
154 Grids.Parse( cNode, aContext );
155 else if( cNode->GetName() == wxT(
"NETCLASSEDITATTRIBSETTINGS" ) )
157 else if( cNode->GetName() == wxT(
"SPCCLASSEDITATTRIBSETTINGS" ) )
167 wxASSERT( aNode->GetName() == wxT(
"LAYERDEFS" ) );
169 wxXmlAttribute* xmlAttribute =
nullptr;
176 for( ; cNode; cNode = cNode->
GetNext() )
178 wxString nodeName = cNode->GetName();
180 if( nodeName == wxT(
"LAYERSTACK" ) )
182 xmlAttribute = cNode->GetAttributes();
184 for( ; xmlAttribute; xmlAttribute = xmlAttribute->GetNext() )
194 else if( nodeName == wxT(
"MATERIAL" ) )
197 material.
Parse( cNode, aContext );
198 Materials.insert( std::make_pair( material.
ID, material ) );
200 else if( nodeName == wxT(
"LAYER" ) )
203 layer.
Parse( cNode, aContext );
204 Layers.insert( std::make_pair( layer.
ID, layer ) );
206 else if( nodeName == wxT(
"SWAPPAIR" ) )
211 Layers[layerId].SwapLayerID = swapLayerId;
223 wxASSERT( aNode->GetName() == wxT(
"RULESET" ) );
230 for( ; cNode; cNode = cNode->
GetNext() )
232 wxString nodeName = cNode->GetName();
234 if( nodeName == wxT(
"ROUCODEREF" ) )
238 else if( nodeName == wxT(
"VIACODEREF" ) )
242 else if( nodeName == wxT(
"SPACINGCODE" ) )
245 spacingcode.
Parse( cNode, aContext );
246 SpacingCodes.insert( std::make_pair( spacingcode.
ID, spacingcode ) );
258 wxASSERT( aNode->GetName() == wxT(
"CODEDEFS" ) );
262 for( ; cNode; cNode = cNode->
GetNext() )
264 wxString nodeName = cNode->GetName();
269 else if( nodeName == wxT(
"COPPERCODE" ) )
272 coppercode.
Parse( cNode, aContext );
273 CopperCodes.insert( std::make_pair( coppercode.
ID, coppercode ) );
275 else if( nodeName == wxT(
"SPACINGCODE" ) )
278 spacingcode.
Parse( cNode, aContext );
279 SpacingCodes.insert( std::make_pair( spacingcode.
ID, spacingcode ) );
281 else if( nodeName == wxT(
"RULESET" ) )
284 ruleset.
Parse( cNode, aContext );
285 Rulesets.insert( std::make_pair( ruleset.
ID, ruleset ) );
287 else if( nodeName == wxT(
"PADCODE" ) )
290 padcode.
Parse( cNode, aContext );
291 PadCodes.insert( std::make_pair( padcode.
ID, padcode ) );
293 else if( nodeName == wxT(
"VIACODE" ) )
296 viacode.
Parse( cNode, aContext );
297 ViaCodes.insert( std::make_pair( viacode.
ID, viacode ) );
299 else if( nodeName == wxT(
"LAYERPAIR" ) )
302 layerpair.
Parse( cNode, aContext );
303 LayerPairs.insert( std::make_pair( layerpair.
ID, layerpair ) );
305 else if( nodeName == wxT(
"SPCCLASSSPACE" ) )
308 spcclassspace.
Parse( cNode, aContext );
321 wxASSERT( aNode->GetName() == wxT(
"MATERIAL" ) );
328 if( sType == wxT(
"CONSTRUCTION" ) )
332 else if( sType == wxT(
"ELECTRICAL" ) )
336 else if( sType == wxT(
"NONELEC" ) )
350 wxString::Format( wxT(
"MATERIAL %s" ),
Name ) );
353 for( ; iNode; iNode = iNode->
GetNext() )
355 wxString nodeName = iNode->GetName();
357 if( nodeName == wxT(
"RELPERMIT" ) )
361 else if( nodeName == wxT(
"LOSSTANGENT" ) )
365 else if( nodeName == wxT(
"RESISTIVITY" ) )
379 wxASSERT( aNode->GetName() == wxT(
"LAYER" ) );
385 auto processLayerMaterialDetails = [&]() {
387 for( ; tempNode; tempNode = tempNode->
GetNext() )
389 wxString tempNodeName = tempNode->GetName();
391 if( tempNodeName == wxT(
"MAKE" ) || tempNodeName == wxT(
"LAYERHEIGHT" ) )
393 if( tempNodeName == wxT(
"LAYERHEIGHT" ) )
405 if( childOfTempNode )
407 if( childOfTempNode->GetName() == wxT(
"EMBEDS" ) )
411 if( embedsValue == wxT(
"UPWARDS" ) )
415 else if( embedsValue == wxT(
"DOWNWARDS" ) )
422 wxString::Format( wxT(
"LAYER %s -> EMBEDS" ),
429 wxString::Format( wxT(
"LAYER %s->MAKE" ),
434 else if( tempNodeName == wxT(
"BIAS" ) )
438 if( bias == wxT(
"X_BIASED" ) )
442 else if( bias == wxT(
"Y_BIASED" ) )
446 else if( bias == wxT(
"ANTITRACK" ) )
450 else if( bias == wxT(
"OBSTACLE" ) )
454 else if( bias == wxT(
"UNBIASED" ) )
461 wxString::Format( wxT(
"LAYER %s -> BIAS" ),
473 for( ; cNode; cNode = cNode->
GetNext() )
475 wxString cNodeName = cNode->GetName();
477 if( cNodeName == wxT(
"ALLDOC" ) )
481 else if( cNodeName == wxT(
"ALLELEC" ) )
485 else if( cNodeName == wxT(
"ALLLAYER" ) )
489 else if( cNodeName == wxT(
"ASSCOMPCOPP" ) )
493 else if( cNodeName == wxT(
"JUMPERLAYER" ) )
497 else if( cNodeName == wxT(
"NOLAYER" ) )
501 else if( cNodeName == wxT(
"POWER" ) )
505 processLayerMaterialDetails();
507 else if( cNodeName == wxT(
"DOC" ) )
511 else if( cNodeName == wxT(
"CONSTRUCTION" ) )
514 processLayerMaterialDetails();
516 else if( cNodeName == wxT(
"ELEC" ) )
520 processLayerMaterialDetails();
522 else if( cNodeName == wxT(
"NONELEC" ) )
526 processLayerMaterialDetails();
528 else if( cNodeName == wxT(
"DESCRIPTION" ) )
532 else if( cNodeName == wxT(
"REFPLANE" ) )
536 else if( cNodeName == wxT(
"VLAYER" ) )
540 else if( cNodeName == wxT(
"LASUBTYP" ) )
545 if( sSubType == wxT(
"LAYERSUBTYPE_ASSEMBLY" ) )
549 else if( sSubType == wxT(
"LAYERSUBTYPE_PASTE" ) )
553 else if( sSubType == wxT(
"LAYERSUBTYPE_PLACEMENT" ) )
557 else if( sSubType == wxT(
"LAYERSUBTYPE_SILKSCREEN" ) )
561 else if( sSubType == wxT(
"LAYERSUBTYPE_SOLDERRESIST" ) )
565 else if( sSubType == wxT(
"LAYERSUBTYPE_CLEARANCE" ) )
569 else if( sSubType == wxT(
"LAYERSUBTYPE_ROUT" ) )
589 wxASSERT( aNode->GetName() == wxT(
"COPREASSIGN" ) );
599 wxASSERT( aNode->GetName() == wxT(
"COPPERCODE" ) );
608 for( ; cNode; cNode = cNode->
GetNext() )
610 if( cNode->GetName() == wxT(
"COPREASSIGN" ) )
613 reassign.
Parse( cNode, aContext );
627 wxASSERT( aNode->GetName() == wxT(
"SPACEREASSIGN" ) );
638 wxASSERT( aNode->GetName() == wxT(
"SPACINGCODE" ) );
645 for( ; cNode; cNode = cNode->
GetNext() )
647 wxString cNodeName = cNode->GetName();
649 if( cNodeName == wxT(
"SPACEREASSIGN" ) )
652 reassign.
Parse( cNode, aContext );
665 wxString aNodeName = aNode->GetName();
667 if( aNodeName == wxT(
"ANNULUS" ) || aNodeName == wxT(
"BULLET" ) || aNodeName == wxT(
"ROUND" )
668 || aNodeName == wxT(
"DIAMOND" ) || aNodeName == wxT(
"FINGER" )
669 || aNodeName == wxT(
"OCTAGON" ) || aNodeName == wxT(
"RECTANGLE" )
670 || aNodeName == wxT(
"ROUNDED" ) || aNodeName == wxT(
"SQUARE" ) )
685 wxString aNodeName = aNode->GetName();
687 if( aNodeName == wxT(
"ANNULUS" ) )
689 else if( aNodeName == wxT(
"BULLET" ) )
691 else if( aNodeName == wxT(
"ROUND" ) )
693 else if( aNodeName == wxT(
"DIAMOND" ) )
695 else if( aNodeName == wxT(
"FINGER" ) )
697 else if( aNodeName == wxT(
"OCTAGON" ) )
699 else if( aNodeName == wxT(
"RECTANGLE" ) )
701 else if( aNodeName == wxT(
"ROUNDED" ) )
703 else if( aNodeName == wxT(
"SQUARE" ) )
731 if( aNode->
GetChildren()->GetName() == wxT(
"ORIENT" ) )
753 wxASSERT( aNode->GetName() == wxT(
"PADREASSIGN" ) );
768 wxASSERT( aNode->GetName() == wxT(
"PADCODE" ) );
774 wxString
location = wxString::Format( wxT(
"PADCODE -> %s" ),
Name );
776 for( ; cNode; cNode = cNode->
GetNext() )
778 wxString cNodeName = cNode->GetName();
782 Shape.Parse( cNode, aContext );
784 else if( cNodeName == wxT(
"CLEARANCE" ) )
788 else if( cNodeName == wxT(
"RELIEFWIDTH" ) )
792 else if( cNodeName == wxT(
"DRILL" ) )
797 for( ; subNode; subNode = subNode->
GetNext() )
799 wxString subNodeName = subNode->GetName();
801 if( subNodeName == wxT(
"NONPLATED" ) )
803 else if( subNodeName == wxT(
"OVERSIZE" ) )
809 else if( cNodeName == wxT(
"DRILLLENGTH" ) )
813 else if( cNodeName == wxT(
"DRILLORIENTATION" ) )
817 else if( cNodeName == wxT(
"DRILLXOFFSET" ) )
821 else if( cNodeName == wxT(
"DRILLYOFFSET" ) )
825 else if( cNodeName == wxT(
"PADREASSIGN" ) )
828 reassign.
Parse( cNode, aContext );
841 wxASSERT( aNode->GetName() == wxT(
"VIAREASSIGN" ) );
856 wxASSERT( aNode->GetName() == wxT(
"VIACODE" ) );
862 wxString
location = wxString::Format( wxT(
"VIACODE -> %s" ),
Name );
864 for( ; cNode; cNode = cNode->
GetNext() )
866 wxString cNodeName = cNode->GetName();
870 Shape.Parse( cNode, aContext );
872 else if( cNodeName == wxT(
"CLEARANCE" ) )
876 else if( cNodeName == wxT(
"RELIEFWIDTH" ) )
880 else if( cNodeName == wxT(
"DRILL" ) )
885 for( ; subNode; subNode = subNode->
GetNext() )
887 wxString subNodeName = subNode->GetName();
889 if( subNodeName == wxT(
"OVERSIZE" ) )
895 else if( cNodeName == wxT(
"VIAREASSIGN" ) )
898 reassign.
Parse( cNode, aContext );
911 wxASSERT( aNode->GetName() == wxT(
"LAYERPAIR" ) );
919 wxString
location = wxString::Format( wxT(
"LAYERPAIR -> %s" ),
Name );
923 if( aNode->
GetChildren()->GetName() == wxT(
"VIACODEREF" ) )
939 wxASSERT( aNode->GetName() == wxT(
"SPCCLASSSPACE" ) );
950 wxASSERT( aNode->GetName() == wxT(
"TECHNOLOGY" ) );
954 for( ; cNode; cNode = cNode->
GetNext() )
956 wxString cNodeName = cNode->GetName();
961 else if( cNodeName == wxT(
"MINROUTEWIDTH" ) )
965 else if( cNodeName == wxT(
"MINNECKED" ) )
969 else if( cNodeName == wxT(
"MINUNNECKED" ) )
973 else if( cNodeName == wxT(
"MINMITER" ) )
977 else if( cNodeName == wxT(
"MAXMITER" ) )
981 else if( cNodeName == wxT(
"MAXPHYSLAYER" ) )
985 else if( cNodeName == wxT(
"TRACKGRID" ) )
989 else if( cNodeName == wxT(
"VIAGRID" ) )
993 else if( cNodeName == wxT(
"BACKOFFJCTS" ) )
997 else if( cNodeName == wxT(
"BCKOFFWIDCHANGE" ) )
1010 const wxString& aPadSideString )
1012 if( aPadSideString == wxT(
"THRU" ) )
1014 else if( aPadSideString == wxT(
"BOTTOM" ) )
1016 else if( aPadSideString == wxT(
"TOP" ) )
1025 wxASSERT( aNode->GetName() == wxT(
"COMPCOPPER" ) );
1031 bool shapeIsInitialised =
false;
1032 wxString
location = wxT(
"COMPCOPPER" );
1037 for( ; cNode; cNode = cNode->
GetNext() )
1039 wxString cNodeName = cNode->GetName();
1041 if( !shapeIsInitialised &&
Shape.IsShape( cNode ) )
1043 Shape.Parse( cNode, aContext );
1044 shapeIsInitialised =
true;
1046 else if( cNodeName == wxT(
"SWAPRULE" ) )
1050 else if( cNodeName == wxT(
"ASSOCPIN" ) )
1052 wxXmlAttribute* xmlAttribute = cNode->GetAttributes();
1054 for( ; xmlAttribute; xmlAttribute = xmlAttribute->GetNext() )
1061 if( !xmlAttribute->GetValue().ToLong( &padId ) )
1079 wxASSERT( aNode->GetName() == wxT(
"COMPAREA" ) );
1086 bool shapeIsInitialised =
false;
1087 wxString
location = wxString::Format( wxT(
"COMPAREA %s" ),
ID );
1092 for( ; cNode; cNode = cNode->
GetNext() )
1094 wxString cNodeName = cNode->GetName();
1096 if( !shapeIsInitialised && SHAPE::IsShape( cNode ) )
1098 Shape.Parse( cNode, aContext );
1099 shapeIsInitialised =
true;
1101 else if( cNodeName == wxT(
"SWAPRULE" ) )
1105 else if( cNodeName == wxT(
"USAGE" ) )
1107 wxXmlAttribute* xmlAttribute = cNode->GetAttributes();
1109 for( ; xmlAttribute; xmlAttribute = xmlAttribute->GetNext() )
1114 if( xmlAttribute->GetValue() == wxT(
"NO_TRACKS" ) )
1116 else if( xmlAttribute->GetValue() == wxT(
"NO_VIAS" ) )
1134 wxASSERT( aNode->GetName() == wxT(
"EXITS" ) );
1136 wxXmlAttribute* xmlAttribute = aNode->GetAttributes();
1138 for( ; xmlAttribute; xmlAttribute = xmlAttribute->GetNext() )
1143 if( xmlAttribute->GetValue() == wxT(
"FREE" ) )
1145 else if( xmlAttribute->GetValue() == wxT(
"N" ) )
1147 else if( xmlAttribute->GetValue() == wxT(
"S" ) )
1149 else if( xmlAttribute->GetValue() == wxT(
"E" ) )
1151 else if( xmlAttribute->GetValue() == wxT(
"W" ) )
1153 else if( xmlAttribute->GetValue() == wxT(
"NE" ) )
1155 else if( xmlAttribute->GetValue() == wxT(
"NW" ) )
1157 else if( xmlAttribute->GetValue() == wxT(
"SE" ) )
1159 else if( xmlAttribute->GetValue() == wxT(
"SW" ) )
1171 wxASSERT( aNode->GetName() == wxT(
"PAD" ) );
1178 wxString
location = wxString::Format( wxT(
"PAD %ld" ),
ID );
1183 for( ; cNode; cNode = cNode->
GetNext() )
1185 wxString cNodeName = cNode->GetName();
1187 if( cNodeName == wxT(
"ORIENT" ) )
1189 else if( cNodeName == wxT(
"FIRSTPAD" ) )
1191 else if( cNodeName == wxT(
"EXITS" ) )
1192 Exits.Parse( cNode, aContext );
1193 else if( cNodeName == wxT(
"PADIDENTIFIER" ) )
1195 else if( cNodeName == wxT(
"PCBONLYPAD" ) )
1197 else if( cNodeName == wxT(
"PT" ) )
1207 wxASSERT( aNode->GetName() == wxT(
"DIMARROW" ) );
1208 bool arrowStyleInitialised =
false;
1209 bool upperAngleInitialised =
false;
1210 bool lowerAngleInitialised =
false;
1217 for( ; cNode; cNode = cNode->
GetNext() )
1219 wxString cNodeName = cNode->GetName();
1221 if( cNodeName == wxT(
"ARROWSTYLE" ) )
1224 arrowStyleInitialised =
true;
1226 if( arrowStyleStr == wxT(
"DIMENSION_ARROWOPEN" ) )
1228 else if( arrowStyleStr == wxT(
"DIMENSION_ARROWCLOSED" ) )
1230 else if( arrowStyleStr == wxT(
"DIMENSION_ARROWCLEAR" ) )
1232 else if( arrowStyleStr == wxT(
"DIMENSION_ARROWCLOSEDFILLED" ) )
1237 else if( cNodeName == wxT(
"ARROWANGLEA" ) )
1240 upperAngleInitialised =
true;
1242 else if( cNodeName == wxT(
"ARROWANGLEB" ) )
1245 lowerAngleInitialised =
true;
1253 if( !arrowStyleInitialised )
1256 if( !upperAngleInitialised )
1259 if( !lowerAngleInitialised )
1267 wxASSERT( aNode->GetName() == wxT(
"DIMTEXT" ) );
1274 if( !cNode || cNode->GetName() != wxT(
"TXTSTYLE" ) )
1279 if( styleStr == wxT(
"DIMENSION_INTERNAL" ) )
1281 else if( styleStr == wxT(
"DIMENSION_EXTERNAL" ) )
1293 wxASSERT( aNode->GetName() == wxT(
"EXTLINE" ) );
1302 for( ; cNode; cNode = cNode->
GetNext() )
1304 wxString cNodeName = cNode->GetName();
1306 if( noOfPoints < 2 && cNodeName == wxT(
"PT" ) )
1310 if( noOfPoints == 1 )
1311 Start.Parse( cNode, aContext );
1313 End.Parse( cNode, aContext );
1315 else if( cNodeName == wxT(
"SUPPRESSFIRST" ) )
1325 if( noOfPoints != 2 )
1332 if( aNode->GetName() == wxT(
"LEADERLINE" ) || aNode->GetName() == wxT(
"LINEARLINE" )
1333 || aNode->GetName() == wxT(
"ANGULARLINE" ) )
1346 wxASSERT(
IsLine( aNode ) );
1348 if( aNode->GetName() == wxT(
"LINEARLINE" ) )
1349 Type = TYPE::LINEARLINE;
1350 else if( aNode->GetName() == wxT(
"LEADERLINE" ) )
1351 Type = TYPE::LEADERLINE;
1352 else if( aNode->GetName() == wxT(
"ANGULARLINE" ) )
1353 Type = TYPE::ANGULARLINE;
1355 wxASSERT_MSG(
true, wxT(
"Not a valid type. What happened to the node Name?" ) );
1359 if(
Type == TYPE::LEADERLINE )
1367 int requiredNoOfPoints = 2;
1369 if(
Type == TYPE::ANGULARLINE )
1370 requiredNoOfPoints = 3;
1372 for( ; cNode; cNode = cNode->
GetNext() )
1374 wxString cNodeName = cNode->GetName();
1376 if( cNodeName == wxT(
"DIMLINETYPE" ) )
1380 if( styleStr == wxT(
"DIMENSION_INTERNAL" ) )
1382 else if( styleStr == wxT(
"DIMENSION_EXTERNAL" ) )
1387 else if( noOfPoints < requiredNoOfPoints && cNodeName == wxT(
"PT" ) )
1391 if( noOfPoints == 1 )
1392 Start.Parse( cNode, aContext );
1393 else if( noOfPoints == 2 )
1394 End.Parse( cNode, aContext );
1396 Centre.Parse( cNode, aContext );
1398 else if(
Type == TYPE::LEADERLINE && cNodeName == wxT(
"LEADERANG" ) )
1408 if( noOfPoints != requiredNoOfPoints )
1415 if( aNode->GetName() == wxT(
"LINEARDIM" ) || aNode->GetName() == wxT(
"LEADERDIM" )
1416 || aNode->GetName() == wxT(
"ANGLEDIM" ) )
1431 std::map<wxString, TYPE> typeMap = { { wxT(
"LINEARDIM" ), TYPE::LINEARDIM },
1432 { wxT(
"LEADERDIM" ), TYPE::LEADERDIM }, { wxT(
"ANGLEDIM" ), TYPE::ANGLEDIM } };
1435 wxASSERT_MSG( typeMap.find( aNode->GetName() ) != typeMap.end(),
1436 wxT(
"Not a valid type. What happened to the node Name?" ) );
1438 Type = typeMap[aNode->GetName()];
1442 std::map<wxString, SUBTYPE> subTypeMap = {
1450 if( subTypeMap.find( subTypeStr ) == subTypeMap.end() )
1453 Subtype = subTypeMap[subTypeStr];
1458 bool idParsed =
false;
1459 bool unitsParsed =
false;
1460 bool arrowParsed =
false;
1461 bool textFormatParsed =
false;
1462 bool extLineParsed =
false;
1463 bool lineParsed =
false;
1464 bool textParsed =
false;
1466 for( ; cNode; cNode = cNode->
GetNext() )
1468 wxString cNodeName = cNode->GetName();
1470 if( !idParsed && cNodeName == wxT(
"DIMREF" ) )
1475 else if( !unitsParsed && cNodeName == wxT(
"UNITS" ) )
1480 else if( !unitsParsed && cNodeName == wxT(
"ANGUNITS" ) )
1485 else if( !arrowParsed && cNodeName == wxT(
"DIMARROW" ) )
1487 Arrow.Parse( cNode, aContext );
1490 else if( !textFormatParsed && cNodeName == wxT(
"DIMTEXT" ) )
1493 textFormatParsed =
true;
1495 else if( !extLineParsed && cNodeName == wxT(
"EXTLINE" ) )
1498 extLineParsed =
true;
1502 Line.Parse( cNode, aContext );
1505 else if( !textParsed && cNodeName == wxT(
"TEXT" ) )
1508 Text.Parse( cNode, aContext,
false );
1511 else if( cNodeName == wxT(
"FIX" ) )
1515 else if( cNodeName == wxT(
"GROUPREF" ) )
1519 else if( cNodeName == wxT(
"REUSEBLOCKREF" ) )
1533 wxASSERT( aNode->GetName() == wxT(
"SYMDEF" ) );
1541 else if(
ReferenceName.StartsWith( wxT(
"STARPOINTNF" ), &rest ) )
1550 for( ; cNode; cNode = cNode->
GetNext() )
1552 wxString cNodeName = cNode->GetName();
1558 else if( cNodeName == wxT(
"SYMHEIGHT" ) )
1562 else if( cNodeName == wxT(
"COMPCOPPER" ) )
1565 compcopper.
Parse( cNode, aContext );
1568 else if( cNodeName == wxT(
"COMPAREA" ) )
1571 area.
Parse( cNode, aContext );
1574 else if( cNodeName == wxT(
"PAD" ) )
1577 pad.Parse( cNode, aContext );
1580 else if( cNodeName == wxT(
"DIMENSIONS" ) )
1584 for( ; dimensionNode; dimensionNode = dimensionNode->
GetNext() )
1589 dim.
Parse( dimensionNode, aContext );
1611 wxASSERT( aNode->GetName() == wxT(
"LIBRARY" ) );
1615 for( ; cNode; cNode = cNode->
GetNext() )
1617 wxString cNodeName = cNode->GetName();
1619 if( cNodeName == wxT(
"SYMDEF" ) )
1622 symdef.
Parse( cNode, aContext );
1625 else if( cNodeName == wxT(
"HIERARCHY" ) )
1645 wxASSERT( aNode->GetName() == wxT(
"BOARD" ) );
1651 bool shapeIsInitialised =
false;
1652 wxString
location = wxString::Format( wxT(
"BOARD %s" ),
ID );
1657 for( ; cNode; cNode = cNode->
GetNext() )
1659 wxString cNodeName = cNode->GetName();
1661 if( !shapeIsInitialised && SHAPE::IsShape( cNode ) )
1663 Shape.Parse( cNode, aContext );
1664 shapeIsInitialised =
true;
1666 else if( cNodeName == wxT(
"ATTR" ) )
1669 attr.
Parse( cNode, aContext );
1672 else if( cNodeName == wxT(
"FIX" ) )
1676 else if( cNodeName == wxT(
"GROUPREF" ) )
1680 else if( cNodeName == wxT(
"REUSEBLOCKREF" ) )
1694 wxASSERT( aNode->GetName() == wxT(
"AREA" ) );
1702 bool shapeIsInitialised =
false;
1703 wxString
location = wxString::Format( wxT(
"AREA %s" ),
ID );
1708 for( ; cNode; cNode = cNode->
GetNext() )
1710 wxString cNodeName = cNode->GetName();
1712 if( !shapeIsInitialised && SHAPE::IsShape( cNode ) )
1714 Shape.Parse( cNode, aContext );
1715 shapeIsInitialised =
true;
1717 else if( cNodeName == wxT(
"FIX" ) )
1721 else if( cNodeName == wxT(
"USAGE" ) )
1723 wxXmlAttribute* xmlAttribute = cNode->GetAttributes();
1725 for( ; xmlAttribute; xmlAttribute = xmlAttribute->GetNext() )
1730 if( xmlAttribute->GetValue() == wxT(
"PLACEMENT" ) )
1732 else if( xmlAttribute->GetValue() == wxT(
"ROUTING" ) )
1734 else if( xmlAttribute->GetValue() == wxT(
"KEEPOUT" ) )
1736 else if( xmlAttribute->GetValue() == wxT(
"NO_TRACKS" ) )
1738 else if( xmlAttribute->GetValue() == wxT(
"NO_VIAS" ) )
1746 else if( cNodeName == wxT(
"AREAHEIGHT" ) )
1750 else if( cNodeName == wxT(
"GROUPREF" ) )
1754 else if( cNodeName == wxT(
"REUSEBLOCKREF" ) )
1758 else if( cNodeName == wxT(
"ATTR" ) )
1761 attr.
Parse( cNode, aContext );
1774 wxASSERT( aNode->GetName() == wxT(
"PINATTR" ) );
1780 for( ; cNode; cNode = cNode->
GetNext() )
1782 wxString cNodeName = cNode->GetName();
1784 if( cNodeName == wxT(
"ATTR" ) )
1787 attrVal.
Parse( cNode, aContext );
1790 else if( cNodeName == wxT(
"TESTLAND" ) )
1804 wxASSERT( aNode->GetName() == wxT(
"PADEXCEPTION" ) );
1810 for( ; cNode; cNode = cNode->
GetNext() )
1812 wxString cNodeName = cNode->GetName();
1814 if( cNodeName == wxT(
"PADCODEREF" ) )
1818 else if( cNodeName == wxT(
"EXITS" ) )
1821 Exits.Parse( cNode, aContext );
1823 else if( cNodeName == wxT(
"SIDE" ) )
1828 else if( cNodeName == wxT(
"ORIENT" ) )
1843 wxASSERT( aNode->GetName() == wxT(
"COMP" ) );
1851 bool originParsed =
false;
1853 for( ; cNode; cNode = cNode->
GetNext() )
1855 wxString cNodeName = cNode->GetName();
1857 if( !originParsed && cNodeName == wxT(
"PT" ) )
1859 Origin.Parse( cNode, aContext );
1860 originParsed =
true;
1862 else if( cNodeName == wxT(
"GROUPREF" ) )
1866 else if( cNodeName == wxT(
"REUSEBLOCKREF" ) )
1870 else if( cNodeName == wxT(
"TESTPOINT" ) )
1874 else if( cNodeName == wxT(
"FIX" ) )
1878 else if( cNodeName == wxT(
"MIRROR" ) )
1882 else if( cNodeName == wxT(
"READABILITY" ) )
1886 else if( cNodeName == wxT(
"ORIENT" ) )
1890 else if( cNodeName == wxT(
"VCOMPMASTER" ) )
1895 else if( cNodeName == wxT(
"TEXTLOC" ) )
1898 textloc.
Parse( cNode, aContext );
1901 else if( cNodeName == wxT(
"ATTR" ) )
1904 attrVal.
Parse( cNode, aContext );
1907 else if( cNodeName == wxT(
"PINATTR" ) )
1910 pinAttr.
Parse( cNode, aContext );
1913 else if( cNodeName == wxT(
"COMPPINLABEL" ) )
1917 PinLabels.insert( std::make_pair( pinID, pinLabel ) );
1919 else if( cNodeName == wxT(
"PADEXCEPTION" ) )
1922 padExcept.
Parse( cNode, aContext );
1939 wxASSERT( aNode->GetName() == wxT(
"TESTLAND" ) );
1943 if( side == wxT(
"MIN_SIDE" ) )
1945 else if( side == wxT(
"MAX_SIDE" ) )
1947 else if( side == wxT(
"BOTH_SIDES" ) )
1958 wxASSERT( aNode->GetName() == wxT(
"TRUNK" ) );
1967 wxASSERT( aNode->GetName() == wxT(
"PIN" ) );
1982 for( ; cNode; cNode = cNode->
GetNext() )
1986 else if( cNode->GetName() == wxT(
"TRUNKREF" ) )
1996 wxASSERT( aNode->GetName() == wxT(
"VIA" ) );
2004 for( ; cNode; cNode = cNode->
GetNext() )
2006 wxString cNodeName = cNode->GetName();
2008 if( cNodeName == wxT(
"PT" ) )
2010 else if( cNodeName == wxT(
"FIX" ) )
2012 else if( cNodeName == wxT(
"GROUPREF" ) )
2014 else if( cNodeName == wxT(
"REUSEBLOCKREF" ) )
2016 else if( cNodeName == wxT(
"TESTLAND" ) )
2018 else if( cNode->GetName() == wxT(
"TRUNKREF" ) )
2029 wxASSERT( aNode->GetName() == wxT(
"COPTERM" ) );
2040 wxASSERT( aNode->GetName() == wxT(
"ROUTEWIDTH" ) );
2043 XNODE* prevNode = aNode;
2046 for( ; nextNode; nextNode = nextNode->
GetNext() )
2048 if( nextNode->GetName() == wxT(
"FIX" ) )
2052 else if( nextNode->GetName() == wxT(
"TDROPATSTART" ) )
2057 else if( nextNode->GetName() == wxT(
"TDROPATEND" ) )
2062 else if( VERTEX::IsVertex( nextNode ) )
2064 Vertex.Parse( nextNode, aContext );
2066 else if( nextNode->GetName() == wxT(
"ROUTEWIDTH" ) )
2075 prevNode = nextNode;
2084 wxASSERT( aNode->GetName() == wxT(
"ROUTE" ) );
2090 bool startPointParsed =
false;
2092 for( ; cNode; cNode = cNode->
GetNext() )
2094 wxString cNodeName = cNode->GetName();
2096 if( !startPointParsed && cNodeName == wxT(
"PT" ) )
2098 startPointParsed =
true;
2101 else if( cNodeName == wxT(
"ROUTEWIDTH" ) )
2104 cNode = rtVert.
Parse( cNode, aContext );
2107 assert( cNode !=
nullptr );
2124 bool routeParsed =
false;
2126 for( ; cNode; cNode = cNode->
GetNext() )
2128 wxString cNodeName = cNode->GetName();
2134 else if( !
Unrouted && !routeParsed && cNodeName == wxT(
"ROUTE" ) )
2136 Route.Parse( cNode, aContext );
2139 else if( !routeParsed && cNodeName == wxT(
"UNROUTE" ) )
2144 else if( cNode->GetName() == wxT(
"TRUNKREF" ) )
2163 for( ; cNode; cNode = cNode->
GetNext() )
2165 wxString cNodeName = cNode->GetName();
2167 if( cNodeName == wxT(
"JPT" ) )
2170 jpt.
Parse( cNode, aContext );
2171 Junctions.insert( std::make_pair( jpt.
ID, jpt ) );
2177 else if( cNodeName == wxT(
"PIN" ) )
2180 pin.Parse( cNode, aContext );
2181 Pins.insert( std::make_pair(
pin.ID,
pin ) );
2183 else if( cNodeName == wxT(
"VIA" ) )
2186 via.Parse( cNode, aContext );
2187 Vias.insert( std::make_pair(
via.ID,
via ) );
2189 else if( cNodeName == wxT(
"COPTERM" ) )
2192 cterm.
Parse( cNode, aContext );
2195 else if( cNodeName == wxT(
"CONN" ) )
2198 conn.
Parse( cNode, aContext );
2211 wxASSERT( aNode->GetName() == wxT(
"POURING" ) );
2223 if( MinIsolCopStr == wxT(
"NONE" ) )
2230 if( MinDisjCopStr == wxT(
"NONE" ) )
2237 for( ; cNode; cNode = cNode->
GetNext() )
2239 wxString cNodeName = cNode->GetName();
2241 if( cNodeName == wxT(
"NOPINRELIEF" ) )
2245 else if( cNodeName == wxT(
"NOVIARELIEF" ) )
2249 else if( cNodeName == wxT(
"IGNORETRN" ) )
2253 else if( cNodeName == wxT(
"BOXPINS" ) )
2257 else if( cNodeName == wxT(
"REGENERATE" ) )
2261 else if( cNodeName == wxT(
"AUTOROUTETARGET" ) )
2265 else if( cNodeName == wxT(
"THERMALCUTOUT" ) )
2269 else if( cNodeName == wxT(
"FILLED" ) )
2273 else if( cNodeName == wxT(
"HATCHCODEREF" ) )
2288 wxASSERT( aNode->GetName() == wxT(
"TEMPLATE" ) );
2297 bool shapeParsed =
false;
2298 bool pouringParsed =
false;
2300 for( ; cNode; cNode = cNode->
GetNext() )
2302 wxString cNodeName = cNode->GetName();
2304 if( !shapeParsed && SHAPE::IsShape( cNode ) )
2306 Shape.Parse( cNode, aContext );
2309 else if( !pouringParsed && cNodeName == wxT(
"POURING" ) )
2311 Pouring.Parse( cNode, aContext );
2312 pouringParsed =
true;
2314 else if( cNodeName == wxT(
"FIX" ) )
2318 else if( cNodeName == wxT(
"GROUPREF" ) )
2322 else if( cNodeName == wxT(
"REUSEBLOCKREF" ) )
2326 else if( cNodeName == wxT(
"ATTR" ) )
2329 attr.
Parse( cNode, aContext );
2343 wxASSERT( aNode->GetName() == wxT(
"TERM" ) );
2348 bool locationParsed =
false;
2350 for( ; cNode; cNode = cNode->
GetNext() )
2352 wxString cNodeName = cNode->GetName();
2354 if( !locationParsed && cNodeName == wxT(
"PT" ) )
2357 locationParsed =
true;
2359 else if( cNodeName == wxT(
"FIX" ) )
2373 wxASSERT( aNode->GetName() == wxT(
"NETREF" ) );
2379 for( ; cNode; cNode = cNode->
GetNext() )
2381 wxString cNodeName = cNode->GetName();
2383 if( cNodeName == wxT(
"TERM" ) )
2386 term.
Parse( cNode, aContext );
2389 else if( cNodeName == wxT(
"FIX" ) )
2403 wxASSERT( aNode->GetName() == wxT(
"COPPER" ) );
2410 bool shapeParsed =
false;
2411 bool netRefParsed =
false;
2413 for( ; cNode; cNode = cNode->
GetNext() )
2415 wxString cNodeName = cNode->GetName();
2417 if( !shapeParsed && SHAPE::IsShape( cNode ) )
2419 Shape.Parse( cNode, aContext );
2422 else if( !netRefParsed && cNodeName == wxT(
"NETREF" ) )
2424 NetRef.Parse( cNode, aContext );
2425 netRefParsed =
true;
2427 else if( cNodeName == wxT(
"FIX" ) )
2431 else if( cNodeName == wxT(
"GROUPREF" ) )
2435 else if( cNodeName == wxT(
"REUSEBLOCKREF" ) )
2439 else if( cNodeName == wxT(
"POURED" ) )
2443 else if( cNodeName == wxT(
"ATTR" ) )
2446 attr.
Parse( cNode, aContext );
2459 wxASSERT( aNode->GetName() == wxT(
"DRILLTABLE" ) );
2465 bool positionParsed =
false;
2467 for( ; cNode; cNode = cNode->
GetNext() )
2469 wxString cNodeName = cNode->GetName();
2471 if( !positionParsed && cNodeName == wxT(
"PT" ) )
2474 positionParsed =
true;
2476 else if( cNodeName == wxT(
"ORIENT" ) )
2480 else if( cNodeName == wxT(
"MIRROR" ) )
2484 else if( cNodeName == wxT(
"FIX" ) )
2488 else if( cNodeName == wxT(
"READABILITY" ) )
2492 else if( cNodeName == wxT(
"GROUPREF" ) )
2496 else if( cNodeName == wxT(
"REUSEBLOCKREF" ) )
2510 wxASSERT( aNode->GetName() == wxT(
"LAYOUT" ) );
2513 bool netSynchParsed =
false;
2514 bool dimensionsParsed =
false;
2516 for( ; cNode; cNode = cNode->
GetNext() )
2518 wxString cNodeName = cNode->GetName();
2520 if( !netSynchParsed && cNodeName == wxT(
"NETSYNCH" ) )
2522 std::map<wxString, NETSYNCH> netSynchMap = { { wxT(
"WARNING" ),
NETSYNCH::WARNING },
2527 if( netSynchMap.find( nsString ) == netSynchMap.end() )
2531 netSynchParsed =
true;
2533 else if( cNodeName == wxT(
"GROUP" ) )
2536 group.Parse( cNode, aContext );
2539 else if( cNodeName == wxT(
"REUSEBLOCK" ) )
2542 reuseblock.
Parse( cNode, aContext );
2543 ReuseBlocks.insert( std::make_pair( reuseblock.
ID, reuseblock ) );
2545 else if( cNodeName == wxT(
"BOARD" ) )
2548 board.
Parse( cNode, aContext );
2549 Boards.insert( std::make_pair( board.
ID, board ) );
2551 else if( cNodeName == wxT(
"FIGURE" ) )
2554 figure.
Parse( cNode, aContext );
2555 Figures.insert( std::make_pair( figure.
ID, figure ) );
2557 else if( cNodeName == wxT(
"AREA" ) )
2560 area.
Parse( cNode, aContext );
2561 Areas.insert( std::make_pair( area.
ID, area ) );
2563 else if( cNodeName == wxT(
"COMP" ) )
2566 comp.Parse( cNode, aContext );
2569 else if( cNodeName == wxT(
"TRUNK" ) )
2572 trunk.
Parse( cNode, aContext );
2573 Trunks.insert( std::make_pair( trunk.
ID, trunk ) );
2575 else if( cNodeName == wxT(
"NET" ) )
2578 net.
Parse( cNode, aContext );
2579 Nets.insert( std::make_pair( net.
ID, net ) );
2581 else if( cNodeName == wxT(
"TEMPLATE" ) )
2584 temp.
Parse( cNode, aContext );
2585 Templates.insert( std::make_pair( temp.
ID, temp ) );
2587 else if( cNodeName == wxT(
"COPPER" ) )
2590 copper.
Parse( cNode, aContext );
2591 Coppers.insert( std::make_pair( copper.
ID, copper ) );
2593 else if( cNodeName == wxT(
"TEXT" ) )
2596 txt.
Parse( cNode, aContext );
2597 Texts.insert( std::make_pair( txt.
ID, txt ) );
2599 else if( cNodeName == wxT(
"DOCSYMBOL" ) )
2602 docsym.
Parse( cNode, aContext );
2605 else if( !dimensionsParsed && cNodeName == wxT(
"DIMENSIONS" ) )
2609 for( ; dimensionNode; dimensionNode = dimensionNode->
GetNext() )
2614 dim.
Parse( dimensionNode, aContext );
2623 dimensionsParsed =
true;
2625 else if( cNodeName == wxT(
"DRILLTABLE" ) )
2628 drilltable.
Parse( cNode, aContext );
2629 DrillTables.insert( std::make_pair( drilltable.
ID, drilltable ) );
2631 else if( cNodeName == wxT(
"VHIERARCHY" ) )
2635 else if( cNodeName == wxT(
"ERRORMARK" ) )
constexpr double PCB_IU_PER_MM
Pcbnew IU is 1 nanometer.
#define THROW_MISSING_NODE_IO_ERROR(nodename, location)
#define THROW_UNKNOWN_NODE_IO_ERROR(nodename, location)
#define THROW_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 ...
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 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)
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.
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
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override