71 long long maxDesignSizekicad = std::numeric_limits<int>::max();
73 if( designSizeXkicad > maxDesignSizekicad || designSizeYkicad > maxDesignSizekicad )
77 THROW_IO_ERRORF(
_(
"The design is too large and cannot be imported into KiCad. \n"
78 "Please reduce the maximum design size in CADSTAR by navigating to: \n"
79 "Design Tab -> Properties -> Design Options -> Maximum Design Size. \n"
80 "Current Design size: %.2f, %.2f millimeters. \n"
81 "Maximum permitted design size: %.2f, %.2f millimeters.\n" ),
94 reportWarning(
_(
"The selected file indicates that nets might be out of synchronisation with the schematic. "
95 "It is recommended that you carry out an 'Align Nets' procedure in CADSTAR and re-import, "
96 "to avoid inconsistencies between the PCB and the schematic. " ) );
106 long numSteps =
Layout.Coppers.size();
109 numSteps += (
Layout.Templates.size() *
Layout.Templates.size() ) / 2;
133 reportError( wxString::Format(
_(
"Unable to determine zone fill priorities for layer '%s'. A best "
134 "attempt has been made but it is possible that DRC errors exist and "
135 "that manual editing of the zone priorities is required." ),
136 m_board->GetLayerName(
id ) ) );
143 if(
Layout.Trunks.size() > 0 )
145 reportWarning(
_(
"The CADSTAR design contains Trunk routing elements, which have no KiCad "
146 "equivalent. These elements were not loaded." ) );
149 if(
Layout.VariantHierarchy.Variants.size() > 0 )
151 reportWarning( wxString::Format(
_(
"The CADSTAR design contains variants which has no KiCad equivalent. "
152 "Only the variant '%s' was loaded." ),
153 Layout.VariantHierarchy.Variants.begin()->second.Name ) );
156 if(
Layout.ReuseBlocks.size() > 0 )
158 reportWarning(
_(
"The CADSTAR design contains re-use blocks which has no KiCad equivalent. The "
159 "re-use block information has been discarded during the import." ) );
162 reportWarning(
_(
"CADSTAR fonts are different to the ones in KiCad. This will likely result "
163 "in alignment issues that may cause DRC errors. Please review the imported "
164 "text elements carefully and correct manually if required." ) );
166 reportInfo(
_(
"The CADSTAR design has been imported successfully.\n"
167 "Please review the import errors and warnings (if any)." ) );
172 std::vector<FOOTPRINT*> retval;
174 for( std::pair<SYMDEF_ID, FOOTPRINT*> fpPair :
m_libraryMap )
176 retval.push_back(
static_cast<FOOTPRINT*
>( fpPair.second->Clone() ) );
192 for( std::pair<SYMDEF_ID, FOOTPRINT*> libItem :
m_libraryMap )
211 std::vector<std::unique_ptr<FOOTPRINT>> retval;
215 footprint->SetParent(
nullptr );
216 retval.emplace_back( footprint );
234 reportWarning( wxString::Format(
_(
"The CADSTAR layer '%s' has no KiCad equivalent. All elements on this "
235 "layer have been mapped to KiCad layer '%s' instead." ),
247 reportInfo( wxString::Format(
_(
"The CADSTAR layer '%s' has been assumed to be a technical layer. All "
248 "elements on this layer have been mapped to KiCad layer '%s'." ),
256 int aDielectricSublayer )
268 if( !aCadstarLayer.
Name.IsEmpty() )
282 LAYER_ID ElecLayerID = wxEmptyString;
285 std::vector<LAYER_ID> ConstructionLayers;
290 bool IsInitialised() {
return !ElecLayerID.IsEmpty() || ConstructionLayers.size() > 0; };
293 std::vector<LAYER_BLOCK> cadstarBoardStackup;
294 LAYER_BLOCK currentBlock;
306 if( currentBlock.IsInitialised() )
308 cadstarBoardStackup.push_back( currentBlock );
309 currentBlock = LAYER_BLOCK();
312 currentBlock.ElecLayerID = cadstarLayerID;
319 reportWarning( wxString::Format(
_(
"The CADSTAR construction layer '%s' is on the outer surface "
320 "of the board. It has been ignored." ),
321 cadstarLayer.
Name ) );
325 currentBlock.ConstructionLayers.push_back( cadstarLayerID );
330 if( currentBlock.IsInitialised() )
331 cadstarBoardStackup.push_back( currentBlock );
336 if( cadstarBoardStackup.back().ConstructionLayers.size() > 0 )
338 for(
const LAYER_ID& layerID : cadstarBoardStackup.back().ConstructionLayers )
342 reportWarning( wxString::Format(
_(
"The CADSTAR construction layer '%s' is on the outer surface "
343 "of the board. It has been ignored." ),
344 cadstarLayer.
Name ) );
347 cadstarBoardStackup.back().ConstructionLayers.clear();
353 LAYER_BLOCK bottomLayer = cadstarBoardStackup.back();
354 cadstarBoardStackup.pop_back();
356 LAYER_BLOCK secondToLastLayer = cadstarBoardStackup.back();
357 cadstarBoardStackup.pop_back();
359 LAYER_BLOCK dummyLayer;
361 if( secondToLastLayer.ConstructionLayers.size() > 0 )
363 LAYER_ID lastConstruction = secondToLastLayer.ConstructionLayers.back();
365 if( secondToLastLayer.ConstructionLayers.size() > 1 )
369 secondToLastLayer.ConstructionLayers.pop_back();
375 Assignments.Layerdefs.Layers.at( lastConstruction ).Thickness /= 2;
378 dummyLayer.ConstructionLayers.push_back( lastConstruction );
381 cadstarBoardStackup.push_back( secondToLastLayer );
382 cadstarBoardStackup.push_back( dummyLayer );
383 cadstarBoardStackup.push_back( bottomLayer );
388 wxASSERT( cadstarBoardStackup.back().ConstructionLayers.size() == 0 );
399 size_t stackIndex = 0;
405 LAYER_ID layerID = cadstarBoardStackup.at( stackIndex ).ElecLayerID;
407 if( layerID.IsEmpty() )
410 item->SetThickness( 0 );
418 switch( copperLayer.
Type )
434 wxFAIL_MSG( wxT(
"Unexpected Layer type. Was expecting an electrical type" ) );
438 m_board->SetLayerType( item->GetBrdLayerId(), copperType );
439 m_board->SetLayerName( item->GetBrdLayerId(), item->GetLayerName() );
440 m_layermap.insert( { copperLayer.
ID, item->GetBrdLayerId() } );
445 LAYER_BLOCK layerBlock = cadstarBoardStackup.at( stackIndex );
446 LAYER_BLOCK layerBlockBelow = cadstarBoardStackup.at( stackIndex + 1 );
448 if( layerBlock.ConstructionLayers.size() == 0 )
454 int dielectricId = stackIndex + 1;
455 item->SetDielectricLayerId( dielectricId );
460 if( layerBlock.ElecLayerID.IsEmpty() )
467 LAYER copperLayer =
Assignments.Layerdefs.Layers.at( layerBlock.ElecLayerID );
469 if( layerBlockBelow.ElecLayerID.IsEmpty() )
480 LAYER copperLayerBelow =
481 Assignments.Layerdefs.Layers.at( layerBlockBelow.ElecLayerID );
498 int dielectricSublayer = 0;
500 for(
LAYER_ID constructionLaID : layerBlock.ConstructionLayers )
502 LAYER dielectricLayer =
Assignments.Layerdefs.Layers.at( constructionLaID );
504 if( dielectricSublayer )
505 item->AddDielectricPrms( dielectricSublayer );
508 m_board->SetLayerName( item->GetBrdLayerId(), item->GetLayerName() );
509 m_layermap.insert( { dielectricLayer.
ID, item->GetBrdLayerId() } );
510 ++dielectricSublayer;
517 item->SetColor( wxT(
"White" ) );
521 item->SetColor( wxT(
"Green" ) );
529 int numElecLayersProcessed = 0;
532 int currentDocLayer = 0;
540 wxString layerName = curLayer.
Name.Lower();
553 kicadLayerID = aBack;
555 kicadLayerID = aFront;
559 case LOG_LEVEL::NONE:
562 case LOG_LEVEL::MSG_LOG:
566 case LOG_LEVEL::WARN:
572 switch( curLayer.
Type )
586 ++numElecLayersProcessed;
594 if( currentDocLayer >= (
int) docLayers.size() )
597 kicadLayerID = docLayers.at( currentDocLayer++ );
615 if( layerName.Contains( wxT(
"glue" ) ) || layerName.Contains( wxT(
"adhesive" ) ) )
619 else if( layerName.Contains( wxT(
"silk" ) ) || layerName.Contains( wxT(
"legend" ) ) )
623 else if( layerName.Contains( wxT(
"assembly" ) ) || layerName.Contains( wxT(
"fabrication" ) ) )
627 else if( layerName.Contains( wxT(
"resist" ) ) || layerName.Contains( wxT(
"mask" ) ) )
631 else if( layerName.Contains( wxT(
"paste" ) ) )
661 wxFAIL_MSG( wxT(
"Unknown CADSTAR Layer Sub-type" ) );
667 wxFAIL_MSG( wxT(
"Unknown CADSTAR Layer Type" ) );
682 std::vector<INPUT_LAYER_DESC> inputLayers;
683 std::map<wxString, LAYER_ID> cadstarLayerNameMap;
685 for( std::pair<LAYER_ID, PCB_LAYER_ID> layerPair :
m_layermap )
697 inputLayers.push_back( iLdesc );
698 cadstarLayerNameMap.insert( { curLayer->
Name, curLayer->
ID } );
702 if( inputLayers.size() == 0 )
708 for( std::pair<wxString, PCB_LAYER_ID> layerPair : reMappedLayers )
712 wxFAIL_MSG( wxT(
"Unexpected Layer ID" ) );
716 LAYER_ID cadstarLayerID = cadstarLayerNameMap.at( layerPair.first );
717 m_layermap.at( cadstarLayerID ) = layerPair.second;
718 enabledLayers |=
LSET( { layerPair.second } );
721 m_board->SetEnabledLayers( enabledLayers );
722 m_board->SetVisibleLayers( enabledLayers );
729 std::map<SPACINGCODE_ID, SPACINGCODE>& spacingCodes =
Assignments.Codedefs.SpacingCodes;
732 [&](
const wxString& aID,
int* aVal )
734 if( spacingCodes.find( aID ) == spacingCodes.end() )
735 reportWarning( wxString::Format(
_(
"Design rule %s was not found. This was ignored." ), aID ) );
753 auto applyNetClassRule =
754 [&](
const wxString& aID,
const std::shared_ptr<NETCLASS>& aNetClassPtr )
757 applyRule( aID, &value );
760 aNetClassPtr->SetClearance( value );
765 reportWarning(
_(
"KiCad design rules are different from CADSTAR ones. Only the compatible "
766 "design rules were imported. It is recommended that you review the design "
767 "rules that have been applied." ) );
773 for( std::pair<SYMDEF_ID, SYMDEF_PCB> symPair :
Library.ComponentDefinitions )
783 if( component.
Figures.size() > 0 )
786 componentLayer = firstFigure.
LayerID;
788 else if( component.
Texts.size() > 0 )
790 TEXT firstText = component.
Texts.begin()->second;
791 componentLayer = firstText.
LayerID;
814 m_libraryMap.insert( std::make_pair( key, footprint ) );
822 for( std::pair<FIGURE_ID, FIGURE> figPair : aComponent.
Figures )
824 FIGURE& fig = figPair.second;
829 wxString::Format( wxT(
"Component %s:%s -> Figure %s" ),
846 LSET remainingLayers = layers;
849 && copperLayers.count() > 0
875 std::unique_ptr<PAD>
pad = std::make_unique<PAD>( aFootprint );
877 pad->SetLayerSet( copperLayers );
878 pad->SetNumber( anchorPad.
Identifier.IsEmpty() ? wxString::Format( wxT(
"%ld" ), anchorPad.
ID )
888 if( anchorSize <= 0 )
895 pad->SetPosition( anchorPos );
898 shapePolys.
Move( -anchorPos );
915 remainingLayers ^= copperLayers;
918 if( remainingLayers.any() )
923 wxString::Format( wxT(
"Component %s:%s -> Copper element" ),
934 for( std::pair<COMP_AREA_ID, COMPONENT_AREA> areaPair : aComponent.
ComponentAreas )
940 int lineThickness = 0;
965 libName << wxT(
" (" ) << aComponent.
Alternate << wxT(
")" );
967 reportError( wxString::Format(
_(
"The CADSTAR area '%s' in library component '%s' does not "
968 "have a KiCad equivalent. The area is neither a via nor "
969 "route keepout area. The area was not imported." ),
980 for( std::pair<PAD_ID, COMPONENT_PAD> padPair : aComponent.
ComponentPads )
1005 auto elongationOffset =
1023 aPad->
SetSize( aPadLayer, elongatedSize() );
1046 aPad->
SetSize( aPadLayer, { sizeOfSquare, sizeOfSquare } );
1054 aPad->
SetSize( aPadLayer, elongatedSize() );
1069 aPad->
SetSize( aPadLayer, elongatedSize() );
1077 aPad->
SetSize( aPadLayer, elongatedSize() );
1089 wxFAIL_MSG( wxT(
"Unknown Pad Shape" ) );
1101 std::unique_ptr<PAD>
pad = std::make_unique<PAD>( aParent );
1104 switch( aCadstarPad.
Side )
1119 wxFAIL_MSG( wxT(
"Unknown Pad type" ) );
1123 pad->SetLocalSolderMaskMargin( 0 );
1124 pad->SetLocalSolderPasteMargin( 0 );
1125 pad->SetLocalSolderPasteMarginRatio( 0.0 );
1127 std::map<PCB_LAYER_ID, CADSTAR_PAD_SHAPE> copperReassigns;
1129 for(
auto& [layer, shape] : csPadcode.
Reassigns )
1133 if( shape.Size == 0 )
1136 padLayerSet.
reset( kiLayer );
1147 std::optional<int> localMargin =
pad->GetLocalSolderMaskMargin();
1149 if( !localMargin.has_value() )
1150 pad->SetLocalSolderMaskMargin( newMargin );
1152 pad->SetLocalSolderMaskMargin( newMargin );
1156 std::optional<int> localMargin =
pad->GetLocalSolderPasteMargin();
1158 if( !localMargin.has_value() )
1159 pad->SetLocalSolderPasteMargin( newMargin );
1161 pad->SetLocalSolderPasteMargin( newMargin );
1165 copperReassigns[kiLayer] = shape;
1170 pad->SetLayerSet( padLayerSet );
1177 pad->SetNumber( wxT(
"" ) );
1181 pad->SetNumber( aCadstarPad.
Identifier.IsEmpty() ? wxString::Format( wxT(
"%ld" ), aCadstarPad.
ID )
1205 if( !copperReassigns.empty() )
1209 for(
const auto& [kiLayer, shape] : copperReassigns )
1212 pad->SetOffset( kiLayer, padOffset - layerOffset );
1248 pad->SetDrillSize( { 0, 0 } );
1253 LSET lset =
pad->GetLayerSet();
1256 if( lset.size() > 0 )
1258 int maxError =
m_board->GetDesignSettings().m_MaxError;
1260 bool holeInsidePad =
true;
1262 pad->SetPosition( { 0, 0 } );
1266 std::map<PCB_LAYER_ID, std::unique_ptr<PCB_SHAPE>> slotShapes;
1271 pad->TransformShapeToPolygon( padOutline, padLayer, 0, maxError,
ERROR_INSIDE );
1273 auto padShape = std::make_unique<PCB_SHAPE>();
1275 padShape->SetFilled(
true );
1276 padShape->SetPolyShape( padOutline );
1278 padShape->Move( padOffset - drillOffset );
1279 padShape->Rotate(
VECTOR2I( 0, 0 ), slotAngle );
1281 if( !padShape->GetPolyShape().Contains( { 0, 0 } ) )
1282 holeInsidePad =
false;
1284 slotShapes[padLayer] = std::move( padShape );
1289 for(
auto& [padLayer, padShape] : slotShapes )
1296 pad->SetOffset( padLayer, { 0, 0 } );
1297 pad->AddPrimitive( padLayer, padShape.release() );
1300 padOffset = { 0, 0 };
1307 drillOffset = { 0, 0 };
1309 errorMSG += wxT(
"\n - " )
1310 + wxString::Format(
_(
"The CADSTAR pad definition '%s' has the hole shape outside the "
1311 "pad shape. The hole has been moved to the center of the pad." ),
1317 wxFAIL_MSG( wxT(
"No copper layers defined in the pad?" ) );
1326 pad->SetOffset( padLayer,
pad->GetOffset( padLayer ) + drillOffset );
1340 reportError( wxString::Format(
_(
"The CADSTAR pad definition '%s' has import errors: %s" ),
1347 return pad.release();
1353 size_t index = aCadstarPadID - (long) 1;
1367 for( std::pair<GROUP_ID, GROUP> groupPair :
Layout.Groups )
1369 GROUP& csGroup = groupPair.second;
1381 for( std::pair<GROUP_ID, GROUP> groupPair :
Layout.Groups )
1383 GROUP& csGroup = groupPair.second;
1385 if( !csGroup.
GroupID.IsEmpty() )
1389 THROW_IO_ERRORF(
_(
"Unable to find group ID %s in the group definitions." ), csGroup.
ID );
1393 THROW_IO_ERRORF(
_(
"Unable to find sub group %s in the group map (parent group ID=%s, Name=%s)." ),
1402 parentGroup->
AddItem( kiCadGroup );
1411 for( std::pair<BOARD_ID, CADSTAR_BOARD> boardPair :
Layout.Boards )
1420 if( !board.
GroupID.IsEmpty() )
1430 for( std::pair<FIGURE_ID, FIGURE> figPair :
Layout.Figures )
1432 FIGURE& fig = figPair.second;
1449 for( std::pair<TEXT_ID, TEXT> txtPair :
Layout.Texts )
1451 TEXT& csTxt = txtPair.second;
1459 for( std::pair<DIMENSION_ID, DIMENSION> dimPair :
Layout.Dimensions )
1463 switch( csDim.
Type )
1465 case DIMENSION::TYPE::LINEARDIM:
1468 case DIMENSION::SUBTYPE::ANGLED:
1469 reportWarning( wxString::Format(
_(
"Dimension ID %s is an angled dimension, which has no KiCad "
1470 "equivalent. An aligned dimension was loaded instead." ),
1473 case DIMENSION::SUBTYPE::DIRECT:
1474 case DIMENSION::SUBTYPE::ORTHOGONAL:
1476 if( csDim.
Line.
Style == DIMENSION::LINE::STYLE::EXTERNAL )
1478 reportWarning( wxString::Format(
_(
"Dimension ID %s has 'External' style in CADSTAR. External "
1479 "dimension styles are not yet supported in KiCad. The "
1480 "dimension object was imported with an internal dimension "
1487 if( csDim.
Subtype == DIMENSION::SUBTYPE::ORTHOGONAL )
1510 VECTOR2I crossbarVector = crossbarEnd - crossbarStart;
1512 double height = 0.0;
1514 if( csDim.
Subtype == DIMENSION::SUBTYPE::ORTHOGONAL )
1517 height = heightVector.
y;
1519 height = heightVector.
x;
1525 height = heightVector.
x * angle.
Cos() + heightVector.
y * angle.
Sin();
1535 reportError( wxString::Format(
_(
"Unexpected Dimension type (ID %s). This was not imported." ),
1541 case DIMENSION::TYPE::LEADERDIM:
1544 if( csDim.
Line.
Style == DIMENSION::LINE::STYLE::INTERNAL )
1668 case DIMENSION::TYPE::ANGLEDIM:
1670 reportError( wxString::Format(
_(
"Dimension %s is an angular dimension which has no KiCad equivalent. "
1671 "The object was not imported." ),
1681 for( std::pair<AREA_ID, AREA> areaPair :
Layout.Areas )
1683 AREA& area = areaPair.second;
1687 int lineThickness = 0;
1710 reportWarning( wxString::Format(
_(
"The CADSTAR area '%s' is marked as a placement area in "
1711 "CADSTAR. Placement areas are not supported in KiCad. Only "
1712 "the supported elements for the area were imported." ),
1718 reportError( wxString::Format(
_(
"The CADSTAR area '%s' does not have a KiCad equivalent. Pure "
1719 "Placement areas are not supported." ),
1734 for( std::pair<COMPONENT_ID, COMPONENT> compPair :
Layout.Components )
1738 if( !
comp.VariantID.empty() &&
comp.VariantParentComponentID !=
comp.ID )
1745 THROW_IO_ERRORF(
_(
"Unable to find component '%s' in the library (Symdef ID: '%s')" ),
1750 FOOTPRINT* libFootprint = fpIter->second;
1761 if(
Parts.PartDefinitions.find(
comp.PartID ) !=
Parts.PartDefinitions.end() )
1769 for( std::pair<PART_DEFINITION_PIN_ID, PART::DEFINITION::PIN> pinPair :
1772 PART::DEFINITION::PIN
pin = pinPair.second;
1773 wxString pinName =
pin.Name;
1775 if( pinName.empty() )
1776 pinName =
pin.Identifier;
1778 if( pinName.empty() )
1779 pinName = wxString::Format( wxT(
"%ld" ),
pin.ID );
1787 if(
comp.PadExceptions.size() > 0 )
1791 for( std::pair<PAD_ID, PADEXCEPTION> padPair :
comp.PadExceptions )
1800 if( !padEx.
PadCode.IsEmpty() )
1815 wxString padNumber = kiPad->
GetNumber();
1830 footprint->
SetValue( wxEmptyString );
1846 if( !
comp.PartID.IsEmpty() &&
comp.PartID != wxT(
"NO_PART" ) )
1858 for( std::pair<DOCUMENTATION_SYMBOL_ID, DOCUMENTATION_SYMBOL> docPair :
Layout.DocumentationSymbols )
1863 auto docSymIter =
Library.ComponentDefinitions.find( docSymInstance.
SymdefID );
1865 if( docSymIter ==
Library.ComponentDefinitions.end() )
1867 THROW_IO_ERRORF(
_(
"Unable to find documentation symbol in the library (Symdef ID: '%s')" ),
1871 SYMDEF_PCB& docSymDefinition = ( *docSymIter ).second;
1877 bool mirrorInvert = docSymInstance.
Mirror;
1882 if( !docSymDefinition.
Alternate.IsEmpty() )
1883 groupName += wxT(
" (" ) + docSymDefinition.
Alternate + wxT(
")" );
1891 for( std::pair<FIGURE_ID, FIGURE> figPair : docSymDefinition.
Figures )
1893 FIGURE fig = figPair.second;
1895 wxString::Format( wxT(
"DOCUMENTATION SYMBOL %s, FIGURE %s" ),
1898 m_board, groupID, moveVector, rotationAngle, scalingFactor,
1899 centreOfTransform, mirrorInvert );
1903 for( std::pair<TEXT_ID, TEXT> textPair : docSymDefinition.
Texts )
1905 TEXT txt = textPair.second;
1907 scalingFactor, centreOfTransform, mirrorInvert );
1915 for( std::pair<TEMPLATE_ID, TEMPLATE> tempPair :
Layout.Templates )
1917 TEMPLATE& csTemplate = tempPair.second;
1919 int zonelinethickness = 0;
1929 if( !( csTemplate.
NetID.IsEmpty() || csTemplate.
NetID == wxT(
"NONE" ) ) )
1934 reportWarning( wxString::Format(
_(
"The CADSTAR template '%s' has the setting 'Allow in No Routing "
1935 "Areas' enabled. This setting has no KiCad equivalent, so it has "
1937 csTemplate.
Name ) );
1942 reportWarning( wxString::Format(
_(
"The CADSTAR template '%s' has the setting 'Box Isolated Pins' "
1943 "enabled. This setting has no KiCad equivalent, so it has been "
1945 csTemplate.
Name ) );
1950 reportWarning( wxString::Format(
_(
"The CADSTAR template '%s' has the setting 'Automatic Repour' "
1951 "enabled. This setting has no KiCad equivalent, so it has been "
1953 csTemplate.
Name ) );
1961 reportWarning( wxString::Format(
_(
"The CADSTAR template '%s' has a non-zero value defined for the "
1962 "'Sliver Width' setting. There is no KiCad equivalent for "
1963 "this, so this setting was ignored." ),
1964 csTemplate.
Name ) );
1970 reportWarning( wxString::Format(
_(
"The CADSTAR template '%s' has different settings for "
1971 "'Retain Poured Copper - Disjoint' and "
1972 "'Retain Poured Copper - Isolated'. KiCad does not distinguish "
1973 "between these two settings. The setting for disjoint copper "
1974 "has been applied as the minimum island area of the KiCad Zone." ),
1975 csTemplate.
Name ) );
1978 long long minIslandArea = -1;
2005 if( csTemplate.
Pouring.
FillType == TEMPLATE::POURING::COPPER_FILL_TYPE::HATCHED )
2021 reportWarning( wxString::Format(
_(
"The CADSTAR template '%s' has different settings for thermal relief "
2022 "in pads and vias. KiCad only supports one single setting for both. "
2023 "The setting for pads has been applied." ),
2024 csTemplate.
Name ) );
2035 if( spokeWidth < minThickness )
2037 reportWarning( wxString::Format(
_(
"The CADSTAR template '%s' has thermal reliefs in the original "
2038 "design but the spoke width (%.2f mm) is thinner "
2039 "than the minimum thickness of the zone (%.2f mm). "
2040 "KiCad requires the minimum thickness of the zone to be preserved. "
2041 "Therefore the minimum thickness has been applied as the new "
2042 "spoke width and will be applied next time the zones are filled." ),
2046 spokeWidth = minThickness;
2067 wxString powerPlaneLayerName =
Assignments.Layerdefs.Layers.at( layer ).Name;
2068 NET_ID netid = wxEmptyString;
2070 for( std::pair<NET_ID, NET_PCB> netPair :
Layout.Nets )
2074 if( net.
Name == powerPlaneLayerName )
2081 if( netid.IsEmpty() )
2083 reportError( wxString::Format(
_(
"The CADSTAR layer '%s' is defined as a power plane layer. "
2084 "However no net with such name exists. The layer has been loaded "
2085 "but no copper zone was created." ),
2086 powerPlaneLayerName ) );
2090 for( std::pair<BOARD_ID, CADSTAR_BOARD> boardPair :
Layout.Boards )
2115 for( std::pair<COPPER_ID, COPPER> copPair :
Layout.Coppers )
2117 COPPER& csCopper = copPair.second;
2179 reportWarning(
_(
"The CADSTAR design contains COPPER elements, which have no direct KiCad "
2180 "equivalent. These have been imported as a KiCad Zone if solid or hatch "
2181 "filled, or as a KiCad Track if the shape was an unfilled outline (open or "
2251 for( std::pair<NET_ID, NET_PCB> netPair :
Layout.Nets )
2254 wxString netnameForErrorReporting = net.
Name;
2256 std::map<NETELEMENT_ID, long> netelementSizes;
2258 if( netnameForErrorReporting.IsEmpty() )
2259 netnameForErrorReporting = wxString::Format( wxT(
"$%ld" ), net.
SignalNum );
2261 for( std::pair<NETELEMENT_ID, NET_PCB::VIA> viaPair : net.
Vias )
2263 NET_PCB::VIA
via = viaPair.second;
2267 netelementSizes.insert( { viaPair.first, viaSize } );
2270 for( std::pair<NETELEMENT_ID, NET_PCB::PIN> pinPair : net.
Pins )
2272 NET_PCB::PIN
pin = pinPair.second;
2275 if( footprint ==
nullptr )
2277 reportWarning( wxString::Format(
_(
"The net '%s' references component ID '%s' which does not exist. "
2278 "This has been ignored." ),
2279 netnameForErrorReporting,
pin.ComponentID ) );
2281 else if(
pin.PadID <= 0 ||
static_cast<size_t>(
pin.PadID ) > footprint->
Pads().size() )
2285 reportWarning( wxString::Format(
_(
"The net '%s' references non-existent pad index '%ld' in "
2286 "component '%s'. This has been ignored." ),
2287 netnameForErrorReporting,
2306 if( assocPads.find(
pin.PadID ) != assocPads.end() )
2308 for(
PAD_ID copperPadID : assocPads.at(
pin.PadID ) )
2319 netelementSizes.insert( { pinPair.first, padsize } );
2331 auto getRouteCodeWidth =
2334 auto rcIt =
Assignments.Codedefs.RouteCodes.find( aRouteCodeID );
2336 if( rcIt !=
Assignments.Codedefs.RouteCodes.end() && rcIt->second.OptimalWidth > 0 )
2337 return rcIt->second.OptimalWidth;
2340 m_board->GetDesignSettings().m_NetSettings->GetDefaultNetclass()->GetTrackWidth();
2347 auto getVertexWidth =
2348 [&](
const NET_PCB::ROUTE_VERTEX& aVertex,
const ROUTECODE_ID& aRouteCodeID ) ->
long
2350 if( aVertex.RouteWidthIsExplicit )
2351 return aVertex.RouteWidth;
2353 return getRouteCodeWidth( aRouteCodeID );
2356 auto getJunctionSize =
2357 [&](
const NETELEMENT_ID& aJptNetElemId,
const NET_PCB::CONNECTION_PCB& aConnectionToIgnore ) ->
int
2361 for( NET_PCB::CONNECTION_PCB connection : net.
Connections )
2363 if( connection.Route.RouteVertices.size() == 0 )
2366 if( connection.StartNode == aConnectionToIgnore.StartNode
2367 && connection.EndNode == aConnectionToIgnore.EndNode )
2372 if( connection.StartNode == aJptNetElemId )
2374 int s =
getKiCadLength( getVertexWidth( connection.Route.RouteVertices.front(),
2375 connection.RouteCodeID ), 0.0 );
2376 jptsize = std::max( jptsize, s );
2378 else if( connection.EndNode == aJptNetElemId )
2380 int s =
getKiCadLength( getVertexWidth( connection.Route.RouteVertices.back(),
2381 connection.RouteCodeID ), 0.0 );
2382 jptsize = std::max( jptsize, s );
2386 if( jptsize == 0 && !aConnectionToIgnore.Route.RouteVertices.empty() )
2390 NET_PCB::ROUTE_VERTEX vertex = aConnectionToIgnore.Route.RouteVertices.front();
2392 if( aConnectionToIgnore.EndNode == aJptNetElemId )
2393 vertex = aConnectionToIgnore.Route.RouteVertices.back();
2395 jptsize =
getKiCadLength( getVertexWidth( vertex, aConnectionToIgnore.RouteCodeID ), 0.0 );
2404 for(
const NET_PCB::CONNECTION_PCB& connection : net.
Connections )
2406 int startSize = std::numeric_limits<int>::max();
2407 int endSize = std::numeric_limits<int>::max();
2409 if( netelementSizes.find( connection.StartNode ) != netelementSizes.end() )
2410 startSize = netelementSizes.at( connection.StartNode );
2412 startSize = getJunctionSize( connection.StartNode, connection );
2414 if( netelementSizes.find( connection.EndNode ) != netelementSizes.end() )
2415 endSize = netelementSizes.at( connection.EndNode );
2417 endSize = getJunctionSize( connection.EndNode, connection );
2422 if( !connection.Unrouted )
2424 loadNetTracks( net.
ID, connection.Route, getRouteCodeWidth( connection.RouteCodeID ),
2425 startSize, endSize );
2434 auto findAndReplaceTextField =
2437 if(
m_context.TextFieldToValuesMap.find( aField ) !=
m_context.TextFieldToValuesMap.end() )
2439 if(
m_context.TextFieldToValuesMap.at( aField ) != aValue )
2441 m_context.TextFieldToValuesMap.at( aField ) = aValue;
2442 m_context.InconsistentTextFields.insert( aField );
2448 m_context.TextFieldToValuesMap.insert( { aField, aValue } );
2456 std::map<wxString, wxString>& txtVars =
m_project->GetTextVars();
2459 if(
Layout.VariantHierarchy.Variants.size() > 0 )
2461 VARIANT loadedVar =
Layout.VariantHierarchy.Variants.begin()->second;
2469 for( std::pair<TEXT_FIELD_NAME, wxString> txtvalue :
m_context.TextFieldToValuesMap )
2472 wxString varValue = txtvalue.second;
2474 txtVars.insert( { varName, varValue } );
2477 for( std::pair<wxString, wxString> txtvalue :
m_context.FilenamesToTextMap )
2479 wxString varName = txtvalue.first;
2480 wxString varValue = txtvalue.second;
2482 txtVars.insert( { varName, varValue } );
2487 reportError(
_(
"Text Variables could not be set as there is no project loaded." ) );
2495 for( std::pair<ATTRIBUTE_ID, ATTRIBUTE_VALUE> attrPair : aComponent.
AttributeValues )
2503 for( std::pair<ATTRIBUTE_ID, TEXT_LOCATION> textlocPair : aComponent.
TextLocations )
2509 attrval = wxEmptyString;
2511 attrval = wxT(
"${REFERENCE}" );
2523 const NET_PCB::ROUTE& aCadstarRoute,
2524 long aDefaultRouteWidth,
2525 long aStartWidth,
long aEndWidth )
2527 if( aCadstarRoute.RouteVertices.size() == 0 )
2530 std::vector<PCB_SHAPE*> shapes;
2531 std::vector<NET_PCB::ROUTE_VERTEX> routeVertices = aCadstarRoute.RouteVertices;
2534 for( NET_PCB::ROUTE_VERTEX& v : routeVertices )
2536 if( !v.RouteWidthIsExplicit )
2537 v.RouteWidth = aDefaultRouteWidth;
2541 if( aStartWidth < routeVertices.front().RouteWidth )
2543 NET_PCB::ROUTE_VERTEX newFrontVertex = aCadstarRoute.RouteVertices.front();
2544 newFrontVertex.RouteWidth = aStartWidth;
2545 newFrontVertex.Vertex.End = aCadstarRoute.StartPoint;
2546 routeVertices.insert( routeVertices.begin(), newFrontVertex );
2550 if( aEndWidth < routeVertices.back().RouteWidth )
2552 NET_PCB::ROUTE_VERTEX newBackVertex = aCadstarRoute.RouteVertices.back();
2553 newBackVertex.RouteWidth = aEndWidth;
2554 routeVertices.push_back( newBackVertex );
2557 POINT prevEnd = aCadstarRoute.StartPoint;
2559 for(
const NET_PCB::ROUTE_VERTEX& v : routeVertices )
2565 shapes.push_back( shape );
2566 prevEnd = v.Vertex.End;
2571 reportError(
_(
"The CADSTAR design contains teardrops. This importer does not yet support them, "
2572 "so the teardrops in the design have been ignored." ) );
2598 via->SetLocked( aCadstarVia.Fixed );
2602 reportError( wxString::Format(
_(
"The CADSTAR via code '%s' has different shape from a circle defined. "
2603 "KiCad only supports circular vias so this via type has been changed to "
2604 "be a via with circular shape of %.2f mm diameter." ),
2612 for(
const auto& [layer, shape] : csViaCode.
Reassigns )
2628 if( start_layer_outside && end_layer_outside )
2630 else if( ( !start_layer_outside ) && ( !end_layer_outside ) )
2646 const LAYER_ID& aCadstarLayerOverride,
2648 double aRotationAngle,
double aScalingFactor,
2650 bool aMirrorInvert )
2653 aContainer->
Add( txt );
2658 RotatePoint( rotatedTextPos, aTransformCentre, rotationAngle );
2659 rotatedTextPos.
x =
KiROUND( ( rotatedTextPos.
x - aTransformCentre.
x ) * aScalingFactor );
2660 rotatedTextPos.
y =
KiROUND( ( rotatedTextPos.
y - aTransformCentre.
y ) * aScalingFactor );
2661 rotatedTextPos += aTransformCentre;
2720 wxFAIL_MSG( wxT(
"Unknown Alignment - needs review!" ) );
2727 if( aScalingFactor != 1.0 )
2733 scaledTextSize.
x =
KiROUND( (
double) unscaledTextSize.
x * aScalingFactor );
2734 scaledTextSize.
y =
KiROUND( (
double) unscaledTextSize.
y * aScalingFactor );
2740 txt->
Move( aMoveVector );
2745 LAYER_ID layersToDrawOn = aCadstarLayerOverride;
2747 if( layersToDrawOn.IsEmpty() )
2748 layersToDrawOn = aCadstarText.
LayerID;
2759 if( !aCadstarGroupID.IsEmpty() )
2770 if( !aCadstarGroupID.IsEmpty() )
2780 double aRotationAngle,
double aScalingFactor,
2781 const VECTOR2I& aTransformCentre,
bool aMirrorInvert )
2783 auto drawAsOutline =
2787 aContainer, aCadstarGroupID, aMoveVector, aRotationAngle,
2788 aScalingFactor, aTransformCentre, aMirrorInvert );
2790 aCadstarGroupID, aMoveVector, aRotationAngle, aScalingFactor,
2791 aTransformCentre, aMirrorInvert );
2801 if( aCadstarShape.
Vertices.size() < 3 )
2817 aRotationAngle, aScalingFactor, aTransformCentre,
2827 if( !aCadstarGroupID.IsEmpty() )
2838 double aRotationAngle,
2839 double aScalingFactor,
2841 bool aMirrorInvert )
2843 for(
const CUTOUT& cutout : aCutouts )
2846 aCadstarGroupID, aMoveVector, aRotationAngle, aScalingFactor, aTransformCentre,
2857 const VECTOR2I& aMoveVector,
double aRotationAngle,
2858 double aScalingFactor,
const VECTOR2I& aTransformCentre,
2859 bool aMirrorInvert )
2861 std::vector<PCB_SHAPE*> shapes =
getShapesFromVertices( aCadstarVertices, aContainer, aCadstarGroupID,
2862 aMoveVector, aRotationAngle, aScalingFactor,
2863 aTransformCentre, aMirrorInvert );
2867 shape->SetStroke(
STROKE_PARAMS( aLineThickness, aLineStyle ) );
2868 shape->SetLayer( aKiCadLayer );
2869 shape->SetParent( aContainer );
2875std::vector<PCB_SHAPE*>
2880 double aRotationAngle,
double aScalingFactor,
2882 bool aMirrorInvert )
2884 std::vector<PCB_SHAPE*> shapes;
2886 if( aCadstarVertices.size() < 2 )
2890 const VERTEX* prev = &aCadstarVertices.at( 0 );
2893 for(
size_t i = 1; i < aCadstarVertices.size(); i++ )
2895 cur = &aCadstarVertices.at( i );
2897 aRotationAngle, aScalingFactor, aTransformCentre, aMirrorInvert ) );
2906 const VERTEX& aCadstarVertex,
2910 double aRotationAngle,
2911 double aScalingFactor,
2913 bool aMirrorInvert )
2925 centerPoint = ( startPoint + endPoint ) / 2;
2932 switch( aCadstarVertex.
Type )
2939 shape->
SetEnd( endPoint );
2955 EDA_ANGLE arcStartAngle( startPoint - centerPoint );
2956 EDA_ANGLE arcEndAngle( endPoint - centerPoint );
2957 EDA_ANGLE arcAngle = ( arcEndAngle - arcStartAngle ).Normalize();
2974 if( aScalingFactor != 1.0 )
2976 shape->
Move( -1*aTransformCentre );
2977 shape->
Scale( aScalingFactor );
2978 shape->
Move( aTransformCentre );
2981 if( aRotationAngle != 0.0 )
2984 if( aMoveVector !=
VECTOR2I{ 0, 0 } )
2985 shape->
Move( aMoveVector );
2987 if( !aCadstarGroupID.IsEmpty() )
2997 ZONE* zone =
new ZONE( aParentContainer );
3013 for(
int i = 0; i < polygon.
HoleCount( 0 ); i++ )
3024 double aRotationAngle,
3025 double aScalingFactor,
3027 bool aMirrorInvert )
3032 aMoveVector, aRotationAngle, aScalingFactor,
3033 aTransformCentre, aMirrorInvert );
3044 aMoveVector, aRotationAngle, aScalingFactor,
3045 aTransformCentre, aMirrorInvert );
3056 if( aLineThickness > 0 )
3064 for(
int j = 0; j < polySet.
HoleCount( i ); ++j )
3079 switch( shape->GetShape() )
3083 SHAPE_ARC arc( shape->GetCenter(), shape->GetStart(), shape->GetArcAngle() );
3085 if( shape->EndsSwapped() )
3093 lineChain.
Append( shape->GetStartX(), shape->GetStartY() );
3094 lineChain.
Append( shape->GetEndX(), shape->GetEndY() );
3098 wxFAIL_MSG( wxT(
"Drawsegment type is unexpected. Ignored." ) );
3119 int aWidthOverride )
3121 std::vector<PCB_TRACK*> tracks;
3133 if( aTrack->GetLength() != 0 )
3135 tracks.push_back( aTrack );
3146 switch( shape->GetShape() )
3150 SHAPE_ARC arc( shape->GetStart(), shape->GetArcMid(), shape->GetEnd(), 0 );
3152 if( shape->EndsSwapped() )
3155 track =
new PCB_ARC( aParentContainer, &arc );
3160 track =
new PCB_TRACK( aParentContainer );
3161 track->
SetStart( shape->GetStart() );
3162 track->
SetEnd( shape->GetEnd() );
3166 wxFAIL_MSG( wxT(
"Drawsegment type is unexpected. Ignored." ) );
3170 if( aWidthOverride == -1 )
3171 track->
SetWidth( shape->GetWidth() );
3176 track->
SetLayer( shape->GetLayer() );
3180 if( aNet !=
nullptr )
3188 if( prevTrack !=
nullptr )
3190 int offsetAmount = ( track->
GetWidth() / 2 ) - ( prevTrack->
GetWidth() / 2 );
3192 if( offsetAmount > 0 )
3199 else if( offsetAmount < 0 )
3204 prevTrack->
SetEnd( newEnd );
3239 FOOTPRINT* aFootprint,
const wxString& aAttributeValue )
3252 aFootprint->
SetValue( aAttributeValue );
3253 field = &aFootprint->
Value();
3258 aFootprint->
Add( field );
3259 field->
SetText( aAttributeValue );
3272 aFootprint->
SetValue( aAttributeValue );
3273 field = &aFootprint->
Value();
3279 aFootprint->
Add( field );
3280 field->
SetText( aAttributeValue );
3289 if( aCadstarAttrLoc.
Mirror )
3347 wxFAIL_MSG( wxT(
"Unknown Alignment - needs review!" ) );
3354 const long& aOffsetAmount )
3356 VECTOR2I v( *aPointToOffset - aRefPoint );
3362 aPointToOffset->
x = offsetted.
x;
3363 aPointToOffset->
y = offsetted.
y;
3367 *aPointToOffset = aRefPoint;
3390 if( textSize.
x == 0 )
3395 if( textSize.
x == 0 || textSize.
y == 0 )
3437 wxCHECK(
Assignments.Codedefs.LineCodes.find( aCadstarLineCodeID ) !=
Assignments.Codedefs.LineCodes.end(),
3446 wxCHECK(
Assignments.Codedefs.LineCodes.find( aCadstarLineCodeID ) !=
Assignments.Codedefs.LineCodes.end(),
3449 switch(
Assignments.Codedefs.LineCodes.at( aCadstarLineCodeID ).Style )
3464 wxCHECK(
Assignments.Codedefs.CopperCodes.find( aCadstaCopperCodeID ) !=
Assignments.Codedefs.CopperCodes.end(),
3467 return Assignments.Codedefs.CopperCodes.at( aCadstaCopperCodeID );
3473 wxCHECK(
Assignments.Codedefs.TextCodes.find( aCadstarTextCodeID ) !=
Assignments.Codedefs.TextCodes.end(),
3476 return Assignments.Codedefs.TextCodes.at( aCadstarTextCodeID );
3485 return Assignments.Codedefs.PadCodes.at( aCadstarPadCodeID );
3494 return Assignments.Codedefs.ViaCodes.at( aCadstarViaCodeID );
3500 wxCHECK(
Assignments.Codedefs.LayerPairs.find( aCadstarLayerPairID ) !=
Assignments.Codedefs.LayerPairs.end(),
3503 return Assignments.Codedefs.LayerPairs.at( aCadstarLayerPairID );
3509 wxCHECK(
Assignments.Codedefs.AttributeNames.find( aCadstarAttributeID )
3513 return Assignments.Codedefs.AttributeNames.at( aCadstarAttributeID ).Name;
3518 const std::map<ATTRIBUTE_ID, ATTRIBUTE_VALUE>& aCadstarAttrMap )
3520 wxCHECK( aCadstarAttrMap.find( aCadstarAttributeID ) != aCadstarAttrMap.end(), wxEmptyString );
3522 return aCadstarAttrMap.at( aCadstarAttributeID ).Value;
3530 return Assignments.Layerdefs.Layers.at( aCadstarLayerID ).Type;
3538 wxCHECK(
Parts.PartDefinitions.find( aCadstarPartID ) !=
Parts.PartDefinitions.end(),
PART() );
3540 return Parts.PartDefinitions.at( aCadstarPartID );
3547 wxCHECK(
Assignments.Codedefs.RouteCodes.find( aCadstarRouteCodeID ) !=
Assignments.Codedefs.RouteCodes.end(),
3550 return Assignments.Codedefs.RouteCodes.at( aCadstarRouteCodeID );
3557 wxCHECK(
Assignments.Codedefs.HatchCodes.find( aCadstarHatchcodeID ) !=
Assignments.Codedefs.HatchCodes.end(),
3560 return Assignments.Codedefs.HatchCodes.at( aCadstarHatchcodeID );
3569 if( hcode.
Hatches.size() < 1 )
3570 return m_board->GetDesignSettings().GetDefaultZoneSettings().m_HatchOrientation;
3582 return m_board->GetDesignSettings().GetDefaultZoneSettings().m_HatchThickness;
3594 return m_board->GetDesignSettings().GetDefaultZoneSettings().m_HatchGap;
3618 if( hcode.
Hatches.size() != 2 )
3620 reportWarning( wxString::Format(
_(
"The CADSTAR Hatching code '%s' has %d hatches defined. "
3621 "KiCad only supports 2 hatches (crosshatching) 90 degrees apart. "
3622 "The imported hatching is crosshatched." ),
3624 (
int) hcode.
Hatches.size() ) );
3628 if( hcode.
Hatches.at( 0 ).LineWidth != hcode.
Hatches.at( 1 ).LineWidth )
3630 reportWarning( wxString::Format(
_(
"The CADSTAR Hatching code '%s' has different line widths for "
3631 "each hatch. KiCad only supports one width for the hatching. The "
3632 "imported hatching uses the width defined in the first hatch "
3633 "definition, i.e. %.2f mm." ),
3640 reportWarning( wxString::Format(
_(
"The CADSTAR Hatching code '%s' has different step sizes for "
3641 "each hatch. KiCad only supports one step size for the hatching. "
3642 "The imported hatching uses the step size defined in the first "
3643 "hatching definition, i.e. %.2f mm." ),
3648 if( abs( hcode.
Hatches.at( 0 ).OrientAngle - hcode.
Hatches.at( 1 ).OrientAngle ) != 90000 )
3650 reportWarning( wxString::Format(
_(
"The hatches in CADSTAR Hatching code '%s' have an angle "
3651 "difference of %.1f degrees. KiCad only supports hatching 90 "
3652 "degrees apart. The imported hatching has two hatches 90 "
3653 "degrees apart, oriented %.1f degrees from horizontal." ),
3656 - hcode.
Hatches.at( 1 ).OrientAngle ) ).AsDegrees(),
3681 wxString prefix = wxEmptyString;
3682 wxString suffix = wxEmptyString;
3683 int startpos = aCadstarDim.
Text.
Text.Find( wxT(
"<@DISTANCE" ) );
3685 if( startpos != wxNOT_FOUND )
3688 wxString remainingStr = aCadstarDim.
Text.
Text.Mid( startpos );
3689 int endpos = remainingStr.Find(
"@>" );
3693 if( suffix.StartsWith( wxT(
"mm" ) ) )
3696 suffix = suffix.Mid( 2 );
3714 switch( dimensionUnits )
3719 reportWarning( wxString::Format(
_(
"Dimension ID %s uses a type of unit that is not supported in KiCad. "
3720 "Millimeters were applied instead." ),
3736 wxFAIL_MSG( wxT(
"We should have handled design units before coming here!" ) );
3744 std::map<TEMPLATE_ID, std::set<TEMPLATE_ID>> winningOverlaps;
3750 -
m_board->GetDesignSettings().m_MinClearance;
3752 int retval = std::max( aZoneA->
GetLocalClearance().value(), aZoneB->GetLocalClearance().value() );
3761 [&](
ZONE* aLowerZone,
ZONE* aHigherZone ) ->
double
3774 double leftOverArea = lowerZoneFill.
Area();
3776 return leftOverArea;
3779 auto intersectionAreaOfZoneOutlines =
3780 [&](
ZONE* aZoneA,
ZONE* aZoneB ) ->
double
3792 return outLineA.
Area();
3796 auto isLowerPriority =
3799 return winningOverlaps[b].count( a ) > 0;
3802 for( std::map<TEMPLATE_ID, ZONE*>::iterator it1 =
m_zonesMap.begin(); it1 !=
m_zonesMap.end(); ++it1 )
3805 ZONE* thisZone = it1->second;
3810 for( std::map<TEMPLATE_ID, ZONE*>::iterator it2 = it1;
3814 ZONE* otherZone = it2->second;
3816 if( thisTemplate.
ID == otherTemplate.
ID )
3825 if( intersectionAreaOfZoneOutlines( thisZone, otherZone ) == 0 )
3834 if( thisZonePolyFill.
Area() > 0.0 && otherZonePolyFill.
Area() > 0.0 )
3837 double areaThis = errorArea( thisZone, otherZone );
3839 double areaOther = errorArea( otherZone, thisZone );
3841 if( areaThis > areaOther )
3844 winningOverlaps[thisTemplate.
ID].insert( otherTemplate.
ID );
3849 winningOverlaps[otherTemplate.
ID].insert( thisTemplate.
ID );
3852 else if( thisZonePolyFill.
Area() > 0.0 )
3855 winningOverlaps[thisTemplate.
ID].insert( otherTemplate.
ID );
3857 else if( otherZonePolyFill.
Area() > 0.0 )
3860 winningOverlaps[otherTemplate.
ID].insert( thisTemplate.
ID );
3866 if( intersectionAreaOfZoneOutlines( thisZone, otherZone ) != 0 )
3869 winningOverlaps[otherTemplate.
ID].insert( thisTemplate.
ID );
3871 winningOverlaps[thisTemplate.
ID].insert( otherTemplate.
ID );
3880 std::set<TEMPLATE_ID> intersectingIDs;
3882 for(
const auto& idPair : winningOverlaps )
3884 intersectingIDs.insert( idPair.first );
3885 intersectingIDs.insert( idPair.second.begin(), idPair.second.end() );
3889 std::vector<TEMPLATE_ID> sortedIDs;
3893 sortedIDs.push_back(
id );
3897 std::sort( sortedIDs.begin(), sortedIDs.end(), isLowerPriority );
3903 if( prevID.IsEmpty() )
3909 wxASSERT( !isLowerPriority(
id, prevID ) );
3911 int newPriority =
m_zonesMap.at( prevID )->GetAssignedPriority();
3914 if( isLowerPriority( prevID,
id ) )
3917 m_zonesMap.at(
id )->SetAssignedPriority( newPriority );
3922 for(
const auto& idPair : winningOverlaps )
3926 for(
const TEMPLATE_ID& losingID : idPair.second )
3928 if(
m_zonesMap.at( losingID )->GetAssignedPriority() >
m_zonesMap.at( winningID )->GetAssignedPriority() )
3959 if( aCadstarNetID.IsEmpty() )
3965 return m_netMap.at( aCadstarNetID );
3969 wxCHECK(
Layout.Nets.find( aCadstarNetID ) !=
Layout.Nets.end(),
nullptr );
3972 wxString newName = csNet.
Name;
3974 if( csNet.
Name.IsEmpty() )
3976 if( csNet.
Pins.size() > 0 )
3980 NET_PCB::PIN firstPin = ( *csNet.
Pins.begin() ).second;
3983 newName = wxT(
"Net-(" );
3985 newName << wxT(
"-Pad" ) << wxString::Format( wxT(
"%ld" ), firstPin.PadID );
3986 newName << wxT(
")" );
3990 wxFAIL_MSG( wxT(
"A net with no pins associated?" ) );
3991 newName = wxT(
"csNet-" );
3992 newName << wxString::Format( wxT(
"%i" ), csNet.
SignalNum );
3998 reportInfo(
_(
"The CADSTAR design contains nets with a 'Net Class' assigned. KiCad "
3999 "does not have an equivalent to CADSTAR's Net Class so these elements "
4000 "were not imported. Note: KiCad's version of 'Net Class' is closer to "
4001 "CADSTAR's 'Net Route Code' (which has been imported for all nets)." ) );
4007 reportWarning(
_(
"The CADSTAR design contains nets with a 'Spacing Class' assigned. "
4008 "KiCad does not have an equivalent to CADSTAR's Spacing Class so "
4009 "these elements were not imported. Please review the design rules as "
4010 "copper pours may be affected by this." ) );
4014 std::shared_ptr<NET_SETTINGS>& netSettings =
m_board->GetDesignSettings().m_NetSettings;
4016 std::shared_ptr<NETCLASS> netclass;
4018 std::tuple<ROUTECODE_ID, NETCLASS_ID, SPACING_CLASS_ID> key = { csNet.
RouteCodeID,
4028 && rcIt->second.OptimalWidth > 0 )
4030 wxString netClassName;
4033 netClassName += wxT(
"Route code: " ) + rc.
Name;
4038 netClassName += wxT(
" | Net class: " ) + nc.
Name;
4044 netClassName += wxT(
" | Spacing class: " ) + sp.
Name;
4047 netclass.reset(
new NETCLASS( netClassName ) );
4048 netSettings->SetNetclass( netClassName, netclass );
4056 netclass = netSettings->GetDefaultNetclass();
4059 m_board->GetDesignSettings().m_NetSettings->SetNetclassPatternAssignment( newName, netclass->GetName() );
4063 m_netMap.insert( { aCadstarNetID, netInfo } );
4116 wxCHECK(
Assignments.Layerdefs.Layers.find( aCadstarLayerID ) !=
Assignments.Layerdefs.Layers.end(),
false );
4120 switch( layer.
Type )
4184 parentGroup->
AddItem( aKiCadItem );
4190 wxString groupName = aName;
4194 groupName = aName + wxT(
"_" ) + wxString::Format( wxT(
"%i" ), ++num );
4198 docSymGroup->
SetName( groupName );
4200 m_groupMap.insert( { groupID, docSymGroup } );
constexpr double PCB_IU_PER_MM
Pcbnew IU is 1 nanometer.
constexpr EDA_IU_SCALE pcbIUScale
LAYER_T
The allowed types of layers, same as Specctra DSN spec.
@ BS_ITEM_TYPE_SILKSCREEN
@ BS_ITEM_TYPE_DIELECTRIC
@ BS_ITEM_TYPE_SOLDERMASK
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
#define CADSTAR_FONT_NAME
file: cadstar_archive_objects.h Contains common object definitions
#define COMPONENT_NAME_2_ATTRID
Component Name 2 Attribute ID - typically used for indicating the placement of designators in placeme...
#define COMPONENT_NAME_ATTRID
Component Name Attribute ID - typically used for placement of designators on silk screen.
Loads a cpa file into a KiCad BOARD object.
BASE_SET & reset(size_t pos)
virtual bool SetNetCode(int aNetCode, bool aNoAssert)
Set net using a net code.
PCB_LAYER_ID GetLayer() const override
Return the primary layer this item is on.
virtual void SetNet(NETINFO_ITEM *aNetInfo)
Set a NET_INFO object for the item.
void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
NETINFO_ITEM * GetNet() const
Return NETINFO_ITEM object for a given item.
Container for design settings for a BOARD object.
std::shared_ptr< NET_SETTINGS > m_NetSettings
int m_CopperEdgeClearance
BOARD_STACKUP & GetStackupDescriptor()
void SetBoardThickness(int aThickness)
int GetLineThickness(PCB_LAYER_ID aLayer) const
Return the default graphic segment thickness from the layer class for the given layer.
int m_ViasMinAnnularWidth
Abstract interface for BOARD_ITEMs capable of storing other items inside.
virtual void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false)=0
Adds an item to the container.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
virtual BOARD_ITEM * Duplicate(bool addToParentGroup, BOARD_COMMIT *aCommit=nullptr) const
Create a copy of this BOARD_ITEM.
void SetLocked(bool aLocked) override
bool IsLocked() const override
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Manage one layer needed to make a physical board.
void SetThickness(int aThickness, int aDielectricSubLayer=0)
void SetMaterial(const wxString &aName, int aDielectricSubLayer=0)
void SetLossTangent(double aTg, int aDielectricSubLayer=0)
void SetEpsilonR(double aEpsilon, int aDielectricSubLayer=0)
void SetLayerName(const wxString &aName)
Manage layers needed to make a physical board.
void RemoveAll()
Delete all items in list and clear the list.
const std::vector< BOARD_STACKUP_ITEM * > & GetList() const
int BuildBoardThicknessFromStackup() const
void BuildDefaultStackupList(const BOARD_DESIGN_SETTINGS *aSettings, int aActiveCopperLayersCount=0)
Create a default stackup, according to the current BOARD_DESIGN_SETTINGS settings.
@ ANTICLOCKWISE_SEMICIRCLE
static const long FONT_BOLD
static const std::map< TEXT_FIELD_NAME, wxString > CADSTAR_TO_KICAD_FIELDS
Map between CADSTAR fields and KiCad text variables.
TEXT_FIELD_NAME
These are special fields in text objects enclosed between the tokens '<@' and '>' such as <@[FIELD_NA...
@ NO_ALIGNMENT
NO_ALIGNMENT has different meaning depending on the object type.
static const long UNDEFINED_VALUE
static wxString ParseTextFields(const wxString &aTextString, PARSER_CONTEXT *aParserContext)
Replaces CADSTAR fields for the equivalent in KiCad and stores the field values in aParserContext.
wxString LAYER_ID
ID of a Sheet (if schematic) or board Layer (if PCB)
static void FixTextPositionNoAlignment(EDA_TEXT *aKiCadTextItem)
Correct the position of a text element that had NO_ALIGNMENT in CADSTAR.
@ OUTLINE
Unfilled closed shape.
@ OPENSHAPE
Unfilled open shape. Cannot have cutouts.
@ SOLID
Filled closed shape (solid fill).
@ HATCHED
Filled closed shape (hatch fill).
static const double TXT_HEIGHT_RATIO
CADSTAR fonts are drawn on a 24x24 integer matrix, where the each axis goes from 0 to 24.
void checkPoint()
Updates m_progressReporter or throws if user canceled.
@ DESIGN
Inherits from design units (assumed Assignments->Technology->Units)
PROGRESS_REPORTER * m_progressReporter
std::map< TEMPLATE_ID, ZONE * > m_zonesMap
Map between Cadstar and KiCad zones.
std::map< std::tuple< ROUTECODE_ID, NETCLASS_ID, SPACING_CLASS_ID >, std::shared_ptr< NETCLASS > > m_netClassMap
Map between Cadstar and KiCad classes.
bool m_doneCopperWarning
Used by loadCoppers() to avoid multiple duplicate warnings.
std::vector< std::unique_ptr< FOOTPRINT > > LoadFpLibrary()
Parse a CADSTAR PCB Archive and load the footprints contained within.
std::set< PADCODE_ID > m_padcodesTested
Used by getKiCadPad() to avoid multiple duplicate warnings.
void drawCadstarVerticesAsShapes(const std::vector< VERTEX > &aCadstarVertices, const PCB_LAYER_ID &aKiCadLayer, int aLineThickness, LINE_STYLE aLineStyle, BOARD_ITEM_CONTAINER *aContainer, const GROUP_ID &aCadstarGroupID=wxEmptyString, const VECTOR2I &aMoveVector={ 0, 0 }, double aRotationAngle=0.0, double aScalingFactor=1.0, const VECTOR2I &aTransformCentre={ 0, 0 }, bool aMirrorInvert=false)
Uses PCB_SHAPE to draw the vertices on m_board object.
void initStackupItem(const LAYER &aCadstarLayer, BOARD_STACKUP_ITEM *aKiCadItem, int aDielectricSublayer)
int m_numCopperLayers
Number of layers in the design.
void reportError(const wxString &aMsg) const
Report an import issue the user can act on.
std::vector< LAYER_ID > m_powerPlaneLayers
List of layers that are marked as power plane in CADSTAR.
void drawCadstarText(const TEXT &aCadstarText, BOARD_ITEM_CONTAINER *aContainer, const GROUP_ID &aCadstarGroupID=wxEmptyString, const LAYER_ID &aCadstarLayerOverride=wxEmptyString, const VECTOR2I &aMoveVector={ 0, 0 }, double aRotationAngle=0.0, double aScalingFactor=1.0, const VECTOR2I &aTransformCentre={ 0, 0 }, bool aMirrorInvert=false)
bool isLayerSet(const LAYER_ID &aCadstarLayerID)
LAYERPAIR getLayerPair(const LAYERPAIR_ID &aCadstarLayerPairID)
FOOTPRINT * getFootprintFromCadstarID(const COMPONENT_ID &aCadstarComponentID)
PADCODE getPadCode(const PADCODE_ID &aCadstarPadCodeID)
int loadNetVia(const NET_ID &aCadstarNetID, const NET_PCB::VIA &aCadstarVia)
Load via and return via size.
EDA_ANGLE getAngle(const long long &aCadstarAngle)
std::vector< PCB_SHAPE * > getShapesFromVertices(const std::vector< VERTEX > &aCadstarVertices, BOARD_ITEM_CONTAINER *aContainer=nullptr, const GROUP_ID &aCadstarGroupID=wxEmptyString, const VECTOR2I &aMoveVector={ 0, 0 }, double aRotationAngle=0.0, double aScalingFactor=1.0, const VECTOR2I &aTransformCentre={ 0, 0 }, bool aMirrorInvert=false)
Returns a vector of pointers to PCB_SHAPE objects.
void applyTextCode(EDA_TEXT *aKiCadText, const TEXTCODE_ID &aCadstarTextCodeID)
Apply cadstar textcode parameters to a KiCad text object.
std::map< COMPONENT_ID, FOOTPRINT * > m_componentMap
Map between Cadstar and KiCad components on the board.
SHAPE_LINE_CHAIN getLineChainFromShapes(const std::vector< PCB_SHAPE * > &aShapes)
Returns a SHAPE_LINE_CHAIN object from a series of PCB_SHAPE objects.
std::map< PAD_ID, std::vector< PAD_ID > > ASSOCIATED_COPPER_PADS
Map of pad anchor points (first) to copper pads (second).
void applyDimensionSettings(const DIMENSION &aCadstarDim, PCB_DIMENSION_BASE *aKiCadDim)
ZONE * getZoneFromCadstarShape(const SHAPE &aCadstarShape, const int &aLineThickness, BOARD_ITEM_CONTAINER *aParentContainer)
void drawCadstarShape(const SHAPE &aCadstarShape, const PCB_LAYER_ID &aKiCadLayer, int aLineThickness, LINE_STYLE aLineStyle, const wxString &aShapeName, BOARD_ITEM_CONTAINER *aContainer, const GROUP_ID &aCadstarGroupID=wxEmptyString, const VECTOR2I &aMoveVector={ 0, 0 }, double aRotationAngle=0.0, double aScalingFactor=1.0, const VECTOR2I &aTransformCentre={ 0, 0 }, bool aMirrorInvert=false)
PCB_LAYER_ID getKiCadCopperLayerID(unsigned int aLayerNum, bool aDetectMaxLayer=true)
void reportInfo(const wxString &aMsg) const
std::vector< PCB_TRACK * > makeTracksFromShapes(const std::vector< PCB_SHAPE * > &aShapes, BOARD_ITEM_CONTAINER *aParentContainer, NETINFO_ITEM *aNet=nullptr, PCB_LAYER_ID aLayerOverride=UNDEFINED_LAYER, int aWidthOverride=-1)
Returns a vector of pointers to TRACK/ARC objects.
VIACODE getViaCode(const VIACODE_ID &aCadstarViaCodeID)
VECTOR2I m_designCenter
Used for calculating the required offset to apply to the Cadstar design so that it fits in KiCad canv...
void Load(BOARD *aBoard, PROJECT *aProject)
Loads a CADSTAR PCB Archive file into the KiCad BOARD object given.
void drawCadstarCutoutsAsShapes(const std::vector< CUTOUT > &aCutouts, const PCB_LAYER_ID &aKiCadLayer, int aLineThickness, BOARD_ITEM_CONTAINER *aContainer, const GROUP_ID &aCadstarGroupID=wxEmptyString, const VECTOR2I &aMoveVector={ 0, 0 }, double aRotationAngle=0.0, double aScalingFactor=1.0, const VECTOR2I &aTransformCentre={ 0, 0 }, bool aMirrorInvert=false)
Uses PCB_SHAPEs to draw the cutouts on m_board object.
void logBoardStackupWarning(const wxString &aCadstarLayerName, const PCB_LAYER_ID &aKiCadLayer)
VECTOR2I applyPadShape(PAD *aPad, PCB_LAYER_ID aPadLayer, const CADSTAR_PAD_SHAPE &aShape)
Apply a CADSTAR pad shape to a single layer of a KiCad padstack.
std::vector< FOOTPRINT * > GetLoadedLibraryFootpints() const
Return a copy of the loaded library footprints (caller owns the objects)
PCB_SHAPE * getShapeFromVertex(const POINT &aCadstarStartPoint, const VERTEX &aCadstarVertex, BOARD_ITEM_CONTAINER *aContainer=nullptr, const GROUP_ID &aCadstarGroupID=wxEmptyString, const VECTOR2I &aMoveVector={ 0, 0 }, double aRotationAngle=0.0, double aScalingFactor=1.0, const VECTOR2I &aTransformCentre={ 0, 0 }, bool aMirrorInvert=false)
Returns a pointer to a PCB_SHAPE object.
void checkAndLogHatchCode(const HATCHCODE_ID &aCadstarHatchcodeID)
bool m_doneSpacingClassWarning
Used by getKiCadNet() to avoid multiple duplicate warnings.
int m_numNets
Number of nets loaded so far.
void loadDocumentationSymbols()
void loadLibraryPads(const SYMDEF_PCB &aComponent, FOOTPRINT *aFootprint)
void loadComponentLibrary()
PAD * getKiCadPad(const COMPONENT_PAD &aCadstarPad, FOOTPRINT *aParent)
NETINFO_ITEM * getKiCadNet(const NET_ID &aCadstarNetID)
Searches m_netMap and returns the NETINFO_ITEM pointer if exists.
void logBoardStackupMessage(const wxString &aCadstarLayerName, const PCB_LAYER_ID &aKiCadLayer)
int getLineThickness(const LINECODE_ID &aCadstarLineCodeID)
bool m_doneTearDropWarning
std::map< NET_ID, NETINFO_ITEM * > m_netMap
Map between Cadstar and KiCad Nets.
void loadComponentAttributes(const COMPONENT &aComponent, FOOTPRINT *aFootprint)
void loadNetTracks(const NET_ID &aCadstarNetID, const NET_PCB::ROUTE &aCadstarRoute, long aDefaultRouteWidth, long aStartWidth=std::numeric_limits< long >::max(), long aEndWidth=std::numeric_limits< long >::max())
PCB_GROUP * getKiCadGroup(const GROUP_ID &aCadstarGroupID)
bool m_logLayerWarnings
Used in loadBoardStackup()
HATCHCODE getHatchCode(const HATCHCODE_ID &aCadstarHatchcodeID)
void loadLibraryCoppers(const SYMDEF_PCB &aComponent, FOOTPRINT *aFootprint)
LAYER_TYPE getLayerType(const LAYER_ID aCadstarLayerID)
void loadLibraryFigures(const SYMDEF_PCB &aComponent, FOOTPRINT *aFootprint)
TEXTCODE getTextCode(const TEXTCODE_ID &aCadstarTextCodeID)
void reportWarning(const wxString &aMsg) const
wxString getAttributeName(const ATTRIBUTE_ID &aCadstarAttributeID)
int getKiCadOffset(long long aCadstarLength)
wxString getAttributeValue(const ATTRIBUTE_ID &aCadstarAttributeID, const std::map< ATTRIBUTE_ID, ATTRIBUTE_VALUE > &aCadstarAttributeMap)
void applyRouteOffset(VECTOR2I *aPointToOffset, const VECTOR2I &aRefPoint, const long &aOffsetAmount)
CADSTAR's Post Processor does an action called "Route Offset" which is applied when a route is wider ...
VECTOR2I getKiCadPoint(const VECTOR2I &aCadstarPoint)
Scales, offsets and inverts y axis to make the point usable directly in KiCad.
void remapUnsureLayers()
Callback m_layerMappingHandler for layers we aren't sure of.
double getAngleTenthDegree(const long long &aCadstarAngle)
LSET getKiCadLayerSet(const LAYER_ID &aCadstarLayerID)
void addToGroup(const GROUP_ID &aCadstarGroupID, BOARD_ITEM *aKiCadItem)
std::map< SYMDEF_ID, FOOTPRINT * > m_libraryMap
Map between Cadstar and KiCad components in the library.
COPPERCODE getCopperCode(const COPPERCODE_ID &aCadstaCopperCodeID)
SHAPE_POLY_SET getPolySetFromCadstarShape(const SHAPE &aCadstarShape, int aLineThickness=-1, BOARD_ITEM_CONTAINER *aContainer=nullptr, const VECTOR2I &aMoveVector={ 0, 0 }, double aRotationAngle=0.0, double aScalingFactor=1.0, const VECTOR2I &aTransformCentre={ 0, 0 }, bool aMirrorInvert=false)
Returns a SHAPE_POLY_SET object from a Cadstar SHAPE.
EDA_ANGLE getHatchCodeAngle(const HATCHCODE_ID &aCadstarHatchcodeID)
int getKiCadHatchCodeThickness(const HATCHCODE_ID &aCadstarHatchcodeID)
PCB_LAYER_ID getKiCadLayer(const LAYER_ID &aCadstarLayerID)
std::set< HATCHCODE_ID > m_hatchcodesTested
Used by checkAndLogHatchCode() to avoid multiple duplicate warnings.
void loadLibraryAreas(const SYMDEF_PCB &aComponent, FOOTPRINT *aFootprint)
GROUP_ID createUniqueGroupID(const wxString &aName)
Adds a new PCB_GROUP* to m_groupMap.
LINE_STYLE getLineStyle(const LINECODE_ID &aCadstarLineCodeID)
int getKiCadHatchCodeGap(const HATCHCODE_ID &aCadstarHatchcodeID)
ROUTECODE getRouteCode(const ROUTECODE_ID &aCadstarRouteCodeID)
int getKiCadLength(long long aCadstarLength, double aDefaultInMM)
void addAttribute(const ATTRIBUTE_LOCATION &aCadstarAttrLoc, const ATTRIBUTE_ID &aCadstarAttributeID, FOOTPRINT *aFootprint, const wxString &aAttributeValue)
Adds a CADSTAR Attribute to a KiCad footprint.
std::map< GROUP_ID, PCB_GROUP * > m_groupMap
Map between Cadstar and KiCad groups.
bool calculateZonePriorities(PCB_LAYER_ID &aLayer)
Tries to make a best guess as to the zone priorities based on the pour status.
std::map< LAYER_ID, PCB_LAYER_ID > m_layermap
Map between Cadstar and KiCad Layers.
PAD *& getPadReference(FOOTPRINT *aFootprint, const PAD_ID aCadstarPadID)
bool m_doneNetClassWarning
Used by getKiCadNet() to avoid multiple duplicate warnings.
double getAngleDegrees(const long long &aCadstarAngle)
PART getPart(const PART_ID &aCadstarPartID)
LAYER_MAPPING_HANDLER m_layerMappingHandler
Callback to get layer mapping.
std::map< SYMDEF_ID, ASSOCIATED_COPPER_PADS > m_librarycopperpads
Associated copper pads (if any) for each component library definition.
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.
@ UNDEFINED
Only used for error detection.
@ 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".
@ MAXIMUM
The highest PHYSICAL_LAYER_ID currently defined (i.e.
@ MINIMUM
PHYSICAL_LAYER_ID 1 (i.e.
@ THROUGH_HOLE
All physical layers currently defined.
EDA_ANGLE NormalizeNegative()
void AddItem(EDA_ITEM *aItem)
Add item to group.
void SetName(const wxString &aName)
void SetFillMode(FILL_T aFill)
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
virtual void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true)
virtual const wxString & GetText() const
Return the string associated with the text object.
virtual void SetTextPos(const VECTOR2I &aPoint)
void SetMirrored(bool isMirrored)
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
virtual void SetVisible(bool aVisible)
void MigrateLegacyBoldStrokeWidth()
Migrate a pre-v11 bold stroke text so its stored thickness holds the base (non-bold) width.
virtual void SetTextThickness(int aWidth)
The TextThickness is that set by the user.
void SetBold(bool aBold)
Set the text to be bold - this will also update the font if needed.
void SetKeepUpright(bool aKeepUpright)
virtual void SetText(const wxString &aText)
void SetItalic(bool aItalic)
Set the text to be italic - this will also update the font if needed.
void SetFont(KIFONT::FONT *aFont)
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
FONT is an abstract base class for both outline and stroke fonts.
static FONT * GetFont(const wxString &aFontName=wxEmptyString, bool aBold=false, bool aItalic=false, const std::vector< wxString > *aEmbeddedFiles=nullptr, bool aForDrawingSheet=false)
A logical library item identifier and consists of various portions much like a URI.
int Parse(const UTF8 &aId, bool aFix=false)
Parse LIB_ID with the information from aId.
const UTF8 & GetLibItemName() const
LSEQ is a sequence (and therefore also a set) of PCB_LAYER_IDs.
LSET is a set of PCB_LAYER_IDs.
static const LSET & AllBoardTechMask()
Return a mask holding board technical layers (no CU layer) on both side.
static const LSET & AllCuMask()
return AllCuMask( MAX_CU_LAYERS );
static const LSET & UserMask()
LSEQ Seq(const LSEQ &aSequence) const
Return an LSEQ from the union of this LSET and a desired sequence.
static LSET AllCuMask(int aCuLayerCount)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
static const LSET & AllLayersMask()
static LSET UserDefinedLayersMask(int aUserDefinedLayerCount=MAX_USER_DEFINED_LAYERS)
Return a mask with the requested number of user defined layers.
static wxString Name(PCB_LAYER_ID aLayerId)
Return the fixed name association with aLayerId.
bool Contains(PCB_LAYER_ID aLayer) const
See if the layer set contains a PCB layer.
Handle the data for a net.
void SetNetClass(const std::shared_ptr< NETCLASS > &aNetClass)
std::shared_ptr< NETCLASS > GetDefaultNetclass() const
Gets the default netclass for the project.
@ NORMAL
Shape is the same on all layers.
@ CUSTOM
Shapes can be defined on arbitrary layers.
static constexpr PCB_LAYER_ID ALL_LAYERS
! The layer identifier to use for the single defintion on normal padstacks
static constexpr PCB_LAYER_ID TEMP_ALL_LAYERS
! Temporary layer identifier to identify code that is not padstack-aware
const wxString & GetNumber() const
void SetShape(PCB_LAYER_ID aLayer, PAD_SHAPE aShape)
Set the new shape of this pad.
void SetNumber(const wxString &aNumber)
Set the pad number (note that it can be alphanumeric, such as the array reference "AA12").
void SetChamferRectRatio(PCB_LAYER_ID aLayer, double aChamferScale)
Has meaning only for chamfered rectangular pads.
void SetSize(PCB_LAYER_ID aLayer, const VECTOR2I &aSize)
void SetRoundRectCornerRadius(PCB_LAYER_ID aLayer, double aRadius)
void SetChamferPositions(PCB_LAYER_ID aLayer, int aPositions)
Has meaning only for chamfered rectangular pads.
void SetRoundRectRadiusRatio(PCB_LAYER_ID aLayer, double aRadiusScale)
Has meaning only for rounded rectangle pads.
virtual void SetEnd(const VECTOR2I &aPoint)
void SetUnitsFormat(const DIM_UNITS_FORMAT aFormat)
virtual void SetStart(const VECTOR2I &aPoint)
void SetPrefix(const wxString &aPrefix)
void SetExtensionOffset(int aOffset)
void SetSuffix(const wxString &aSuffix)
void SetLineThickness(int aWidth)
void SetPrecision(DIM_PRECISION aPrecision)
void SetOverrideText(const wxString &aValue)
virtual VECTOR2I GetStart() const
The dimension's origin is the first feature point for the dimension.
void SetUnitsMode(DIM_UNITS_MODE aMode)
For better understanding of the points that make a dimension:
void SetExtensionHeight(int aHeight)
void SetHeight(int aHeight)
Set the distance from the feature points to the crossbar line.
A leader is a dimension-like object pointing to a specific point.
An orthogonal dimension is like an aligned dimension, but the extension lines are locked to the X or ...
void SetOrientation(DIR aOrientation)
Set the orientation of the dimension line (so, perpendicular to the feature lines).
A set of BOARD_ITEMs (i.e., without duplicates).
void SetLocked(bool aLocked) override
void SetCenter(const VECTOR2I &aCenter) override
void Rotate(const VECTOR2I &aRotCentre, const EDA_ANGLE &aAngle) override
Rotate this object.
void SetArcAngleAndEnd(const EDA_ANGLE &aAngle, bool aCheckNegativeAngle=false)
void SetEnd(const VECTOR2I &aEnd) override
void Flip(const VECTOR2I &aCentre, FLIP_DIRECTION aFlipDirection) override
Flip this object, i.e.
void SetPolyShape(const SHAPE_POLY_SET &aShape) override
void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
void Move(const VECTOR2I &aMoveVector) override
Move this object.
void SetStart(const VECTOR2I &aStart) override
void Scale(double aScale)
void SetStroke(const STROKE_PARAMS &aStroke) override
void SetTextThickness(int aWidth) override
The TextThickness is that set by the user.
void Flip(const VECTOR2I &aCentre, FLIP_DIRECTION aFlipDirection) override
Flip this object, i.e.
EDA_ANGLE GetTextAngle() const override
void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true) override
void SetPosition(const VECTOR2I &aPos) override
void Move(const VECTOR2I &aMoveVector) override
Move this object.
int GetTextThickness() const override
void SetTextAngle(const EDA_ANGLE &aAngle) override
VECTOR2I GetTextSize() const override
void SetEnd(const VECTOR2I &aEnd)
void SetStart(const VECTOR2I &aStart)
const VECTOR2I & GetStart() const
const VECTOR2I & GetEnd() const
virtual void SetWidth(int aWidth)
virtual int GetWidth() const
Container for project specific data.
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
Report a string with a given severity.
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
virtual const VECTOR2I GetPoint(int aIndex) const override
void SetClosed(bool aClosed)
Mark the line chain as closed (i.e.
int PointCount() const
Return the number of points (vertices) in this line chain.
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
Represent a set of closed polygons.
void BooleanAdd(const SHAPE_POLY_SET &b)
Perform boolean polyset union.
void ClearArcs()
Removes all arc references from all the outlines and holes in the polyset.
double Area()
Return the area of this poly set.
void Inflate(int aAmount, CORNER_STRATEGY aCornerStrategy, int aMaxError, bool aSimplify=false)
Perform outline inflation/deflation.
int HoleCount(int aOutline) const
Returns the number of holes in a given outline.
int AddHole(const SHAPE_LINE_CHAIN &aHole, int aOutline=-1)
Adds a new hole to the given outline (default: last) and returns its index.
SHAPE_LINE_CHAIN & Outline(int aIndex)
Return the reference to aIndex-th outline in the set.
SHAPE_LINE_CHAIN & Hole(int aOutline, int aHole)
Return the reference to aHole-th hole in the aIndex-th outline.
void BooleanIntersection(const SHAPE_POLY_SET &b)
Perform boolean polyset intersection.
const SHAPE_LINE_CHAIN & CHole(int aOutline, int aHole) const
int OutlineCount() const
Return the number of outlines in the set.
void Move(const VECTOR2I &aVector) override
void Fracture(bool aSimplify=true)
Convert a set of polygons with holes to a single outline with "slits"/"fractures" connecting the oute...
void BooleanSubtract(const SHAPE_POLY_SET &b)
Perform boolean polyset difference.
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
virtual VECTOR2I GetStart() const
Simple container to manage line stroke parameters.
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
VECTOR2< T > Resize(T aNewLength) const
Return a vector of the same direction, but length specified in aNewLength.
Handle a list of polygons defining a copper zone.
void SetHatchThickness(int aThickness)
void SetNeedRefill(bool aNeedRefill)
void SetDoNotAllowPads(bool aEnable)
std::optional< int > GetLocalClearance() const override
void SetLocalClearance(std::optional< int > aClearance)
void AddPolygon(std::vector< VECTOR2I > &aPolygon)
Add a polygon to the zone outline.
std::shared_ptr< SHAPE_POLY_SET > GetFilledPolysList(PCB_LAYER_ID aLayer) const
void SetMinThickness(int aMinThickness)
void SetHatchOrientation(const EDA_ANGLE &aStep)
void SetThermalReliefSpokeWidth(int aThermalReliefSpokeWidth)
virtual void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
SHAPE_POLY_SET * Outline()
void SetHatchStyle(ZONE_BORDER_DISPLAY_STYLE aStyle)
SHAPE_POLY_SET * GetFill(PCB_LAYER_ID aLayer)
void SetIsRuleArea(bool aEnable)
void SetDoNotAllowTracks(bool aEnable)
void SetFilledPolysList(PCB_LAYER_ID aLayer, const SHAPE_POLY_SET &aPolysList)
Set the list of filled polygons.
void SetIsFilled(bool isFilled)
void SetFillMode(ZONE_FILL_MODE aFillMode)
bool HasFilledPolysForLayer(PCB_LAYER_ID aLayer) const
void SetLayerSet(const LSET &aLayerSet) override
void SetDoNotAllowVias(bool aEnable)
void SetNet(NETINFO_ITEM *aNetInfo) override
Override that drops aNetInfo when this zone is in copper-thieving fill mode.
void SetThermalReliefGap(int aThermalReliefGap)
virtual LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
void SetDoNotAllowFootprints(bool aEnable)
void SetDoNotAllowZoneFills(bool aEnable)
void SetAssignedPriority(unsigned aPriority)
void SetPadConnection(ZONE_CONNECTION aPadConnection)
void SetZoneName(const wxString &aName)
void SetIslandRemovalMode(ISLAND_REMOVAL_MODE aRemove)
void SetMinIslandArea(long long int aArea)
void SetHatchGap(int aStep)
static REPORTER & GetReporter()
Get the current reporter used for font substitution warnings.
void TransformArcToPolygon(SHAPE_POLY_SET &aBuffer, const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd, int aWidth, int aError, ERROR_LOC aErrorLoc)
Convert arc to multiple straight segments.
void TransformOvalToPolygon(SHAPE_POLY_SET &aBuffer, const VECTOR2I &aStart, const VECTOR2I &aEnd, int aWidth, int aError, ERROR_LOC aErrorLoc, int aMinSegCount=0)
Convert a oblong shape to a polygon, using multiple segments.
@ RECT_CHAMFER_BOTTOM_LEFT
@ ROUND_ALL_CORNERS
All angles are rounded.
static constexpr EDA_ANGLE ANGLE_90
static constexpr EDA_ANGLE ANGLE_180
@ FILLED_SHAPE
Fill with object color.
#define IGNORE_PARENT_GROUP
#define DEFAULT_SIZE_TEXT
This is the "default-of-the-default" hardcoded text size; individual application define their own def...
#define THROW_IO_ERRORF(msg,...)
bool IsCopperLayer(int aLayerId)
Test whether a layer is a copper layer.
PCB_LAYER_ID
A quick note on layer IDs:
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 ...
@ LEFT_RIGHT
Flip left to right (around the Y axis)
constexpr int Mils2IU(const EDA_IU_SCALE &aIuScale, int mils)
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
@ NPTH
like PAD_PTH, but not plated mechanical use only, no connection allowed
@ SMD
Smd pad, appears on the solder paste layer (default)
@ PTH
Plated through hole pad.
Class to handle a set of BOARD_ITEMs.
LINE_STYLE
Dashed line types.
ALIGNMENT Alignment
In CADSTAR The default alignment for a TEXT object (when "(No Alignment()" is selected) Bottom Left o...
ATTRIBUTE_LOCATION AttributeLocation
bool HasLocation
Flag to know if this ATTRIBUTE_VALUE has a location i.e.
Represent a cutout in a closed shape (e.g.
std::vector< VERTEX > Vertices
long ScaleRatioNumerator
Documentation symbols can be arbitrarily scaled when added to a design.
long ScaleRatioDenominator
Documentation symbols can be arbitrarily scaled when added to a design.
POINT Origin
Origin of the component (this is used as the reference point when placing the component in the design...
LAYER_ID LayerID
Move all objects in the Symdef to this layer.
SYMDEF_ID SymdefID
Normally documentation symbols only have TEXT, FIGURE and TEXT_LOCATION objects which are all drawn o...
long Modifier1
It seems this is related to weight. 400=Normal, 700=Bold.
GROUP_ID GroupID
If not empty, this GROUP is part of another GROUP.
std::vector< HATCH > Hatches
ROUTECODE_ID RouteCodeID
"NETCODE" subnode
wxString Name
This is undefined (wxEmptyString) if the net is unnamed.
NETCLASS_ID NetClassID
The net might not have a net class, in which case it will be wxEmptyString subnode="NETCLASSREF".
SPACING_CLASS_ID SpacingClassID
The net might not have a spacing class, in which case it will be wxEmptyString subnode="SPACINGCLASS"...
long SignalNum
This is undefined if the net has been given a name.
wxString Name
This name can be different to the PART name.
std::map< PART_DEFINITION_PIN_ID, PIN > Pins
Represent a point in x,y coordinates.
std::vector< VERTEX > Vertices
wxString HatchCodeID
Only Applicable for HATCHED Type.
std::vector< CUTOUT > Cutouts
Not Applicable to OPENSHAPE Type.
std::map< FIGURE_ID, FIGURE > Figures
POINT Origin
Origin of the component (this is used as the reference point when placing the component in the design...
wxString Alternate
This is in addition to ReferenceName.
std::map< TEXT_ID, TEXT > Texts
wxString ReferenceName
This is the name which identifies the symbol in the library.
wxString BuildLibName() const
long Width
Defaults to 0 if using system fonts or, if using CADSTAR font, defaults to equal height (1:1 aspect r...
Corresponds to CADSTAR "origin".
ALIGNMENT Alignment
In CADSTAR The default alignment for a TEXT object (when "(No Alignment)" is selected) Bottom Left of...
< Nodename = "VARIANT" or "VMASTER" (master variant
Represents a vertex in a shape.
From CADSTAR Help: "Area is for creating areas within which, and nowhere else, certain operations are...
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.
bool Routing
From CADSTAR Help: "Area can be used to place routes during Automatic Routing.
bool NoTracks
From CADSTAR Help: "Area cannot be used to place routes during automatic routing.
GROUP_ID GroupID
Normally CADSTAR_BOARD cannot be part of a reuseblock, but included for completeness.
long OrientAngle
1/1000 of a Degree
From CADSTAR Help: "Area is for creating areas within which, and nowhere else, certain operations are...
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.
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.
PAD_SIDE Side
See PAD_SIDE.
std::map< ATTRIBUTE_ID, ATTRIBUTE_VALUE > AttributeValues
std::map< ATTRIBUTE_ID, TEXT_LOCATION > TextLocations
This contains location of any attributes, including designator position.
COPPERCODE_ID CopperCodeID
TEMPLATE_ID PouredTemplateID
If not empty, it means this COPPER is part of a poured template.
long Offset
Offset from the measurement point.
long Overshoot
Overshoot of the extension line past the arrow line.
long LeaderLineExtensionLength
Only for TYPE=LEADERLINE Length of the horizontal part of the leader line [param6].
LINECODE_ID LineCodeID
param0
long LeaderLineLength
Only for TYPE=LEADERLINE Length of the angled part of the leader line [param5].
long LeaderAngle
Only for TYPE=LEADERLINE subnode "LEADERANG".
STYLE Style
Subnode="DIMLINETYPE".
Linear, leader (radius/diameter) or angular dimension.
LAYER_ID LayerID
ID on which to draw this [param1].
EXTENSION_LINE ExtensionLineParams
Not applicable to TYPE=LEADERDIM.
DIMENSION_ID ID
Some ID (doesn't seem to be used) subnode="DIMREF".
long Precision
Number of decimal points to display in the measurement [param3].
PHYSICAL_LAYER_ID PhysicalLayerStart
PHYSICAL_LAYER_ID PhysicalLayerEnd
long Thickness
Note: Units of length are defined in file header.
std::vector< CONNECTION_PCB > Connections
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
std::map< LAYER_ID, CADSTAR_PAD_SHAPE > Reassigns
long ReliefClearance
if undefined inherits from design
PADCODE_ID PadCode
If not empty, override padcode.
std::map< PAD_ID, COMPONENT_PAD > ComponentPads
std::vector< COMPONENT_COPPER > ComponentCoppers
std::map< COMP_AREA_ID, COMPONENT_AREA > ComponentAreas
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 ThermalReliefOnVias
false when subnode "NOVIARELIEF" is present
HATCHCODE_ID HatchCodeID
Only for FillType = HATCHED.
bool ThermalReliefOnPads
false when subnode "NOPINRELIEF" is present
long ThermalReliefPadsAngle
Orientation for the thermal reliefs.
long MinDisjointCopper
The value is the length of one side of a notional square.
bool AutomaticRepour
true when subnode "REGENERATE" is present
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.
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".
POURING Pouring
Copper pour settings (e.g. relief / hatching /etc.)
std::map< LAYER_ID, CADSTAR_PAD_SHAPE > Reassigns
@ USER
The field ID hasn't been set yet; field is invalid.
static void addTrack(BOARD &aBoard, int aNetCode, PCB_LAYER_ID aLayer, const VECTOR2I &aStart, const VECTOR2I &aEnd)
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.
double DEG2RAD(double deg)
@ PCB_DIM_ALIGNED_T
class PCB_DIM_ALIGNED, a linear dimension (graphic item)
VECTOR2< int32_t > VECTOR2I
@ THERMAL
Use thermal relief for pads.
@ FULL
pads are covered by copper