69 long long maxDesignSizekicad = std::numeric_limits<int>::max();
71 if( designSizeXkicad > maxDesignSizekicad || designSizeYkicad > maxDesignSizekicad )
74 _(
"The design is too large and cannot be imported into KiCad. \n"
75 "Please reduce the maximum design size in CADSTAR by navigating to: \n"
76 "Design Tab -> Properties -> Design Options -> Maximum Design Size. \n"
77 "Current Design size: %.2f, %.2f millimeters. \n"
78 "Maximum permitted design size: %.2f, %.2f millimeters.\n" ),
92 _(
"The selected file indicates that nets might be out of synchronisation "
93 "with the schematic. It is recommended that you carry out an 'Align Nets' "
94 "procedure in CADSTAR and re-import, to avoid inconsistencies between the "
95 "PCB and the schematic. " ) );
132 wxLogError(
wxString::Format(
_(
"Unable to determine zone fill priorities for layer "
133 "'%s'. A best attempt has been made but it is "
134 "possible that DRC errors exist and that manual "
135 "editing of the zone priorities is required." ),
146 _(
"The CADSTAR design contains Trunk routing elements, which have no KiCad "
147 "equivalent. These elements were not loaded." ) );
153 _(
"The CADSTAR design contains variants which has no KiCad equivalent. Only "
154 "the variant '%s' was loaded." ),
161 _(
"The CADSTAR design contains re-use blocks which has no KiCad equivalent. The "
162 "re-use block information has been discarded during the import." ) );
165 wxLogWarning(
_(
"CADSTAR fonts are different to the ones in KiCad. This will likely result "
166 "in alignment issues that may cause DRC errors. Please review the imported "
167 "text elements carefully and correct manually if required." ) );
170 _(
"The CADSTAR design has been imported successfully.\n"
171 "Please review the import errors and warnings (if any)." ) );
176 std::vector<FOOTPRINT*> retval;
178 for( std::pair<SYMDEF_ID, FOOTPRINT*> fpPair :
m_libraryMap )
180 retval.push_back(
static_cast<FOOTPRINT*
>( fpPair.second->Clone() ) );
188 const wxString& aCadstarLayerName,
194 _(
"The CADSTAR layer '%s' has no KiCad equivalent. All elements on this "
195 "layer have been mapped to KiCad layer '%s' instead." ),
196 aCadstarLayerName,
LSET::Name( aKiCadLayer ) ) );
207 _(
"The CADSTAR layer '%s' has been assumed to be a technical layer. All "
208 "elements on this layer have been mapped to KiCad layer '%s'." ),
209 aCadstarLayerName,
LSET::Name( aKiCadLayer ) ) );
216 int aDielectricSublayer )
228 if( !aCadstarLayer.
Name.IsEmpty() )
242 LAYER_ID ElecLayerID = wxEmptyString;
245 std::vector<LAYER_ID> ConstructionLayers;
250 bool IsInitialised() {
return !ElecLayerID.IsEmpty() || ConstructionLayers.size() > 0; };
253 std::vector<LAYER_BLOCK> cadstarBoardStackup;
254 LAYER_BLOCK currentBlock;
265 if( currentBlock.IsInitialised() )
267 cadstarBoardStackup.push_back( currentBlock );
268 currentBlock = LAYER_BLOCK();
271 currentBlock.ElecLayerID = cadstarLayerID;
275 currentBlock.ConstructionLayers.push_back( cadstarLayerID );
279 if( currentBlock.IsInitialised() )
280 cadstarBoardStackup.push_back( currentBlock );
286 if( cadstarBoardStackup.back().ConstructionLayers.size() > 0 )
288 cadstarBoardStackup.push_back( LAYER_BLOCK() );
295 LAYER_BLOCK bottomLayer = cadstarBoardStackup.back();
296 cadstarBoardStackup.pop_back();
298 LAYER_BLOCK secondToLastLayer = cadstarBoardStackup.back();
299 cadstarBoardStackup.pop_back();
301 LAYER_BLOCK dummyLayer;
302 LAYER_ID lastConstruction = secondToLastLayer.ConstructionLayers.back();
304 if( secondToLastLayer.ConstructionLayers.size() > 1 )
307 secondToLastLayer.ConstructionLayers.pop_back();
316 dummyLayer.ConstructionLayers.push_back( lastConstruction );
317 cadstarBoardStackup.push_back( secondToLastLayer );
318 cadstarBoardStackup.push_back( dummyLayer );
319 cadstarBoardStackup.push_back( bottomLayer );
324 wxASSERT( cadstarBoardStackup.back().ConstructionLayers.size() == 0 );
335 size_t stackIndex = 0;
341 LAYER_ID layerID = cadstarBoardStackup.at( stackIndex ).ElecLayerID;
343 if( layerID.IsEmpty() )
346 item->SetThickness( 0 );
354 switch( copperLayer.
Type )
370 wxFAIL_MSG( wxT(
"Unexpected Layer type. Was expecting an electrical type" ) );
376 m_layermap.insert( { copperLayer.
ID, item->GetBrdLayerId() } );
381 LAYER_BLOCK layerBlock = cadstarBoardStackup.at( stackIndex );
382 LAYER_BLOCK layerBlockBelow = cadstarBoardStackup.at( stackIndex + 1 );
384 if( layerBlock.ConstructionLayers.size() == 0 )
390 int dielectricId = stackIndex + 1;
391 item->SetDielectricLayerId( dielectricId );
396 if( layerBlock.ElecLayerID.IsEmpty() )
405 if( layerBlockBelow.ElecLayerID.IsEmpty() )
416 LAYER copperLayerBelow =
434 int dielectricSublayer = 0;
436 for(
LAYER_ID constructionLaID : layerBlock.ConstructionLayers )
440 if( dielectricSublayer )
441 item->AddDielectricPrms( dielectricSublayer );
445 m_layermap.insert( { dielectricLayer.
ID, item->GetBrdLayerId() } );
446 ++dielectricSublayer;
453 item->SetColor( wxT(
"White" ) );
457 item->SetColor( wxT(
"Green" ) );
465 int numElecLayersProcessed = 0;
468 int currentDocLayer = 0;
476 wxString layerName = curLayer.
Name.Lower();
489 kicadLayerID = aBack;
491 kicadLayerID = aFront;
502 case LOG_LEVEL::WARN:
508 switch( curLayer.
Type )
523 ++numElecLayersProcessed;
531 if( currentDocLayer >= docLayers.size() )
534 kicadLayerID = docLayers.at( currentDocLayer++ );
552 if( layerName.Contains( wxT(
"glue" ) ) || layerName.Contains( wxT(
"adhesive" ) ) )
556 else if( layerName.Contains( wxT(
"silk" ) ) || layerName.Contains( wxT(
"legend" ) ) )
560 else if( layerName.Contains( wxT(
"assembly" ) ) || layerName.Contains( wxT(
"fabrication" ) ) )
564 else if( layerName.Contains( wxT(
"resist" ) ) || layerName.Contains( wxT(
"mask" ) ) )
568 else if( layerName.Contains( wxT(
"paste" ) ) )
599 wxFAIL_MSG( wxT(
"Unknown CADSTAR Layer Sub-type" ) );
605 wxFAIL_MSG( wxT(
"Unknown CADSTAR Layer Type" ) );
620 std::vector<INPUT_LAYER_DESC> inputLayers;
621 std::map<wxString, LAYER_ID> cadstarLayerNameMap;
623 for( std::pair<LAYER_ID, PCB_LAYER_ID> layerPair :
m_layermap )
635 inputLayers.push_back( iLdesc );
636 cadstarLayerNameMap.insert( { curLayer->
Name, curLayer->
ID } );
640 if( inputLayers.size() == 0 )
646 for( std::pair<wxString, PCB_LAYER_ID> layerPair : reMappedLayers )
650 wxFAIL_MSG( wxT(
"Unexpected Layer ID" ) );
654 LAYER_ID cadstarLayerID = cadstarLayerNameMap.at( layerPair.first );
655 m_layermap.at( cadstarLayerID ) = layerPair.second;
656 enabledLayers |=
LSET( layerPair.second );
670 [&]( wxString aID,
int* aVal )
672 if( spacingCodes.find( aID ) == spacingCodes.end() )
673 wxLogWarning(
_(
"Design rule %s was not found. This was ignored." ) );
691 auto applyNetClassRule =
692 [&]( wxString aID, std::shared_ptr<NETCLASS>& aNetClassPtr )
695 applyRule( aID, &value );
698 aNetClassPtr->SetClearance( value );
701 applyNetClassRule(
"T_T", bds.
m_NetSettings->m_DefaultNetClass );
703 wxLogWarning(
_(
"KiCad design rules are different from CADSTAR ones. Only the compatible "
704 "design rules were imported. It is recommended that you review the design "
705 "rules that have been applied." ) );
716 ( wxT(
" (" ) + component.
Alternate + wxT(
")" ) ) :
717 wxString( wxT(
"" ) ) );
724 if( component.
Figures.size() > 0 )
727 componentLayer = firstFigure.
LayerID;
729 else if( component.
Texts.size() > 0 )
731 TEXT firstText = component.
Texts.begin()->second;
732 componentLayer = firstText.
LayerID;
742 libID.
Parse( fpName,
true );
751 m_libraryMap.insert( std::make_pair( key, footprint ) );
759 for( std::pair<FIGURE_ID, FIGURE> figPair : aComponent.
Figures )
761 FIGURE& fig = figPair.second;
777 int totalCopperPads = 0;
810 std::unique_ptr<PAD>
pad = std::make_unique<PAD>( aFootprint );
812 pad->SetLayerSet(
LSET( 1, copperLayer ) );
824 if( anchorSize <= 0 )
829 pad->SetSize( { anchorSize, anchorSize } );
830 pad->SetPosition( anchorPos );
831 pad->SetLocalCoord();
837 pad->AddPrimitivePoly( shapePolys, 0,
true );
868 for( std::pair<COMP_AREA_ID, COMPONENT_AREA> areaPair : aComponent.
ComponentAreas )
874 int lineThickness = 0;
899 libName << wxT(
" (" ) << aComponent.
Alternate << wxT(
")" );
903 "have a KiCad equivalent. The area is neither a via nor "
904 "route keepout area. The area was not imported." ),
905 area.
ID, libName ) );
914 for( std::pair<PAD_ID, COMPONENT_PAD> padPair : aComponent.
ComponentPads )
928 std::unique_ptr<PAD>
pad = std::make_unique<PAD>( aParent );
931 switch( aCadstarPad.
Side )
946 wxFAIL_MSG( wxT(
"Unknown Pad type" ) );
950 pad->SetLocalSolderMaskMargin( 0 );
951 pad->SetLocalSolderPasteMargin( 0 );
952 pad->SetLocalSolderPasteMarginRatio( 0.0 );
953 bool complexPadErrorLogged =
false;
955 for(
auto& reassign : csPadcode.
Reassigns )
960 if( shape.
Size == 0 )
962 padLayerSet.reset( kiLayer );
971 pad->SetLocalSolderMaskMargin( newMargin );
976 pad->SetLocalSolderPasteMargin( newMargin );
982 if( !complexPadErrorLogged )
984 complexPadErrorLogged =
true;
988 _(
"The CADSTAR pad definition '%s' is a complex pad stack, "
989 "which is not supported in KiCad. Please review the "
990 "imported pads as they may require manual correction." ),
997 pad->SetLayerSet( padLayerSet );
1004 pad->SetNumber( wxT(
"" ) );
1049 pad->SetRoundRectRadiusRatio( 0.5 );
1050 pad->SetChamferRectRatio( 0.0 );
1068 pad->SetChamferRectRatio( 0.5 );
1069 pad->SetSize( { sizeOfSquare, sizeOfSquare } );
1090 pad->SetChamferRectRatio( 0.25 );
1126 wxFAIL_MSG( wxT(
"Unknown Pad Shape" ) );
1161 pad->SetDrillSize( { 0, 0 } );
1166 LSET lset =
pad->GetLayerSet();
1169 if( lset.size() > 0 )
1175 pad->SetPosition( { 0, 0 } );
1176 pad->SetPos0( { 0, 0 } );
1177 pad->TransformShapeToPolygon( padOutline, layer, 0, maxError,
ERROR_INSIDE );
1184 padShape->
Move( padOffset - drillOffset );
1189 if( editedPadOutline.
Contains( { 0, 0 } ) )
1194 pad->AddPrimitive( padShape );
1195 padOffset = { 0, 0 };
1202 drillOffset = { 0, 0 };
1207 _(
"The CADSTAR pad definition '%s' has the hole shape outside the "
1208 "pad shape. The hole has been moved to the center of the pad." ),
1214 wxFAIL_MSG( wxT(
"No copper layers defined in the pad?" ) );
1216 pad->SetOffset( drillOffset );
1221 pad->SetOffset( drillOffset );
1238 wxLogError(
_(
"The CADSTAR pad definition '%s' has import errors: %s" ),
1245 return pad.release();
1250 const PAD_ID aCadstarPadID )
1252 size_t index = aCadstarPadID - (long) 1;
1254 if( !( index < aFootprint->Pads().size() ) )
1257 (
long) aCadstarPadID,
1261 return aFootprint->
Pads().at( index );
1267 for( std::pair<GROUP_ID, GROUP> groupPair :
Layout.
Groups )
1269 GROUP& csGroup = groupPair.second;
1281 for( std::pair<GROUP_ID, GROUP> groupPair :
Layout.
Groups )
1283 GROUP& csGroup = groupPair.second;
1285 if( !csGroup.
GroupID.IsEmpty() )
1296 "map (parent group ID=%s, Name=%s)." ),
1305 parentGroup->
AddItem( kiCadGroup );
1314 for( std::pair<BOARD_ID, CADSTAR_BOARD> boardPair :
Layout.
Boards )
1323 if( !board.
GroupID.IsEmpty() )
1335 for( std::pair<FIGURE_ID, FIGURE> figPair :
Layout.
Figures )
1337 FIGURE& fig = figPair.second;
1352 for( std::pair<TEXT_ID, TEXT> txtPair :
Layout.
Texts )
1354 TEXT& csTxt = txtPair.second;
1366 switch( csDim.
Type )
1368 case DIMENSION::TYPE::LINEARDIM:
1371 case DIMENSION::SUBTYPE::ANGLED:
1372 wxLogWarning(
wxString::Format(
_(
"Dimension ID %s is an angled dimension, which "
1373 "has no KiCad equivalent. An aligned dimension "
1374 "was loaded instead." ),
1377 case DIMENSION::SUBTYPE::DIRECT:
1378 case DIMENSION::SUBTYPE::ORTHOGONAL:
1380 if( csDim.
Line.
Style == DIMENSION::LINE::STYLE::EXTERNAL )
1383 _(
"Dimension ID %s has 'External' style in CADSTAR. External "
1384 "dimension styles are not yet supported in KiCad. The dimension "
1385 "object was imported with an internal dimension style instead." ),
1391 if( csDim.
Subtype == DIMENSION::SUBTYPE::ORTHOGONAL )
1415 VECTOR2I crossbarVector = crossbarEnd - crossbarStart;
1417 double height = 0.0;
1419 if( csDim.
Subtype == DIMENSION::SUBTYPE::ORTHOGONAL )
1422 height = heightVector.
y;
1424 height = heightVector.
x;
1430 height = heightVector.
x *
angle.Cos() + heightVector.
y *
angle.Sin();
1440 wxLogError(
_(
"Unexpected Dimension type (ID %s). This was not imported." ),
1446 case DIMENSION::TYPE::LEADERDIM:
1449 if( csDim.
Line.
Style == DIMENSION::LINE::STYLE::INTERNAL )
1573 case DIMENSION::TYPE::ANGLEDIM:
1575 wxLogError(
_(
"Dimension %s is an angular dimension which has no KiCad equivalent. "
1576 "The object was not imported." ),
1586 for( std::pair<AREA_ID, AREA> areaPair :
Layout.
Areas )
1588 AREA& area = areaPair.second;
1592 int lineThickness = 0;
1615 wxLogWarning(
wxString::Format(
_(
"The CADSTAR area '%s' is marked as a placement "
1616 "area in CADSTAR. Placement areas are not "
1617 "supported in KiCad. Only the supported elements "
1618 "for the area were imported." ),
1625 "equivalent. Pure Placement areas are not supported." ),
1652 "(Symdef ID: '%s')" ),
1657 FOOTPRINT* libFootprint = fpIter->second;
1676 for( std::pair<PART_DEFINITION_PIN_ID, PART::DEFINITION::PIN> pinPair :
1679 PART::DEFINITION::PIN
pin = pinPair.second;
1680 wxString pinName =
pin.Name;
1682 if( pinName.empty() )
1683 pinName =
pin.Identifier;
1685 if( pinName.empty() )
1698 for( std::pair<PAD_ID, PADEXCEPTION> padPair : comp.
PadExceptions )
1703 if( !padEx.
PadCode.IsEmpty() )
1718 wxString padNumber = kiPad->
GetNumber();
1733 footprint->
SetValue( wxEmptyString );
1749 if( !comp.
PartID.IsEmpty() && comp.
PartID != wxT(
"NO_PART" ) )
1761 for( std::pair<DOCUMENTATION_SYMBOL_ID, DOCUMENTATION_SYMBOL> docPair :
1772 "library (Symdef ID: '%s')" ),
1776 SYMDEF_PCB& docSymDefinition = ( *docSymIter ).second;
1783 bool mirrorInvert = docSymInstance.
Mirror;
1788 if( !docSymDefinition.
Alternate.IsEmpty() )
1789 groupName += wxT(
" (" ) + docSymDefinition.
Alternate + wxT(
")" );
1797 for( std::pair<FIGURE_ID, FIGURE> figPair : docSymDefinition.
Figures )
1799 FIGURE fig = figPair.second;
1803 m_board, groupID, moveVector, rotationAngle, scalingFactor,
1804 centreOfTransform, mirrorInvert );
1808 for( std::pair<TEXT_ID, TEXT> textPair : docSymDefinition.
Texts )
1810 TEXT txt = textPair.second;
1812 rotationAngle, scalingFactor, centreOfTransform, mirrorInvert );
1822 TEMPLATE& csTemplate = tempPair.second;
1824 int zonelinethickness = 0;
1834 if( !( csTemplate.
NetID.IsEmpty() || csTemplate.
NetID == wxT(
"NONE" ) ) )
1840 _(
"The CADSTAR template '%s' has the setting 'Allow in No Routing Areas' "
1841 "enabled. This setting has no KiCad equivalent, so it has been ignored." ),
1842 csTemplate.
Name ) );
1848 _(
"The CADSTAR template '%s' has the setting 'Box Isolated Pins' "
1849 "enabled. This setting has no KiCad equivalent, so it has been ignored." ),
1850 csTemplate.
Name ) );
1856 _(
"The CADSTAR template '%s' has the setting 'Automatic Repour' "
1857 "enabled. This setting has no KiCad equivalent, so it has been ignored." ),
1858 csTemplate.
Name ) );
1867 _(
"The CADSTAR template '%s' has a non-zero value defined for the "
1868 "'Sliver Width' setting. There is no KiCad equivalent for "
1869 "this, so this setting was ignored." ),
1870 csTemplate.
Name ) );
1877 _(
"The CADSTAR template '%s' has different settings for 'Retain Poured Copper "
1878 "- Disjoint' and 'Retain Poured Copper - Isolated'. KiCad does not "
1879 "distinguish between these two settings. The setting for disjoint copper "
1880 "has been applied as the minimum island area of the KiCad Zone." ),
1881 csTemplate.
Name ) );
1884 long long minIslandArea = -1;
1911 if( csTemplate.
Pouring.
FillType == TEMPLATE::POURING::COPPER_FILL_TYPE::HATCHED )
1928 _(
"The CADSTAR template '%s' has different settings for thermal relief "
1929 "in pads and vias. KiCad only supports one single setting for both. The "
1930 "setting for pads has been applied." ),
1931 csTemplate.
Name ) );
1942 if( spokeWidth < minThickness )
1945 _(
"The CADSTAR template '%s' has thermal reliefs in the original design "
1946 "but the spoke width (%.2f mm) is thinner than the minimum thickness of "
1947 "the zone (%.2f mm). KiCad requires the minimum thickness of the zone "
1948 "to be preserved. Therefore the minimum thickness has been applied as "
1949 "the new spoke width and will be applied next time the zones are "
1954 spokeWidth = minThickness;
1977 NET_ID netid = wxEmptyString;
1979 for( std::pair<NET_ID, NET_PCB> netPair :
Layout.
Nets )
1983 if( net.
Name == powerPlaneLayerName )
1990 if( netid.IsEmpty() )
1992 wxLogError(
_(
"The CADSTAR layer '%s' is defined as a power plane layer. However no "
1993 "net with such name exists. The layer has been loaded but no copper "
1994 "zone was created." ),
1995 powerPlaneLayerName );
1999 for( std::pair<BOARD_ID, CADSTAR_BOARD> boardPair :
Layout.
Boards )
2024 for( std::pair<COPPER_ID, COPPER> copPair :
Layout.
Coppers )
2026 COPPER& csCopper = copPair.second;
2071 fill.
Inflate( copperWidth / 2, 32 );
2094 _(
"The CADSTAR design contains COPPER elements, which have no direct KiCad "
2095 "equivalent. These have been imported as a KiCad Zone if solid or hatch "
2096 "filled, or as a KiCad Track if the shape was an unfilled outline (open or "
2160 fill.
Fracture( SHAPE_POLY_SET::POLYGON_MODE::PM_STRICTLY_SIMPLE );
2170 for( std::pair<NET_ID, NET_PCB> netPair :
Layout.
Nets )
2173 wxString netnameForErrorReporting = net.
Name;
2175 std::map<NETELEMENT_ID, long> netelementSizes;
2177 if( netnameForErrorReporting.IsEmpty() )
2180 for( std::pair<NETELEMENT_ID, NET_PCB::VIA> viaPair : net.
Vias )
2186 netelementSizes.insert( { viaPair.first, viaSize } );
2189 for( std::pair<NETELEMENT_ID, NET_PCB::PIN> pinPair : net.
Pins )
2191 NET_PCB::PIN
pin = pinPair.second;
2194 if( footprint ==
nullptr )
2197 _(
"The net '%s' references component ID '%s' which does not exist. "
2198 "This has been ignored." ),
2199 netnameForErrorReporting,
pin.ComponentID ) );
2201 else if( (
pin.PadID - (
long) 1 ) > footprint->
Pads().size() )
2203 wxLogWarning(
wxString::Format(
_(
"The net '%s' references non-existent pad index"
2204 " '%d' in component '%s'. This has been "
2206 netnameForErrorReporting,
2225 if( assocPads.find(
pin.PadID ) != assocPads.end() )
2227 for(
PAD_ID copperPadID : assocPads.at(
pin.PadID ) )
2236 int padsize = std::min(
pad->GetSizeX(),
pad->GetSizeY() );
2237 netelementSizes.insert( { pinPair.first, padsize } );
2245 auto getJunctionSize =
2246 [&](
NETELEMENT_ID aJptNetElemId,
const NET_PCB::CONNECTION_PCB& aConnectionToIgnore ) ->
int
2250 for( NET_PCB::CONNECTION_PCB connection : net.
Connections )
2252 if( connection.Route.RouteVertices.size() == 0 )
2255 if( connection.StartNode == aConnectionToIgnore.StartNode
2256 && connection.EndNode == aConnectionToIgnore.EndNode )
2261 if( connection.StartNode == aJptNetElemId )
2263 int s =
getKiCadLength( connection.Route.RouteVertices.front().RouteWidth );
2264 jptsize = std::max( jptsize, s );
2266 else if( connection.EndNode == aJptNetElemId )
2268 int s =
getKiCadLength( connection.Route.RouteVertices.back().RouteWidth );
2269 jptsize = std::max( jptsize, s );
2277 NET_PCB::ROUTE_VERTEX vertex = aConnectionToIgnore.Route.RouteVertices.front();
2279 if( aConnectionToIgnore.EndNode == aJptNetElemId )
2280 vertex = aConnectionToIgnore.Route.RouteVertices.back();
2288 for( NET_PCB::CONNECTION_PCB connection : net.
Connections )
2290 int startSize = std::numeric_limits<int>::max();
2291 int endSize = std::numeric_limits<int>::max();
2293 if( netelementSizes.find( connection.StartNode ) != netelementSizes.end() )
2294 startSize = netelementSizes.at( connection.StartNode );
2296 startSize = getJunctionSize( connection.StartNode, connection );
2298 if( netelementSizes.find( connection.EndNode ) != netelementSizes.end() )
2299 endSize = netelementSizes.at( connection.EndNode );
2301 endSize = getJunctionSize( connection.EndNode, connection );
2306 if( !connection.Unrouted )
2315 auto findAndReplaceTextField =
2354 wxString varValue = txtvalue.second;
2356 txtVars.insert( { varName, varValue } );
2361 wxString varName = txtvalue.first;
2362 wxString varValue = txtvalue.second;
2364 txtVars.insert( { varName, varValue } );
2369 wxLogError(
_(
"Text Variables could not be set as there is no project loaded." ) );
2377 for( std::pair<ATTRIBUTE_ID, ATTRIBUTE_VALUE> attrPair : aComponent.
AttributeValues )
2388 for( std::pair<ATTRIBUTE_ID, TEXT_LOCATION> textlocPair : aComponent.
TextLocations )
2395 attrval = wxEmptyString;
2399 attrval = wxT(
"${REFERENCE}" );
2414 const NET_PCB::ROUTE& aCadstarRoute,
2415 long aStartWidth,
long aEndWidth )
2417 if( aCadstarRoute.RouteVertices.size() == 0 )
2420 std::vector<PCB_SHAPE*> shapes;
2421 std::vector<NET_PCB::ROUTE_VERTEX> routeVertices = aCadstarRoute.RouteVertices;
2424 if( aStartWidth < routeVertices.front().RouteWidth )
2426 NET_PCB::ROUTE_VERTEX newFrontVertex = aCadstarRoute.RouteVertices.front();
2427 newFrontVertex.RouteWidth = aStartWidth;
2428 newFrontVertex.Vertex.End = aCadstarRoute.StartPoint;
2429 routeVertices.insert( routeVertices.begin(), newFrontVertex );
2433 if( aEndWidth < routeVertices.back().RouteWidth )
2435 NET_PCB::ROUTE_VERTEX newBackVertex = aCadstarRoute.RouteVertices.back();
2436 newBackVertex.RouteWidth = aEndWidth;
2437 routeVertices.push_back( newBackVertex );
2440 POINT prevEnd = aCadstarRoute.StartPoint;
2442 for(
const NET_PCB::ROUTE_VERTEX& v : routeVertices )
2448 shapes.push_back( shape );
2449 prevEnd = v.Vertex.End;
2454 wxLogError(
_(
"The CADSTAR design contains teardrops. This importer does not yet "
2455 "support them, so the teardrops in the design have been ignored." ) );
2481 via->SetLocked( aCadstarVia.Fixed );
2485 wxLogError(
_(
"The CADSTAR via code '%s' has different shape from a circle defined. "
2486 "KiCad only supports circular vias so this via type has been changed to "
2487 "be a via with circular shape of %.2f mm diameter." ),
2494 bool start_layer_outside =
2497 bool end_layer_outside =
2501 if( start_layer_outside && end_layer_outside )
2505 else if( ( !start_layer_outside ) && ( !end_layer_outside ) )
2519 return via->GetWidth();
2526 const double& aRotationAngle,
const double& aScalingFactor,
2527 const VECTOR2I& aTransformCentre,
const bool& aMirrorInvert )
2530 aContainer->
Add( txt );
2535 RotatePoint( rotatedTextPos, aTransformCentre, rotationAngle );
2537 KiROUND( (
double) ( rotatedTextPos.
x - aTransformCentre.
x ) * aScalingFactor );
2539 KiROUND( (
double) ( rotatedTextPos.
y - aTransformCentre.
y ) * aScalingFactor );
2540 rotatedTextPos += aTransformCentre;
2599 wxFAIL_MSG( wxT(
"Unknown Alignment - needs review!" ) );
2604 txt->
Flip( aTransformCentre,
true );
2608 if( aScalingFactor != 1.0 )
2614 scaledTextSize.
x =
KiROUND( (
double) unscaledTextSize.
x * aScalingFactor );
2615 scaledTextSize.
y =
KiROUND( (
double) unscaledTextSize.
y * aScalingFactor );
2621 txt->
Move( aMoveVector );
2626 LAYER_ID layersToDrawOn = aCadstarLayerOverride;
2628 if( layersToDrawOn.IsEmpty() )
2629 layersToDrawOn = aCadstarText.
LayerID;
2644 if( !aCadstarGroupID.IsEmpty() )
2655 if( !aCadstarGroupID.IsEmpty() )
2664 const int& aLineThickness,
2665 const wxString& aShapeName,
2669 const double& aRotationAngle,
2670 const double& aScalingFactor,
2672 const bool& aMirrorInvert )
2674 auto drawAsOutline = [&]()
2677 aContainer, aCadstarGroupID, aMoveVector, aRotationAngle,
2678 aScalingFactor, aTransformCentre, aMirrorInvert );
2680 aCadstarGroupID, aMoveVector, aRotationAngle, aScalingFactor,
2681 aTransformCentre, aMirrorInvert );
2684 switch( aCadstarShape.
Type )
2695 _(
"The shape for '%s' is Hatch filled in CADSTAR, which has no KiCad equivalent. "
2696 "Using solid fill instead." ),
2702 if( aCadstarShape.
Vertices.size() < 3
2703 || ( aCadstarShape.
Vertices.size() == 3
2704 && aCadstarShape.
Vertices.at( 0 ).End == aCadstarShape.
Vertices.at( 2 ).End ) )
2720 aMoveVector, aRotationAngle,
2721 aScalingFactor, aTransformCentre,
2724 shapePolys.
Fracture( SHAPE_POLY_SET::POLYGON_MODE::PM_STRICTLY_SIMPLE );
2731 if( !aCadstarGroupID.IsEmpty() )
2741 const int& aLineThickness,
2745 const double& aRotationAngle,
2746 const double& aScalingFactor,
2748 const bool& aMirrorInvert )
2750 for(
CUTOUT cutout : aCutouts )
2753 aCadstarGroupID, aMoveVector, aRotationAngle, aScalingFactor,
2754 aTransformCentre, aMirrorInvert );
2761 const int& aLineThickness,
2765 const double& aRotationAngle,
2766 const double& aScalingFactor,
2768 const bool& aMirrorInvert )
2771 aCadstarGroupID, aMoveVector,
2772 aRotationAngle, aScalingFactor,
2773 aTransformCentre, aMirrorInvert );
2778 shape->SetLayer( aKiCadLayer );
2779 shape->SetParent( aContainer );
2786 const std::vector<VERTEX>& aCadstarVertices,
2790 const double& aRotationAngle,
2791 const double& aScalingFactor,
2793 const bool& aMirrorInvert )
2795 std::vector<PCB_SHAPE*> drawSegments;
2797 if( aCadstarVertices.size() < 2 )
2799 return drawSegments;
2801 const VERTEX* prev = &aCadstarVertices.at( 0 );
2804 for(
size_t i = 1; i < aCadstarVertices.size(); i++ )
2806 cur = &aCadstarVertices.at( i );
2808 aMoveVector, aRotationAngle, aScalingFactor,
2809 aTransformCentre, aMirrorInvert ) );
2813 return drawSegments;
2818 const VERTEX& aCadstarVertex,
2822 const double& aRotationAngle,
2823 const double& aScalingFactor,
2825 const bool& aMirrorInvert )
2837 centerPoint = ( startPoint + endPoint ) / 2;
2844 switch( aCadstarVertex.
Type )
2855 shape->
SetEnd( endPoint );
2874 EDA_ANGLE arcStartAngle( startPoint - centerPoint );
2875 EDA_ANGLE arcEndAngle( endPoint - centerPoint );
2876 EDA_ANGLE arcAngle = ( arcEndAngle - arcStartAngle ).Normalize();
2891 shape->
Flip( aTransformCentre,
true );
2893 if( aScalingFactor != 1.0 )
2895 shape->
Move( -1*aTransformCentre );
2896 shape->
Scale( aScalingFactor );
2897 shape->
Move( aTransformCentre );
2900 if( aRotationAngle != 0.0 )
2903 if( aMoveVector !=
VECTOR2I{ 0, 0 } )
2904 shape->
Move( aMoveVector );
2906 if(
isFootprint( aContainer ) && shape != nullptr )
2909 if( !aCadstarGroupID.IsEmpty() )
2917 const int& aLineThickness,
2936 for(
int i = 0; i < polygon.
HoleCount( 0 ); i++ )
2944 const int& aLineThickness,
2947 const double& aRotationAngle,
2948 const double& aScalingFactor,
2950 const bool& aMirrorInvert )
2955 aContainer, noGroup, aMoveVector,
2956 aRotationAngle, aScalingFactor,
2957 aTransformCentre, aMirrorInvert );
2968 noGroup, aMoveVector,
2969 aRotationAngle, aScalingFactor,
2970 aTransformCentre, aMirrorInvert );
2981 if( aLineThickness > 0 )
2983 polySet.
Inflate( aLineThickness / 2, 32,
2984 SHAPE_POLY_SET::CORNER_STRATEGY::ROUND_ALL_CORNERS );
2992 for(
int j = 0; j < polySet.
HoleCount( i ); ++j )
3009 switch( shape->GetShape() )
3013 if( shape->GetClass() == wxT(
"MGRAPHIC" ) )
3018 if( shape->EndsSwapped() )
3025 SHAPE_ARC arc( shape->GetCenter(), shape->GetStart(), shape->GetArcAngle() );
3027 if( shape->EndsSwapped() )
3035 if( shape->GetClass() == wxT(
"MGRAPHIC" ) )
3043 lineChain.
Append( shape->GetStartX(), shape->GetStartY() );
3044 lineChain.
Append( shape->GetEndX(), shape->GetEndY() );
3049 wxFAIL_MSG( wxT(
"Drawsegment type is unexpected. Ignored." ) );
3069 const std::vector<PCB_SHAPE*> aShapes,
3072 int aWidthOverride )
3074 std::vector<PCB_TRACK*> tracks;
3086 if( aTrack->GetLength() != 0 )
3088 tracks.push_back( aTrack );
3099 switch( shape->GetShape() )
3102 if( shape->GetClass() == wxT(
"MGRAPHIC" ) )
3110 track =
new PCB_ARC( aParentContainer, &arc );
3114 SHAPE_ARC arc( shape->GetStart(), shape->GetArcMid(), shape->GetEnd(), 0 );
3116 if( shape->EndsSwapped() )
3119 track =
new PCB_ARC( aParentContainer, &arc );
3123 if( shape->GetClass() == wxT(
"MGRAPHIC" ) )
3126 track =
new PCB_TRACK( aParentContainer );
3132 track =
new PCB_TRACK( aParentContainer );
3133 track->
SetStart( shape->GetStart() );
3134 track->
SetEnd( shape->GetEnd() );
3139 wxFAIL_MSG( wxT(
"Drawsegment type is unexpected. Ignored." ) );
3143 if( aWidthOverride == -1 )
3144 track->
SetWidth( shape->GetWidth() );
3149 track->
SetLayer( shape->GetLayer() );
3153 if( aNet !=
nullptr )
3161 if( prevTrack !=
nullptr )
3163 int offsetAmount = ( track->
GetWidth() / 2 ) - ( prevTrack->
GetWidth() / 2 );
3165 if( offsetAmount > 0 )
3172 else if( offsetAmount < 0 )
3177 prevTrack->
SetEnd( newEnd );
3193 addTrack( synthTrack );
3198 addTrack( prevTrack );
3213 const wxString& aAttributeValue )
3226 aFootprint->
SetValue( aAttributeValue );
3227 txt = &aFootprint->
Value();
3231 txt =
new FP_TEXT( aFootprint );
3232 aFootprint->
Add( txt );
3233 txt->
SetText( aAttributeValue );
3246 aFootprint->
SetValue( aAttributeValue );
3247 txt = &aFootprint->
Value();
3252 txt =
new FP_TEXT( aFootprint );
3253 aFootprint->
Add( txt );
3254 txt->
SetText( aAttributeValue );
3263 txt->
SetPos0( rotatedTextPos );
3268 if( aCadstarAttrLoc.
Mirror )
3326 wxFAIL_MSG( wxT(
"Unknown Alignment - needs review!" ) );
3335 const long& aOffsetAmount )
3337 VECTOR2I v( *aPointToOffset - aRefPoint );
3343 aPointToOffset->
x = offsetted.
x;
3344 aPointToOffset->
y = offsetted.
y;
3348 *aPointToOffset = aRefPoint;
3366 if( textSize.
x == 0 )
3371 if( textSize.
x == 0 || textSize.
y == 0 )
3464 const std::map<ATTRIBUTE_ID, ATTRIBUTE_VALUE>& aCadstarAttributeMap )
3466 wxCHECK( aCadstarAttributeMap.find( aCadstarAttributeID ) != aCadstarAttributeMap.end(),
3469 return aCadstarAttributeMap.at( aCadstarAttributeID ).Value;
3486 const PART_ID& aCadstarPartID )
3521 if( hcode.
Hatches.size() < 1 )
3534 if( hcode.
Hatches.size() < 1 )
3546 if( hcode.
Hatches.size() < 1 )
3571 if( hcode.
Hatches.size() != 2 )
3574 _(
"The CADSTAR Hatching code '%s' has %d hatches defined. "
3575 "KiCad only supports 2 hatches (crosshatching) 90 degrees apart. "
3576 "The imported hatching is crosshatched." ),
3581 if( hcode.
Hatches.at( 0 ).LineWidth != hcode.
Hatches.at( 1 ).LineWidth )
3584 _(
"The CADSTAR Hatching code '%s' has different line widths for each "
3585 "hatch. KiCad only supports one width for the hatching. The imported "
3586 "hatching uses the width defined in the first hatch definition, i.e. "
3596 _(
"The CADSTAR Hatching code '%s' has different step sizes for each "
3597 "hatch. KiCad only supports one step size for the hatching. The imported "
3598 "hatching uses the step size defined in the first hatching definition, "
3605 if(
abs( hcode.
Hatches.at( 0 ).OrientAngle - hcode.
Hatches.at( 1 ).OrientAngle )
3609 _(
"The hatches in CADSTAR Hatching code '%s' have an angle "
3610 "difference of %.1f degrees. KiCad only supports hatching 90 "
3611 "degrees apart. The imported hatching has two hatches 90 "
3612 "degrees apart, oriented %.1f degrees from horizontal." ),
3641 wxString prefix = wxEmptyString;
3642 wxString suffix = wxEmptyString;
3643 size_t startpos = aCadstarDim.
Text.
Text.Find( wxT(
"<@DISTANCE" ) );
3645 if( startpos != wxNOT_FOUND )
3648 wxString remainingStr = aCadstarDim.
Text.
Text.Mid( startpos );
3649 size_t endpos = remainingStr.Find(
"@>" );
3653 if( suffix.StartsWith( wxT(
"mm" ) ) )
3656 suffix = suffix.Mid( 2 );
3674 switch( dimensionUnits )
3680 "is not supported in KiCad. Millimeters were "
3681 "applied instead." ),
3697 wxFAIL_MSG( wxT(
"We should have handled design units before coming here!" ) );
3704 std::map<TEMPLATE_ID, std::set<TEMPLATE_ID>> winningOverlaps;
3712 int retval = std::max( aZoneA->
GetLocalClearance(), aZoneB->GetLocalClearance() );
3721 [&](
ZONE* aLowerZone,
ZONE* aHigherZone ) ->
double
3724 intersectShape.
Inflate( inflateValue( aLowerZone, aHigherZone ) , 32 );
3733 double leftOverArea = lowerZoneFill.
Area();
3735 return leftOverArea;
3738 auto intersectionAreaOfZoneOutlines =
3739 [&](
ZONE* aZoneA,
ZONE* aZoneB ) ->
double
3742 outLineA.
Inflate( inflateValue( aZoneA, aZoneB ), 32 );
3745 outLineB.
Inflate( inflateValue( aZoneA, aZoneB ), 32 );
3749 return outLineA.
Area();
3753 auto isLowerPriority =
3756 return winningOverlaps[b].count( a ) > 0;
3759 for( std::map<TEMPLATE_ID, ZONE*>::iterator it1 =
m_zonesMap.begin();
3763 ZONE* thisZone = it1->second;
3768 for( std::map<TEMPLATE_ID, ZONE*>::iterator it2 = it1;
3772 ZONE* otherZone = it2->second;
3774 if( thisTemplate.
ID == otherTemplate.
ID )
3783 if( intersectionAreaOfZoneOutlines( thisZone, otherZone ) == 0 )
3792 if( thisZonePolyFill.
Area() > 0.0 && otherZonePolyFill.
Area() > 0.0 )
3795 double areaThis = errorArea( thisZone, otherZone );
3797 double areaOther = errorArea( otherZone, thisZone );
3799 if( areaThis > areaOther )
3802 winningOverlaps[thisTemplate.
ID].insert( otherTemplate.
ID );
3807 winningOverlaps[otherTemplate.
ID].insert( thisTemplate.
ID );
3810 else if( thisZonePolyFill.
Area() > 0.0 )
3813 winningOverlaps[thisTemplate.
ID].insert( otherTemplate.
ID );
3815 else if( otherZonePolyFill.
Area() > 0.0 )
3818 winningOverlaps[otherTemplate.
ID].insert( thisTemplate.
ID );
3824 if( intersectionAreaOfZoneOutlines( thisZone, otherZone ) != 0 )
3827 winningOverlaps[otherTemplate.
ID].insert( thisTemplate.
ID );
3829 winningOverlaps[thisTemplate.
ID].insert( otherTemplate.
ID );
3838 std::set<TEMPLATE_ID> intersectingIDs;
3840 for(
const std::pair<
TEMPLATE_ID, std::set<TEMPLATE_ID>>& idPair : winningOverlaps )
3842 intersectingIDs.insert( idPair.first );
3843 intersectingIDs.insert( idPair.second.begin(), idPair.second.end() );
3847 std::vector<TEMPLATE_ID> sortedIDs;
3851 sortedIDs.push_back(
id );
3855 std::sort( sortedIDs.begin(), sortedIDs.end(), isLowerPriority );
3861 if( prevID.IsEmpty() )
3867 wxASSERT( !isLowerPriority(
id, prevID ) );
3869 int newPriority =
m_zonesMap.at( prevID )->GetAssignedPriority();
3872 if( isLowerPriority( prevID,
id ) )
3875 m_zonesMap.at(
id )->SetAssignedPriority( newPriority );
3880 for(
const std::pair<
TEMPLATE_ID, std::set<TEMPLATE_ID>>& idPair : winningOverlaps )
3884 for(
const TEMPLATE_ID& losingID : idPair.second )
3886 if(
m_zonesMap.at( losingID )->GetAssignedPriority()
3887 >
m_zonesMap.at( winningID )->GetAssignedPriority() )
3921 if( aCadstarNetID.IsEmpty() )
3927 return m_netMap.at( aCadstarNetID );
3934 wxString newName = csNet.
Name;
3936 if( csNet.
Name.IsEmpty() )
3938 if( csNet.
Pins.size() > 0 )
3942 NET_PCB::PIN firstPin = ( *csNet.
Pins.begin() ).second;
3945 newName = wxT(
"Net-(" );
3947 newName << wxT(
"-Pad" ) <<
wxString::Format( wxT(
"%ld" ), firstPin.PadID );
3948 newName << wxT(
")" );
3952 wxFAIL_MSG( wxT(
"A net with no pins associated?" ) );
3953 newName = wxT(
"csNet-" );
3961 wxLogMessage(
_(
"The CADSTAR design contains nets with a 'Net Class' assigned. KiCad "
3962 "does not have an equivalent to CADSTAR's Net Class so these elements "
3963 "were not imported. Note: KiCad's version of 'Net Class' is closer to "
3964 "CADSTAR's 'Net Route Code' (which has been imported for all nets)." ) );
3971 wxLogWarning(
_(
"The CADSTAR design contains nets with a 'Spacing Class' assigned. "
3972 "KiCad does not have an equivalent to CADSTAR's Spacing Class so "
3973 "these elements were not imported. Please review the design rules as "
3974 "copper pours will affected by this." ) );
3980 std::shared_ptr<NETCLASS> netclass;
3982 std::tuple<ROUTECODE_ID, NETCLASS_ID, SPACING_CLASS_ID> key = { csNet.
RouteCodeID,
3992 wxString netClassName;
3995 netClassName += wxT(
"Route code: " ) + rc.
Name;
4000 netClassName += wxT(
" | Net class: " ) + nc.
Name;
4006 netClassName += wxT(
" | Spacing class: " ) + sp.
Name;
4009 netclass.reset(
new NETCLASS( *netSettings->m_DefaultNetClass ) );
4010 netclass->SetName( netClassName );
4011 netSettings->m_NetClasses[ netClassName ] = netclass;
4018 std::make_unique<EDA_COMBINED_MATCHER>( newName,
CTX_NETCLASS ),
4024 m_netMap.insert( { aCadstarNetID, netInfo } );
4033 bool aDetectMaxLayer )
4086 switch( layer.
Type )
4147 parentGroup->
AddItem( aKiCadItem );
4152 const wxString& aName )
4154 wxString groupName = aName;
4164 docSymGroup->
SetName( groupName );
4166 m_groupMap.insert( { groupID, docSymGroup } );
constexpr int ARC_HIGH_DEF
constexpr double PCB_IU_PER_MM
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
#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.
bool SetNetCode(int aNetCode, bool aNoAssert)
Set net using a net code.
NETINFO_ITEM * GetNet() const
Return #NET_INFO object for a given item.
void SetNet(NETINFO_ITEM *aNetInfo)
Set a NET_INFO object for the 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.
ZONE_SETTINGS & GetDefaultZoneSettings()
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 PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
virtual void SetLocked(bool aLocked)
virtual BOARD_ITEM * Duplicate() const
Create a copy of this BOARD_ITEM.
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
virtual bool IsLocked() const
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.
Information pertinent to a Pcbnew printed circuit board.
LSET GetEnabledLayers() const
A proxy function that calls the corresponding function in m_BoardSettings.
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
void SetEnabledLayers(LSET aLayerMask)
A proxy function that calls the correspondent function in m_BoardSettings.
bool SetLayerName(PCB_LAYER_ID aLayer, const wxString &aLayerName)
Changes the name of the layer given by aLayer.
void SetVisibleLayers(LSET aLayerMask)
A proxy function that calls the correspondent function in m_BoardSettings changes the bit-mask of vis...
void SetCopperLayerCount(int aCount)
bool SetLayerType(PCB_LAYER_ID aLayer, LAYER_T aLayerType)
Change the type of the layer given by aLayer.
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Return the name of a aLayer.
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
void Remove(BOARD_ITEM *aBoardItem, REMOVE_MODE aMode=REMOVE_MODE::NORMAL) override
Removes an item from the container.
@ ANTICLOCKWISE_SEMICIRCLE
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)
Corrects 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 cancelled.
@ DESIGN
Inherits from design units (assumed Assignments->Technology->Units)
PROGRESS_REPORTER * m_progressReporter
PCB_SHAPE * getShapeFromVertex(const POINT &aCadstarStartPoint, const VERTEX &aCadstarVertex, BOARD_ITEM_CONTAINER *aContainer=nullptr, const GROUP_ID &aCadstarGroupID=wxEmptyString, const VECTOR2I &aMoveVector={ 0, 0 }, const double &aRotationAngle=0.0, const double &aScalingFactor=1.0, const VECTOR2I &aTransformCentre={ 0, 0 }, const bool &aMirrorInvert=false)
Returns a pointer to a PCB_SHAPE object.
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::set< PADCODE_ID > m_padcodesTested
Used by getKiCadPad() to avoid multiple duplicate warnings.
int getKiCadLength(long long aCadstarLength)
void initStackupItem(const LAYER &aCadstarLayer, BOARD_STACKUP_ITEM *aKiCadItem, int aDielectricSublayer)
int m_numCopperLayers
Number of layers in the design.
std::vector< LAYER_ID > m_powerPlaneLayers
List of layers that are marked as power plane in CADSTAR.
bool isLayerSet(const LAYER_ID &aCadstarLayerID)
LAYERPAIR getLayerPair(const LAYERPAIR_ID &aCadstarLayerPairID)
void drawCadstarShape(const SHAPE &aCadstarShape, const PCB_LAYER_ID &aKiCadLayer, const int &aLineThickness, const wxString &aShapeName, BOARD_ITEM_CONTAINER *aContainer, const GROUP_ID &aCadstarGroupID=wxEmptyString, const VECTOR2I &aMoveVector={ 0, 0 }, const double &aRotationAngle=0.0, const double &aScalingFactor=1.0, const VECTOR2I &aTransformCentre={ 0, 0 }, const bool &aMirrorInvert=false)
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)
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.
void applyDimensionSettings(const DIMENSION &aCadstarDim, PCB_DIMENSION_BASE *aKiCadDim)
void drawCadstarVerticesAsShapes(const std::vector< VERTEX > &aCadstarVertices, const PCB_LAYER_ID &aKiCadLayer, const int &aLineThickness, BOARD_ITEM_CONTAINER *aContainer, const GROUP_ID &aCadstarGroupID=wxEmptyString, const VECTOR2I &aMoveVector={ 0, 0 }, const double &aRotationAngle=0.0, const double &aScalingFactor=1.0, const VECTOR2I &aTransformCentre={ 0, 0 }, const bool &aMirrorInvert=false)
Uses PCB_SHAPE to draw the vertices on m_board object.
void loadNetTracks(const NET_ID &aCadstarNetID, const NET_PCB::ROUTE &aCadstarRoute, long aStartWidth=std::numeric_limits< long >::max(), long aEndWidth=std::numeric_limits< long >::max())
ZONE * getZoneFromCadstarShape(const SHAPE &aCadstarShape, const int &aLineThickness, BOARD_ITEM_CONTAINER *aParentContainer)
PCB_LAYER_ID getKiCadCopperLayerID(unsigned int aLayerNum, bool aDetectMaxLayer=true)
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 logBoardStackupWarning(const wxString &aCadstarLayerName, const PCB_LAYER_ID &aKiCadLayer)
std::vector< FOOTPRINT * > GetLoadedLibraryFootpints() const
Return a copy of the loaded library footprints (caller owns the objects)
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)
void drawCadstarCutoutsAsShapes(const std::vector< CUTOUT > &aCutouts, const PCB_LAYER_ID &aKiCadLayer, const int &aLineThickness, BOARD_ITEM_CONTAINER *aContainer, const GROUP_ID &aCadstarGroupID=wxEmptyString, const VECTOR2I &aMoveVector={ 0, 0 }, const double &aRotationAngle=0.0, const double &aScalingFactor=1.0, const VECTOR2I &aTransformCentre={ 0, 0 }, const bool &aMirrorInvert=false)
Uses PCB_SHAPEs to draw the cutouts on m_board object.
NETINFO_ITEM * getKiCadNet(const NET_ID &aCadstarNetID)
Searches m_netMap and returns the NETINFO_ITEM pointer if exists.
SHAPE_POLY_SET getPolySetFromCadstarShape(const SHAPE &aCadstarShape, const int &aLineThickness=-1, BOARD_ITEM_CONTAINER *aContainer=nullptr, const VECTOR2I &aMoveVector={ 0, 0 }, const double &aRotationAngle=0.0, const double &aScalingFactor=1.0, const VECTOR2I &aTransformCentre={ 0, 0 }, const bool &aMirrorInvert=false)
Returns a SHAPE_POLY_SET object from a Cadstar SHAPE.
void logBoardStackupMessage(const wxString &aCadstarLayerName, const PCB_LAYER_ID &aKiCadLayer)
SHAPE_LINE_CHAIN getLineChainFromShapes(const std::vector< PCB_SHAPE * > aShapes)
Returns a SHAPE_LINE_CHAIN object from a series of PCB_SHAPE objects.
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)
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)
bool isFootprint(BOARD_ITEM_CONTAINER *aContainer)
void loadLibraryFigures(const SYMDEF_PCB &aComponent, FOOTPRINT *aFootprint)
TEXTCODE getTextCode(const TEXTCODE_ID &aCadstarTextCodeID)
wxString getAttributeName(const ATTRIBUTE_ID &aCadstarAttributeID)
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 drawCadstarText(const TEXT &aCadstarText, BOARD_ITEM_CONTAINER *aContainer, const GROUP_ID &aCadstarGroupID=wxEmptyString, const LAYER_ID &aCadstarLayerOverride=wxEmptyString, const VECTOR2I &aMoveVector={ 0, 0 }, const double &aRotationAngle=0.0, const double &aScalingFactor=1.0, const VECTOR2I &aTransformCentre={ 0, 0 }, const bool &aMirrorInvert=false)
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)
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 }, const double &aRotationAngle=0.0, const double &aScalingFactor=1.0, const VECTOR2I &aTransformCentre={ 0, 0 }, const bool &aMirrorInvert=false)
Returns a vector of pointers to PCB_SHAPE objects.
std::map< PAD_ID, std::vector< PAD_ID > > ASSOCIATED_COPPER_PADS
Map of pad anchor points (first) to copper pads (second).
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.
int getKiCadHatchCodeGap(const HATCHCODE_ID &aCadstarHatchcodeID)
ROUTECODE getRouteCode(const ROUTECODE_ID &aCadstarRouteCodeID)
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.
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
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".
void Parse()
Parses the file.
@ 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()
EDA_ANGLE GetArcAngle() const
void SetCenter(const VECTOR2I &aCenter)
SHAPE_POLY_SET & GetPolyShape()
void SetFilled(bool aFlag)
void SetPolyShape(const SHAPE_POLY_SET &aShape)
void SetStart(const VECTOR2I &aStart)
void SetShape(SHAPE_T aShape)
void SetEnd(const VECTOR2I &aEnd)
bool EndsSwapped() const
Have the start and end points been swapped since they were set?
void SetArcAngleAndEnd(const EDA_ANGLE &aAngle, bool aCheckNegativeAngle=false)
Set the end point from the angle center and start.
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
const EDA_ANGLE & GetTextAngle() const
virtual const wxString & GetText() const
Return the string associated with the text object.
void SetTextPos(const VECTOR2I &aPoint)
void SetMirrored(bool isMirrored)
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
virtual void SetVisible(bool aVisible)
void SetTextThickness(int aWidth)
The TextThickness is that set by the user.
void SetKeepUpright(bool aKeepUpright)
void SetTextSize(const VECTOR2I &aNewSize)
virtual void SetText(const wxString &aText)
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
int GetTextThickness() const
VECTOR2I GetTextSize() const
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
VECTOR2I GetArcMid0() const
const VECTOR2I & GetEnd0() const
VECTOR2I GetCenter0() const
virtual void SetLocalCoord()
Set relative coordinates from draw coordinates.
const VECTOR2I & GetStart0() const
void SetPos0(const VECTOR2I &aPos)
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.
LSEQ is a sequence (and ther