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" ) )
732 if( aNode->
GetChildren()->GetName() == wxT(
"ORIENT" ) )
754 wxASSERT( aNode->GetName() == wxT(
"PADREASSIGN" ) );
769 wxASSERT( aNode->GetName() == wxT(
"PADCODE" ) );
775 wxString
location = wxString::Format( wxT(
"PADCODE -> %s" ),
Name );
777 for( ; cNode; cNode = cNode->
GetNext() )
779 wxString cNodeName = cNode->GetName();
783 Shape.Parse( cNode, aContext );
785 else if( cNodeName == wxT(
"CLEARANCE" ) )
789 else if( cNodeName == wxT(
"RELIEFWIDTH" ) )
793 else if( cNodeName == wxT(
"DRILL" ) )
798 for( ; subNode; subNode = subNode->
GetNext() )
800 wxString subNodeName = subNode->GetName();
802 if( subNodeName == wxT(
"NONPLATED" ) )
804 else if( subNodeName == wxT(
"OVERSIZE" ) )
810 else if( cNodeName == wxT(
"DRILLLENGTH" ) )
814 else if( cNodeName == wxT(
"DRILLORIENTATION" ) )
818 else if( cNodeName == wxT(
"DRILLXOFFSET" ) )
822 else if( cNodeName == wxT(
"DRILLYOFFSET" ) )
826 else if( cNodeName == wxT(
"PADREASSIGN" ) )
829 reassign.
Parse( cNode, aContext );
842 wxASSERT( aNode->GetName() == wxT(
"VIAREASSIGN" ) );
857 wxASSERT( aNode->GetName() == wxT(
"VIACODE" ) );
863 wxString
location = wxString::Format( wxT(
"VIACODE -> %s" ),
Name );
865 for( ; cNode; cNode = cNode->
GetNext() )
867 wxString cNodeName = cNode->GetName();
871 Shape.Parse( cNode, aContext );
873 else if( cNodeName == wxT(
"CLEARANCE" ) )
877 else if( cNodeName == wxT(
"RELIEFWIDTH" ) )
881 else if( cNodeName == wxT(
"DRILL" ) )
886 for( ; subNode; subNode = subNode->
GetNext() )
888 wxString subNodeName = subNode->GetName();
890 if( subNodeName == wxT(
"OVERSIZE" ) )
896 else if( cNodeName == wxT(
"VIAREASSIGN" ) )
899 reassign.
Parse( cNode, aContext );
912 wxASSERT( aNode->GetName() == wxT(
"LAYERPAIR" ) );
920 wxString
location = wxString::Format( wxT(
"LAYERPAIR -> %s" ),
Name );
924 if( aNode->
GetChildren()->GetName() == wxT(
"VIACODEREF" ) )
940 wxASSERT( aNode->GetName() == wxT(
"SPCCLASSSPACE" ) );
951 wxASSERT( aNode->GetName() == wxT(
"TECHNOLOGY" ) );
955 for( ; cNode; cNode = cNode->
GetNext() )
957 wxString cNodeName = cNode->GetName();
962 else if( cNodeName == wxT(
"MINROUTEWIDTH" ) )
966 else if( cNodeName == wxT(
"MINNECKED" ) )
970 else if( cNodeName == wxT(
"MINUNNECKED" ) )
974 else if( cNodeName == wxT(
"MINMITER" ) )
978 else if( cNodeName == wxT(
"MAXMITER" ) )
982 else if( cNodeName == wxT(
"MAXPHYSLAYER" ) )
986 else if( cNodeName == wxT(
"TRACKGRID" ) )
990 else if( cNodeName == wxT(
"VIAGRID" ) )
994 else if( cNodeName == wxT(
"BACKOFFJCTS" ) )
998 else if( cNodeName == wxT(
"BCKOFFWIDCHANGE" ) )
1011 const wxString& aPadSideString )
1013 if( aPadSideString == wxT(
"THRU" ) )
1015 else if( aPadSideString == wxT(
"BOTTOM" ) )
1017 else if( aPadSideString == wxT(
"TOP" ) )
1026 wxASSERT( aNode->GetName() == wxT(
"COMPCOPPER" ) );
1032 bool shapeIsInitialised =
false;
1033 wxString
location = wxT(
"COMPCOPPER" );
1038 for( ; cNode; cNode = cNode->
GetNext() )
1040 wxString cNodeName = cNode->GetName();
1042 if( !shapeIsInitialised &&
Shape.IsShape( cNode ) )
1044 Shape.Parse( cNode, aContext );
1045 shapeIsInitialised =
true;
1047 else if( cNodeName == wxT(
"SWAPRULE" ) )
1051 else if( cNodeName == wxT(
"ASSOCPIN" ) )
1053 wxXmlAttribute* xmlAttribute = cNode->GetAttributes();
1055 for( ; xmlAttribute; xmlAttribute = xmlAttribute->GetNext() )
1062 if( !xmlAttribute->GetValue().ToLong( &padId ) )
1080 wxASSERT( aNode->GetName() == wxT(
"COMPAREA" ) );
1087 bool shapeIsInitialised =
false;
1088 wxString
location = wxString::Format( wxT(
"COMPAREA %s" ),
ID );
1093 for( ; cNode; cNode = cNode->
GetNext() )
1095 wxString cNodeName = cNode->GetName();
1097 if( !shapeIsInitialised && SHAPE::IsShape( cNode ) )
1099 Shape.Parse( cNode, aContext );
1100 shapeIsInitialised =
true;
1102 else if( cNodeName == wxT(
"SWAPRULE" ) )
1106 else if( cNodeName == wxT(
"USAGE" ) )
1108 wxXmlAttribute* xmlAttribute = cNode->GetAttributes();
1110 for( ; xmlAttribute; xmlAttribute = xmlAttribute->GetNext() )
1115 if( xmlAttribute->GetValue() == wxT(
"NO_TRACKS" ) )
1117 else if( xmlAttribute->GetValue() == wxT(
"NO_VIAS" ) )
1135 wxASSERT( aNode->GetName() == wxT(
"EXITS" ) );
1137 wxXmlAttribute* xmlAttribute = aNode->GetAttributes();
1139 for( ; xmlAttribute; xmlAttribute = xmlAttribute->GetNext() )
1144 if( xmlAttribute->GetValue() == wxT(
"FREE" ) )
1146 else if( xmlAttribute->GetValue() == wxT(
"N" ) )
1148 else if( xmlAttribute->GetValue() == wxT(
"S" ) )
1150 else if( xmlAttribute->GetValue() == wxT(
"E" ) )
1152 else if( xmlAttribute->GetValue() == wxT(
"W" ) )
1154 else if( xmlAttribute->GetValue() == wxT(
"NE" ) )
1156 else if( xmlAttribute->GetValue() == wxT(
"NW" ) )
1158 else if( xmlAttribute->GetValue() == wxT(
"SE" ) )
1160 else if( xmlAttribute->GetValue() == wxT(
"SW" ) )
1172 wxASSERT( aNode->GetName() == wxT(
"PAD" ) );
1179 wxString
location = wxString::Format( wxT(
"PAD %ld" ),
ID );
1184 for( ; cNode; cNode = cNode->
GetNext() )
1186 wxString cNodeName = cNode->GetName();
1188 if( cNodeName == wxT(
"ORIENT" ) )
1190 else if( cNodeName == wxT(
"FIRSTPAD" ) )
1192 else if( cNodeName == wxT(
"EXITS" ) )
1193 Exits.Parse( cNode, aContext );
1194 else if( cNodeName == wxT(
"PADIDENTIFIER" ) )
1196 else if( cNodeName == wxT(
"PCBONLYPAD" ) )
1198 else if( cNodeName == wxT(
"PT" ) )
1208 wxASSERT( aNode->GetName() == wxT(
"DIMARROW" ) );
1209 bool arrowStyleInitialised =
false;
1210 bool upperAngleInitialised =
false;
1211 bool lowerAngleInitialised =
false;
1218 for( ; cNode; cNode = cNode->
GetNext() )
1220 wxString cNodeName = cNode->GetName();
1222 if( cNodeName == wxT(
"ARROWSTYLE" ) )
1225 arrowStyleInitialised =
true;
1227 if( arrowStyleStr == wxT(
"DIMENSION_ARROWOPEN" ) )
1229 else if( arrowStyleStr == wxT(
"DIMENSION_ARROWCLOSED" ) )
1231 else if( arrowStyleStr == wxT(
"DIMENSION_ARROWCLEAR" ) )
1233 else if( arrowStyleStr == wxT(
"DIMENSION_ARROWCLOSEDFILLED" ) )
1238 else if( cNodeName == wxT(
"ARROWANGLEA" ) )
1241 upperAngleInitialised =
true;
1243 else if( cNodeName == wxT(
"ARROWANGLEB" ) )
1246 lowerAngleInitialised =
true;
1254 if( !arrowStyleInitialised )
1257 if( !upperAngleInitialised )
1260 if( !lowerAngleInitialised )
1268 wxASSERT( aNode->GetName() == wxT(
"DIMTEXT" ) );
1275 if( !cNode || cNode->GetName() != wxT(
"TXTSTYLE" ) )
1280 if( styleStr == wxT(
"DIMENSION_INTERNAL" ) )
1282 else if( styleStr == wxT(
"DIMENSION_EXTERNAL" ) )
1294 wxASSERT( aNode->GetName() == wxT(
"EXTLINE" ) );
1303 for( ; cNode; cNode = cNode->
GetNext() )
1305 wxString cNodeName = cNode->GetName();
1307 if( noOfPoints < 2 && cNodeName == wxT(
"PT" ) )
1311 if( noOfPoints == 1 )
1312 Start.Parse( cNode, aContext );
1314 End.Parse( cNode, aContext );
1316 else if( cNodeName == wxT(
"SUPPRESSFIRST" ) )
1326 if( noOfPoints != 2 )
1333 if( aNode->GetName() == wxT(
"LEADERLINE" ) || aNode->GetName() == wxT(
"LINEARLINE" )
1334 || aNode->GetName() == wxT(
"ANGULARLINE" ) )
1347 wxASSERT(
IsLine( aNode ) );
1349 if( aNode->GetName() == wxT(
"LINEARLINE" ) )
1350 Type = TYPE::LINEARLINE;
1351 else if( aNode->GetName() == wxT(
"LEADERLINE" ) )
1352 Type = TYPE::LEADERLINE;
1353 else if( aNode->GetName() == wxT(
"ANGULARLINE" ) )
1354 Type = TYPE::ANGULARLINE;
1356 wxASSERT_MSG(
true, wxT(
"Not a valid type. What happened to the node Name?" ) );
1360 if(
Type == TYPE::LEADERLINE )
1368 int requiredNoOfPoints = 2;
1370 if(
Type == TYPE::ANGULARLINE )
1371 requiredNoOfPoints = 3;
1373 for( ; cNode; cNode = cNode->
GetNext() )
1375 wxString cNodeName = cNode->GetName();
1377 if( cNodeName == wxT(
"DIMLINETYPE" ) )
1381 if( styleStr == wxT(
"DIMENSION_INTERNAL" ) )
1383 else if( styleStr == wxT(
"DIMENSION_EXTERNAL" ) )
1388 else if( noOfPoints < requiredNoOfPoints && cNodeName == wxT(
"PT" ) )
1392 if( noOfPoints == 1 )
1393 Start.Parse( cNode, aContext );
1394 else if( noOfPoints == 2 )
1395 End.Parse( cNode, aContext );
1397 Centre.Parse( cNode, aContext );
1399 else if(
Type == TYPE::LEADERLINE && cNodeName == wxT(
"LEADERANG" ) )
1409 if( noOfPoints != requiredNoOfPoints )
1416 if( aNode->GetName() == wxT(
"LINEARDIM" ) || aNode->GetName() == wxT(
"LEADERDIM" )
1417 || aNode->GetName() == wxT(
"ANGLEDIM" ) )
1432 std::map<wxString, TYPE> typeMap = { { wxT(
"LINEARDIM" ), TYPE::LINEARDIM },
1433 { wxT(
"LEADERDIM" ), TYPE::LEADERDIM }, { wxT(
"ANGLEDIM" ), TYPE::ANGLEDIM } };
1436 wxASSERT_MSG( typeMap.find( aNode->GetName() ) != typeMap.end(),
1437 wxT(
"Not a valid type. What happened to the node Name?" ) );
1439 Type = typeMap[aNode->GetName()];
1443 std::map<wxString, SUBTYPE> subTypeMap = {
1451 if( subTypeMap.find( subTypeStr ) == subTypeMap.end() )
1454 Subtype = subTypeMap[subTypeStr];
1459 bool idParsed =
false;
1460 bool unitsParsed =
false;
1461 bool arrowParsed =
false;
1462 bool textFormatParsed =
false;
1463 bool extLineParsed =
false;
1464 bool lineParsed =
false;
1465 bool textParsed =
false;
1467 for( ; cNode; cNode = cNode->
GetNext() )
1469 wxString cNodeName = cNode->GetName();
1471 if( !idParsed && cNodeName == wxT(
"DIMREF" ) )
1476 else if( !unitsParsed && cNodeName == wxT(
"UNITS" ) )
1481 else if( !unitsParsed && cNodeName == wxT(
"ANGUNITS" ) )
1486 else if( !arrowParsed && cNodeName == wxT(
"DIMARROW" ) )
1488 Arrow.Parse( cNode, aContext );
1491 else if( !textFormatParsed && cNodeName == wxT(
"DIMTEXT" ) )
1494 textFormatParsed =
true;
1496 else if( !extLineParsed && cNodeName == wxT(
"EXTLINE" ) )
1499 extLineParsed =
true;
1503 Line.Parse( cNode, aContext );
1506 else if( !textParsed && cNodeName == wxT(
"TEXT" ) )
1509 Text.Parse( cNode, aContext,
false );
1512 else if( cNodeName == wxT(
"FIX" ) )
1516 else if( cNodeName == wxT(
"GROUPREF" ) )
1520 else if( cNodeName == wxT(
"REUSEBLOCKREF" ) )
1534 wxASSERT( aNode->GetName() == wxT(
"SYMDEF" ) );
1542 else if(
ReferenceName.StartsWith( wxT(
"STARPOINTNF" ), &rest ) )
1551 for( ; cNode; cNode = cNode->
GetNext() )
1553 wxString cNodeName = cNode->GetName();
1559 else if( cNodeName == wxT(
"SYMHEIGHT" ) )
1563 else if( cNodeName == wxT(
"COMPCOPPER" ) )
1566 compcopper.
Parse( cNode, aContext );
1569 else if( cNodeName == wxT(
"COMPAREA" ) )
1572 area.
Parse( cNode, aContext );
1575 else if( cNodeName == wxT(
"PAD" ) )
1578 pad.Parse( cNode, aContext );
1581 else if( cNodeName == wxT(
"DIMENSIONS" ) )
1585 for( ; dimensionNode; dimensionNode = dimensionNode->
GetNext() )
1590 dim.
Parse( dimensionNode, aContext );
1612 wxASSERT( aNode->GetName() == wxT(
"LIBRARY" ) );
1616 for( ; cNode; cNode = cNode->
GetNext() )
1618 wxString cNodeName = cNode->GetName();
1620 if( cNodeName == wxT(
"SYMDEF" ) )
1623 symdef.
Parse( cNode, aContext );
1626 else if( cNodeName == wxT(
"HIERARCHY" ) )
1646 wxASSERT( aNode->GetName() == wxT(
"BOARD" ) );
1652 bool shapeIsInitialised =
false;
1653 wxString
location = wxString::Format( wxT(
"BOARD %s" ),
ID );
1658 for( ; cNode; cNode = cNode->
GetNext() )
1660 wxString cNodeName = cNode->GetName();
1662 if( !shapeIsInitialised && SHAPE::IsShape( cNode ) )
1664 Shape.Parse( cNode, aContext );
1665 shapeIsInitialised =
true;
1667 else if( cNodeName == wxT(
"ATTR" ) )
1670 attr.
Parse( cNode, aContext );
1673 else if( cNodeName == wxT(
"FIX" ) )
1677 else if( cNodeName == wxT(
"GROUPREF" ) )
1681 else if( cNodeName == wxT(
"REUSEBLOCKREF" ) )
1695 wxASSERT( aNode->GetName() == wxT(
"AREA" ) );
1703 bool shapeIsInitialised =
false;
1704 wxString
location = wxString::Format( wxT(
"AREA %s" ),
ID );
1709 for( ; cNode; cNode = cNode->
GetNext() )
1711 wxString cNodeName = cNode->GetName();
1713 if( !shapeIsInitialised && SHAPE::IsShape( cNode ) )
1715 Shape.Parse( cNode, aContext );
1716 shapeIsInitialised =
true;
1718 else if( cNodeName == wxT(
"FIX" ) )
1722 else if( cNodeName == wxT(
"USAGE" ) )
1724 wxXmlAttribute* xmlAttribute = cNode->GetAttributes();
1726 for( ; xmlAttribute; xmlAttribute = xmlAttribute->GetNext() )
1731 if( xmlAttribute->GetValue() == wxT(
"PLACEMENT" ) )
1733 else if( xmlAttribute->GetValue() == wxT(
"ROUTING" ) )
1735 else if( xmlAttribute->GetValue() == wxT(
"KEEPOUT" ) )
1737 else if( xmlAttribute->GetValue() == wxT(
"NO_TRACKS" ) )
1739 else if( xmlAttribute->GetValue() == wxT(
"NO_VIAS" ) )
1747 else if( cNodeName == wxT(
"AREAHEIGHT" ) )
1751 else if( cNodeName == wxT(
"GROUPREF" ) )
1755 else if( cNodeName == wxT(
"REUSEBLOCKREF" ) )
1759 else if( cNodeName == wxT(
"ATTR" ) )
1762 attr.
Parse( cNode, aContext );
1775 wxASSERT( aNode->GetName() == wxT(
"PINATTR" ) );
1781 for( ; cNode; cNode = cNode->
GetNext() )
1783 wxString cNodeName = cNode->GetName();
1785 if( cNodeName == wxT(
"ATTR" ) )
1788 attrVal.
Parse( cNode, aContext );
1791 else if( cNodeName == wxT(
"TESTLAND" ) )
1805 wxASSERT( aNode->GetName() == wxT(
"PADEXCEPTION" ) );
1811 for( ; cNode; cNode = cNode->
GetNext() )
1813 wxString cNodeName = cNode->GetName();
1815 if( cNodeName == wxT(
"PADCODEREF" ) )
1819 else if( cNodeName == wxT(
"EXITS" ) )
1822 Exits.Parse( cNode, aContext );
1824 else if( cNodeName == wxT(
"SIDE" ) )
1829 else if( cNodeName == wxT(
"ORIENT" ) )
1844 wxASSERT( aNode->GetName() == wxT(
"COMP" ) );
1852 bool originParsed =
false;
1854 for( ; cNode; cNode = cNode->
GetNext() )
1856 wxString cNodeName = cNode->GetName();
1858 if( !originParsed && cNodeName == wxT(
"PT" ) )
1860 Origin.Parse( cNode, aContext );
1861 originParsed =
true;
1863 else if( cNodeName == wxT(
"GROUPREF" ) )
1867 else if( cNodeName == wxT(
"REUSEBLOCKREF" ) )
1871 else if( cNodeName == wxT(
"TESTPOINT" ) )
1875 else if( cNodeName == wxT(
"FIX" ) )
1879 else if( cNodeName == wxT(
"MIRROR" ) )
1883 else if( cNodeName == wxT(
"READABILITY" ) )
1887 else if( cNodeName == wxT(
"ORIENT" ) )
1891 else if( cNodeName == wxT(
"VCOMPMASTER" ) )
1896 else if( cNodeName == wxT(
"TEXTLOC" ) )
1899 textloc.
Parse( cNode, aContext );
1902 else if( cNodeName == wxT(
"ATTR" ) )
1905 attrVal.
Parse( cNode, aContext );
1908 else if( cNodeName == wxT(
"PINATTR" ) )
1911 pinAttr.
Parse( cNode, aContext );
1914 else if( cNodeName == wxT(
"COMPPINLABEL" ) )
1918 PinLabels.insert( std::make_pair( pinID, pinLabel ) );
1920 else if( cNodeName == wxT(
"PADEXCEPTION" ) )
1923 padExcept.
Parse( cNode, aContext );
1940 wxASSERT( aNode->GetName() == wxT(
"TESTLAND" ) );
1944 if( side == wxT(
"MIN_SIDE" ) )
1946 else if( side == wxT(
"MAX_SIDE" ) )
1948 else if( side == wxT(
"BOTH_SIDES" ) )
1959 wxASSERT( aNode->GetName() == wxT(
"TRUNK" ) );
1968 wxASSERT( aNode->GetName() == wxT(
"PIN" ) );
1983 for( ; cNode; cNode = cNode->
GetNext() )
1987 else if( cNode->GetName() == wxT(
"TRUNKREF" ) )
1997 wxASSERT( aNode->GetName() == wxT(
"VIA" ) );
2005 for( ; cNode; cNode = cNode->
GetNext() )
2007 wxString cNodeName = cNode->GetName();
2009 if( cNodeName == wxT(
"PT" ) )
2011 else if( cNodeName == wxT(
"FIX" ) )
2013 else if( cNodeName == wxT(
"GROUPREF" ) )
2015 else if( cNodeName == wxT(
"REUSEBLOCKREF" ) )
2017 else if( cNodeName == wxT(
"TESTLAND" ) )
2019 else if( cNode->GetName() == wxT(
"TRUNKREF" ) )
2030 wxASSERT( aNode->GetName() == wxT(
"COPTERM" ) );
2041 wxASSERT( aNode->GetName() == wxT(
"ROUTEWIDTH" ) );
2044 XNODE* prevNode = aNode;
2047 for( ; nextNode; nextNode = nextNode->
GetNext() )
2049 if( nextNode->GetName() == wxT(
"FIX" ) )
2053 else if( nextNode->GetName() == wxT(
"TDROPATSTART" ) )
2058 else if( nextNode->GetName() == wxT(
"TDROPATEND" ) )
2063 else if( VERTEX::IsVertex( nextNode ) )
2065 Vertex.Parse( nextNode, aContext );
2067 else if( nextNode->GetName() == wxT(
"ROUTEWIDTH" ) )
2076 prevNode = nextNode;
2085 wxASSERT( aNode->GetName() == wxT(
"ROUTE" ) );
2091 bool startPointParsed =
false;
2093 for( ; cNode; cNode = cNode->
GetNext() )
2095 wxString cNodeName = cNode->GetName();
2097 if( !startPointParsed && cNodeName == wxT(
"PT" ) )
2099 startPointParsed =
true;
2102 else if( cNodeName == wxT(
"ROUTEWIDTH" ) )
2105 cNode = rtVert.
Parse( cNode, aContext );
2108 assert( cNode !=
nullptr );
2125 bool routeParsed =
false;
2127 for( ; cNode; cNode = cNode->
GetNext() )
2129 wxString cNodeName = cNode->GetName();
2135 else if( !
Unrouted && !routeParsed && cNodeName == wxT(
"ROUTE" ) )
2137 Route.Parse( cNode, aContext );
2140 else if( !routeParsed && cNodeName == wxT(
"UNROUTE" ) )
2145 else if( cNode->GetName() == wxT(
"TRUNKREF" ) )
2164 for( ; cNode; cNode = cNode->
GetNext() )
2166 wxString cNodeName = cNode->GetName();
2168 if( cNodeName == wxT(
"JPT" ) )
2171 jpt.
Parse( cNode, aContext );
2172 Junctions.insert( std::make_pair( jpt.
ID, jpt ) );
2178 else if( cNodeName == wxT(
"PIN" ) )
2181 pin.Parse( cNode, aContext );
2182 Pins.insert( std::make_pair(
pin.ID,
pin ) );
2184 else if( cNodeName == wxT(
"VIA" ) )
2187 via.Parse( cNode, aContext );
2188 Vias.insert( std::make_pair(
via.ID,
via ) );
2190 else if( cNodeName == wxT(
"COPTERM" ) )
2193 cterm.
Parse( cNode, aContext );
2196 else if( cNodeName == wxT(
"CONN" ) )
2199 conn.
Parse( cNode, aContext );
2212 wxASSERT( aNode->GetName() == wxT(
"POURING" ) );
2224 if( MinIsolCopStr == wxT(
"NONE" ) )
2231 if( MinDisjCopStr == wxT(
"NONE" ) )
2238 for( ; cNode; cNode = cNode->
GetNext() )
2240 wxString cNodeName = cNode->GetName();
2242 if( cNodeName == wxT(
"NOPINRELIEF" ) )
2246 else if( cNodeName == wxT(
"NOVIARELIEF" ) )
2250 else if( cNodeName == wxT(
"IGNORETRN" ) )
2254 else if( cNodeName == wxT(
"BOXPINS" ) )
2258 else if( cNodeName == wxT(
"REGENERATE" ) )
2262 else if( cNodeName == wxT(
"AUTOROUTETARGET" ) )
2266 else if( cNodeName == wxT(
"THERMALCUTOUT" ) )
2270 else if( cNodeName == wxT(
"FILLED" ) )
2274 else if( cNodeName == wxT(
"HATCHCODEREF" ) )
2289 wxASSERT( aNode->GetName() == wxT(
"TEMPLATE" ) );
2298 bool shapeParsed =
false;
2299 bool pouringParsed =
false;
2301 for( ; cNode; cNode = cNode->
GetNext() )
2303 wxString cNodeName = cNode->GetName();
2305 if( !shapeParsed && SHAPE::IsShape( cNode ) )
2307 Shape.Parse( cNode, aContext );
2310 else if( !pouringParsed && cNodeName == wxT(
"POURING" ) )
2312 Pouring.Parse( cNode, aContext );
2313 pouringParsed =
true;
2315 else if( cNodeName == wxT(
"FIX" ) )
2319 else if( cNodeName == wxT(
"GROUPREF" ) )
2323 else if( cNodeName == wxT(
"REUSEBLOCKREF" ) )
2327 else if( cNodeName == wxT(
"ATTR" ) )
2330 attr.
Parse( cNode, aContext );
2344 wxASSERT( aNode->GetName() == wxT(
"TERM" ) );
2349 bool locationParsed =
false;
2351 for( ; cNode; cNode = cNode->
GetNext() )
2353 wxString cNodeName = cNode->GetName();
2355 if( !locationParsed && cNodeName == wxT(
"PT" ) )
2358 locationParsed =
true;
2360 else if( cNodeName == wxT(
"FIX" ) )
2374 wxASSERT( aNode->GetName() == wxT(
"NETREF" ) );
2380 for( ; cNode; cNode = cNode->
GetNext() )
2382 wxString cNodeName = cNode->GetName();
2384 if( cNodeName == wxT(
"TERM" ) )
2387 term.
Parse( cNode, aContext );
2390 else if( cNodeName == wxT(
"FIX" ) )
2404 wxASSERT( aNode->GetName() == wxT(
"COPPER" ) );
2411 bool shapeParsed =
false;
2412 bool netRefParsed =
false;
2414 for( ; cNode; cNode = cNode->
GetNext() )
2416 wxString cNodeName = cNode->GetName();
2418 if( !shapeParsed && SHAPE::IsShape( cNode ) )
2420 Shape.Parse( cNode, aContext );
2423 else if( !netRefParsed && cNodeName == wxT(
"NETREF" ) )
2425 NetRef.Parse( cNode, aContext );
2426 netRefParsed =
true;
2428 else if( cNodeName == wxT(
"FIX" ) )
2432 else if( cNodeName == wxT(
"GROUPREF" ) )
2436 else if( cNodeName == wxT(
"REUSEBLOCKREF" ) )
2440 else if( cNodeName == wxT(
"POURED" ) )
2444 else if( cNodeName == wxT(
"ATTR" ) )
2447 attr.
Parse( cNode, aContext );
2460 wxASSERT( aNode->GetName() == wxT(
"DRILLTABLE" ) );
2466 bool positionParsed =
false;
2468 for( ; cNode; cNode = cNode->
GetNext() )
2470 wxString cNodeName = cNode->GetName();
2472 if( !positionParsed && cNodeName == wxT(
"PT" ) )
2475 positionParsed =
true;
2477 else if( cNodeName == wxT(
"ORIENT" ) )
2481 else if( cNodeName == wxT(
"MIRROR" ) )
2485 else if( cNodeName == wxT(
"FIX" ) )
2489 else if( cNodeName == wxT(
"READABILITY" ) )
2493 else if( cNodeName == wxT(
"GROUPREF" ) )
2497 else if( cNodeName == wxT(
"REUSEBLOCKREF" ) )
2511 wxASSERT( aNode->GetName() == wxT(
"LAYOUT" ) );
2514 bool netSynchParsed =
false;
2515 bool dimensionsParsed =
false;
2517 for( ; cNode; cNode = cNode->
GetNext() )
2519 wxString cNodeName = cNode->GetName();
2521 if( !netSynchParsed && cNodeName == wxT(
"NETSYNCH" ) )
2523 std::map<wxString, NETSYNCH> netSynchMap = { { wxT(
"WARNING" ),
NETSYNCH::WARNING },
2528 if( netSynchMap.find( nsString ) == netSynchMap.end() )
2532 netSynchParsed =
true;
2534 else if( cNodeName == wxT(
"GROUP" ) )
2537 group.Parse( cNode, aContext );
2540 else if( cNodeName == wxT(
"REUSEBLOCK" ) )
2543 reuseblock.
Parse( cNode, aContext );
2544 ReuseBlocks.insert( std::make_pair( reuseblock.
ID, reuseblock ) );
2546 else if( cNodeName == wxT(
"BOARD" ) )
2549 board.
Parse( cNode, aContext );
2550 Boards.insert( std::make_pair( board.
ID, board ) );
2552 else if( cNodeName == wxT(
"FIGURE" ) )
2555 figure.
Parse( cNode, aContext );
2556 Figures.insert( std::make_pair( figure.
ID, figure ) );
2558 else if( cNodeName == wxT(
"AREA" ) )
2561 area.
Parse( cNode, aContext );
2562 Areas.insert( std::make_pair( area.
ID, area ) );
2564 else if( cNodeName == wxT(
"COMP" ) )
2567 comp.
Parse( cNode, aContext );
2570 else if( cNodeName == wxT(
"TRUNK" ) )
2573 trunk.
Parse( cNode, aContext );
2574 Trunks.insert( std::make_pair( trunk.
ID, trunk ) );
2576 else if( cNodeName == wxT(
"NET" ) )
2579 net.
Parse( cNode, aContext );
2580 Nets.insert( std::make_pair( net.
ID, net ) );
2582 else if( cNodeName == wxT(
"TEMPLATE" ) )
2585 temp.
Parse( cNode, aContext );
2586 Templates.insert( std::make_pair( temp.
ID, temp ) );
2588 else if( cNodeName == wxT(
"COPPER" ) )
2591 copper.
Parse( cNode, aContext );
2592 Coppers.insert( std::make_pair( copper.
ID, copper ) );
2594 else if( cNodeName == wxT(
"TEXT" ) )
2597 txt.
Parse( cNode, aContext );
2598 Texts.insert( std::make_pair( txt.
ID, txt ) );
2600 else if( cNodeName == wxT(
"DOCSYMBOL" ) )
2603 docsym.
Parse( cNode, aContext );
2606 else if( !dimensionsParsed && cNodeName == wxT(
"DIMENSIONS" ) )
2610 for( ; dimensionNode; dimensionNode = dimensionNode->
GetNext() )
2615 dim.
Parse( dimensionNode, aContext );
2624 dimensionsParsed =
true;
2626 else if( cNodeName == wxT(
"DRILLTABLE" ) )
2629 drilltable.
Parse( cNode, aContext );
2630 DrillTables.insert( std::make_pair( drilltable.
ID, drilltable ) );
2632 else if( cNodeName == wxT(
"VHIERARCHY" ) )
2636 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.
Hold an XML or S-expression element.
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