49#include <compoundfilereader.h>
56#include <wx/docview.h>
58#include <wx/mstream.h>
59#include <wx/wfstream.h>
60#include <wx/zstream.h>
62#include <magic_enum.hpp>
84 THROW_IO_ERROR( wxString::Format( wxT(
"Component creator tries to access component id %u "
85 "of %u existing components" ),
94 const std::vector<ALTIUM_VERTICE>& aVertices )
103 double startradiant =
DEG2RAD( vertex.startangle );
104 double endradiant =
DEG2RAD( vertex.endangle );
105 VECTOR2I arcStartOffset =
KiROUND( std::cos( startradiant ) * vertex.radius,
106 -std::sin( startradiant ) * vertex.radius );
108 VECTOR2I arcEndOffset =
KiROUND( std::cos( endradiant ) * vertex.radius,
109 -std::sin( endradiant ) * vertex.radius );
111 VECTOR2I arcStart = vertex.center + arcStartOffset;
112 VECTOR2I arcEnd = vertex.center + arcEndOffset;
117 if( arcStart.
Distance( vertex.position )
118 < arcEnd.
Distance( vertex.position ) )
145 aLine.
Append( vertex.position );
155 auto override =
m_layermap.find( aAltiumLayer );
159 return override->second;
162 switch( aAltiumLayer )
261 static std::set<ALTIUM_LAYER> altiumLayersWithWarning;
266 std::vector<PCB_LAYER_ID> layers;
267 layers.reserve( layerCount );
272 layers.emplace_back( layer );
283 wxString layerName = it !=
m_layerNames.end() ? it->second : wxString::Format( wxT(
"(%d)" ),
284 (
int) aAltiumLayer );
286 if(
m_reporter && altiumLayersWithWarning.insert( aAltiumLayer ).second )
289 _(
"Altium layer %s has no KiCad equivalent. It has been moved to KiCad "
305 const wxString& aLibrary,
const wxString& aFootprintName )
325 const unsigned PROGRESS_DELTA = 250;
343 const std::map<ALTIUM_PCB_DIR, std::string>& aFileMapping )
346 const std::vector<std::tuple<bool, ALTIUM_PCB_DIR, PARSE_FUNCTION_POINTER_fp>> parserOrder = {
458 for(
const std::tuple<bool, ALTIUM_PCB_DIR, PARSE_FUNCTION_POINTER_fp>& cur : parserOrder )
463 std::tie( isRequired,
directory, fp ) = cur;
468 const auto& mappedDirectory = aFileMapping.find(
directory );
470 if( mappedDirectory == aFileMapping.end() )
473 const std::vector<std::string> mappedFile{ mappedDirectory->second,
"Header" };
474 const CFB::COMPOUND_FILE_ENTRY* file = altiumPcbFile.
FindStream( mappedFile );
476 if( file ==
nullptr )
480 uint32_t numOfRecords = reader.
Read<uint32_t>();
486 m_reporter->Report( wxString::Format(
_(
"'%s' was not parsed correctly." ),
500 m_reporter->Report( wxString::Format(
_(
"'%s' was not fully parsed." ),
512 if( boardDirectory != aFileMapping.end() )
514 std::vector<std::string> mappedFile{ boardDirectory->second,
"Data" };
516 const CFB::COMPOUND_FILE_ENTRY* file = altiumPcbFile.
FindStream( mappedFile );
521 "This file does not appear to be in a valid PCB Binary Version 6.0 format. In "
523 "make sure to save as \"PCB Binary Files (*.PcbDoc)\"." ) );
528 for(
const std::tuple<bool, ALTIUM_PCB_DIR, PARSE_FUNCTION_POINTER_fp>& cur : parserOrder )
533 std::tie( isRequired,
directory, fp ) = cur;
535 const auto& mappedDirectory = aFileMapping.find(
directory );
537 if( mappedDirectory == aFileMapping.end() )
539 wxASSERT_MSG( !isRequired, wxString::Format( wxT(
"Altium Directory of kind %d was "
540 "expected, but no mapping is "
541 "present in the code" ),
546 std::vector<std::string> mappedFile{ mappedDirectory->second };
549 mappedFile.emplace_back(
"Data" );
551 const CFB::COMPOUND_FILE_ENTRY* file = altiumPcbFile.
FindStream( mappedFile );
553 if( file !=
nullptr )
555 fp( altiumPcbFile, file );
557 else if( isRequired )
561 m_reporter->Report( wxString::Format(
_(
"File not found: '%s' for directory '%s'." ),
576 if( zone->GetAssignedPriority() == 1000 )
587 zone->SetAssignedPriority( priority >= 0 ? priority : 0 );
591 for( std::pair<const ALTIUM_LAYER, ZONE*>& zone :
m_outer_plane )
592 zone.second->SetAssignedPriority( 0 );
602 if( !zone->HasFilledPolysForLayer( layer ) )
605 zone->GetFilledPolysList( layer )->Fracture();
643 if( arc->
GetCenter() == dim->GetPosition() )
652 VECTOR2I radialLine = dim->GetEnd() - dim->GetStart();
657 radialLine = radialLine.
Resize( std::max(
radius, 2 ) );
658 dim->SetEnd( dim->GetStart() + (
VECTOR2I) radialLine );
659 dim->SetLeaderLength( totalLength -
radius );
669 int desired_x = ( w - bbbox.
GetWidth() ) / 2;
670 int desired_y = ( h - bbbox.
GetHeight() ) / 2;
672 VECTOR2I movementVector( desired_x - bbbox.
GetX(), desired_y - bbbox.
GetY() );
673 m_board->Move( movementVector );
684 const wxString& aFootprintName )
686 std::unique_ptr<FOOTPRINT> footprint = std::make_unique<FOOTPRINT>(
m_board );
704 std::tuple<wxString, const CFB::COMPOUND_FILE_ENTRY*> ret =
707 wxString fpDirName = std::get<0>( ret );
708 const CFB::COMPOUND_FILE_ENTRY* footprintStream = std::get<1>( ret );
710 if( fpDirName.IsEmpty() )
713 wxString::Format(
_(
"Footprint directory not found: '%s'." ), aFootprintName ) );
716 const std::vector<std::string> streamName{ fpDirName.ToStdString(),
"Data" };
717 const CFB::COMPOUND_FILE_ENTRY* footprintData = altiumLibFile.
FindStream( footprintStream, {
"Data" } );
719 if( footprintData ==
nullptr )
732 footprint->SetFPID( fpID );
734 const std::vector<std::string> parametersStreamName{ fpDirName.ToStdString(),
736 const CFB::COMPOUND_FILE_ENTRY* parametersData =
737 altiumLibFile.
FindStream( footprintStream, {
"Parameters" } );
739 if( parametersData !=
nullptr )
742 std::map<wxString, wxString> parameterProperties = parametersReader.
ReadProperties();
744 wxT(
"DESCRIPTION" ), wxT(
"" ) );
745 footprint->SetLibDescription( description );
751 m_reporter->Report( wxString::Format(
_(
"File not found: '%s'." ),
756 footprint->SetLibDescription( wxT(
"" ) );
759 const std::vector<std::string> extendedPrimitiveInformationStreamName{
760 "ExtendedPrimitiveInformation",
"Data"
762 const CFB::COMPOUND_FILE_ENTRY* extendedPrimitiveInformationData =
763 altiumLibFile.
FindStream( footprintStream, extendedPrimitiveInformationStreamName );
765 if( extendedPrimitiveInformationData !=
nullptr )
768 footprint->SetReference( wxT(
"REF**" ) );
769 footprint->SetValue( aFootprintName );
770 footprint->Reference().SetVisible(
true );
771 footprint->Value().SetVisible(
true );
774 const int defaultTextThickness(
pcbIUScale.mmToIU( 0.15 ) );
776 for(
PCB_FIELD* field : footprint->GetFields() )
778 field->SetTextSize( defaultTextSize );
779 field->SetTextThickness( defaultTextThickness );
837 THROW_IO_ERROR( wxString::Format(
_(
"Record of unknown type: '%d'." ), recordtype ) );
843 for(
bool changes =
true; changes; )
848 [&changes](
PAD* aPad1,
PAD* aPad2 )
850 if( !( aPad1->GetNumber().IsEmpty() ^ aPad2->GetNumber().IsEmpty() ) )
853 for( PCB_LAYER_ID layer : aPad1->GetLayerSet() )
855 std::shared_ptr<SHAPE> shape1 = aPad1->GetEffectiveShape( layer );
856 std::shared_ptr<SHAPE> shape2 = aPad2->GetEffectiveShape( layer );
858 if( shape1->Collide( shape2.get() ) )
860 if( aPad1->GetNumber().IsEmpty() )
861 aPad1->SetNumber( aPad2->GetNumber() );
863 aPad2->SetNumber( aPad1->GetNumber() );
872 footprint->AutoPositionFields();
874 if( parser.HasParsingError() )
876 THROW_IO_ERROR( wxString::Format( wxT(
"%s stream was not parsed correctly" ),
880 if( parser.GetRemainingBytes() != 0 )
882 THROW_IO_ERROR( wxString::Format( wxT(
"%s stream is not fully parsed" ),
886 return footprint.release();
897 THROW_IO_ERROR( wxString::Format( wxT(
"Netcode with id %d does not exist. Only %d nets "
909 const auto rules =
m_rules.find( aKind );
914 for(
const ARULE6& rule : rules->second )
916 if( rule.
name == aName )
925 const auto rules =
m_rules.find( aKind );
930 for(
const ARULE6& rule : rules->second )
940 const CFB::COMPOUND_FILE_ENTRY* aEntry )
958 const CFB::COMPOUND_FILE_ENTRY* aEntry )
975 THROW_IO_ERROR( wxT(
"ExtendedPrimitiveInformation stream is not fully parsed" ) );
980 const CFB::COMPOUND_FILE_ENTRY* aEntry )
997 size_t layercount = 0;
1000 while( layerid < elem.
stackup.size() && layerid != 0 )
1002 layerid = elem.
stackup[ layerid - 1 ].nextId;
1006 size_t kicadLayercount = ( layercount % 2 == 0 ) ? layercount : layercount + 1;
1007 m_board->SetCopperLayerCount( kicadLayercount );
1016 auto it = stackup.
GetList().begin();
1025 altiumLayerId < elem.
stackup.size() && altiumLayerId != 0;
1026 altiumLayerId = elem.
stackup[altiumLayerId - 1].nextId )
1032 if( layer.
nextId == 0 && layercount != kicadLayercount )
1034 m_board->SetLayerName( ( *it )->GetBrdLayerId(), wxT(
"[unused]" ) );
1037 THROW_IO_ERROR( wxT(
"Board6 stream, unexpected item while parsing stackup" ) );
1039 ( *it )->SetThickness( 0 );
1044 THROW_IO_ERROR( wxT(
"Board6 stream, unexpected item while parsing stackup" ) );
1046 ( *it )->SetThickness( 0, 0 );
1047 ( *it )->SetThicknessLocked(
true, 0 );
1055 THROW_IO_ERROR( wxT(
"Board6 stream, unexpected item while parsing stackup" ) );
1069 if( klayer ==
B_Cu )
1072 THROW_IO_ERROR( wxT(
"Board6 stream, unexpected id while parsing last stackup layer" ) );
1082 THROW_IO_ERROR( wxT(
"Board6 stream, unexpected item while parsing stackup" ) );
1131 if( aStackup.size() == 0 )
1134 std::vector<INPUT_LAYER_DESC> inputLayers;
1135 std::map<wxString, ALTIUM_LAYER> altiumLayerNameMap;
1142 [&](
size_t ii ) ->
size_t
1148 return curLayer.
nextId - 1;
1153 for(
size_t ii = 0; ii < aStackup.size(); ii =
next( ii ) )
1155 curLayer = aStackup[ii];
1181 inputLayers.push_back( iLdesc );
1182 altiumLayerNameMap.insert( { curLayer.
name, layer_num } );
1186 if( inputLayers.size() == 0 )
1192 for( std::pair<wxString, PCB_LAYER_ID> layerPair : reMappedLayers )
1200 m_reporter->Report( wxString::Format(
_(
"Layer '%s' could not be mapped and "
1201 "will be skipped." ),
1209 ALTIUM_LAYER altiumID = altiumLayerNameMap.at( layerPair.first );
1210 m_layermap.insert_or_assign( altiumID, layerPair.second );
1211 enabledLayers |=
LSET( { layerPair.second } );
1214 m_board->SetEnabledLayers( enabledLayers );
1215 m_board->SetVisibleLayers( enabledLayers );
1232 int nextShape = lineChain.
NextShape( i );
1233 bool isLastShape = nextShape < 0;
1237 shape->SetStroke( stroke );
1249 shape->SetStroke( stroke );
1251 shape->SetStart( seg.
A );
1252 shape->SetEnd( seg.
B );
1261 const CFB::COMPOUND_FILE_ENTRY* aEntry )
1275 std::shared_ptr<NETCLASS> nc = std::make_shared<NETCLASS>( elem.
name );
1277 for(
const wxString&
name : elem.
names )
1279 m_board->GetDesignSettings().m_NetSettings->SetNetclassPatternAssignment(
1280 name, nc->GetName() );
1283 if(
m_board->GetDesignSettings().m_NetSettings->HasNetclass( nc->GetName() ) )
1290 msg.Printf(
_(
"More than one Altium netclass with name '%s' found. "
1291 "Only the first one will be imported." ), elem.
name );
1297 m_board->GetDesignSettings().m_NetSettings->SetNetclass( nc->GetName(), nc );
1307 std::shared_ptr<NET_SETTINGS> netSettings =
m_board->GetDesignSettings().m_NetSettings;
1311 if( net->GetNetCode() > 0 )
1313 std::shared_ptr<NETCLASS> netclass = netSettings->GetEffectiveNetClass( net->GetNetname() );
1316 net->SetNetClass( netclass );
1320 m_board->m_LegacyNetclassesLoaded =
true;
1325 const CFB::COMPOUND_FILE_ENTRY* aEntry )
1332 uint16_t componentId = 0;
1339 std::unique_ptr<FOOTPRINT> footprint = std::make_unique<FOOTPRINT>(
m_board );
1350 wxString fpName = elem.
pattern;
1352 if( fpName.Contains( wxT(
"\\" ) ) || fpName.Contains( wxT(
"/" ) ) )
1354 wxFileName fpPath( fpName, wxPATH_WIN );
1355 fpName = fpPath.GetFullName();
1360 footprint->SetFPID( fpID );
1362 footprint->SetPosition( elem.
position );
1363 footprint->SetOrientationDegrees( elem.
rotation );
1369 if( reference.find_first_not_of(
"0123456789" ) == wxString::npos )
1370 reference.Prepend( wxT(
"UNK" ) );
1372 footprint->SetReference( reference );
1377 path.push_back( pathid );
1378 path.push_back(
id );
1380 footprint->SetPath(
path );
1384 footprint->SetLocked( elem.
locked );
1385 footprint->Reference().SetVisible( elem.
nameon );
1386 footprint->Value().SetVisible( elem.
commenton );
1396 THROW_IO_ERROR( wxT(
"Components6 stream is not fully parsed" ) );
1403 while( Angle < aMin )
1406 while( Angle >= aMax )
1429 m_reporter->Report( wxString::Format( wxT(
"Model %s not found for footprint %s" ),
1442 if( file->
name.IsEmpty() )
1446 std::vector<char> decompressedData;
1447 wxMemoryInputStream compressedStream(
model->second.data(),
model->second.size() );
1448 wxZlibInputStream zlibStream( compressedStream );
1452 decompressedData.resize(
model->second.size() * 6 );
1455 while( !zlibStream.Eof() )
1457 zlibStream.Read( decompressedData.data() + offset, decompressedData.size() - offset );
1458 size_t bytesRead = zlibStream.LastRead();
1463 offset += bytesRead;
1465 if( offset >= decompressedData.size() )
1466 decompressedData.resize( 2 * decompressedData.size() );
1469 decompressedData.resize( offset );
1490 orientation = -orientation;
1497 modelRotation.
x += 180;
1498 modelRotation.
z = -modelRotation.
z;
1512 aFootprint->
Models().push_back( modelSettings );
1517 const CFB::COMPOUND_FILE_ENTRY* aEntry )
1531 if( skipComponentBodies )
1539 THROW_IO_ERROR( wxString::Format( wxT(
"ComponentsBodies6 stream tries to access "
1540 "component id %d of %zu existing components" ),
1555 msg.Printf( wxT(
"ComponentsBodies6 stream tries to access model id %s which does "
1556 "not exist" ), elem.
modelId );
1569 wxMemoryInputStream compressedStream( modelData.
m_data.data(), modelData.
m_data.size() );
1570 wxZlibInputStream zlibStream( compressedStream );
1571 wxMemoryOutputStream decompressedStream;
1573 zlibStream.Read( decompressedStream );
1596 orientation = -orientation;
1619 footprint->
Models().push_back( modelSettings );
1623 THROW_IO_ERROR( wxT(
"ComponentsBodies6 stream is not fully parsed" ) );
1630 THROW_IO_ERROR( wxT(
"Incorrect number of reference points for linear dimension object" ) );
1639 _(
"Dimension found on an Altium layer (%d) with no KiCad equivalent. "
1640 "It has been moved to KiCad layer Eco1_User." ), aElem.
layer ),
1653 dimension->SetLayer( klayer );
1654 dimension->SetStart( referencePoint0 );
1656 if( referencePoint0 != aElem.
xy1 )
1668 VECTOR2I referenceDiff = referencePoint1 - referencePoint0;
1670 SEG segm1( referencePoint0, referencePoint0 + directionNormalVector );
1671 SEG segm2( referencePoint1, referencePoint1 + direction );
1675 THROW_IO_ERROR( wxT(
"Invalid dimension. This should never happen." ) );
1677 dimension->SetEnd( *intersection );
1681 if( direction.
Cross( referenceDiff ) > 0 )
1684 dimension->SetHeight( height );
1688 dimension->SetEnd( referencePoint1 );
1691 dimension->SetLineThickness( aElem.
linewidth );
1697 int dist = ( dimension->GetEnd() - dimension->GetStart() ).EuclideanNorm();
1699 if( dist < 3 * dimension->GetArrowLength() )
1703 wxRegEx units( wxS(
"(mm)|(in)|(mils)|(thou)|(')|(\")" ), wxRE_ADVANCED );
1715 dimension->Text().SetBold( aElem.
textbold );
1718 dimension->SetTextThickness( dimension->GetTextThickness() *
BOLD_FACTOR );
1737 THROW_IO_ERROR( wxT(
"Not enough reference points for radial dimension object" ) );
1746 _(
"Dimension found on an Altium layer (%d) with no KiCad equivalent. "
1747 "It has been moved to KiCad layer Eco1_User." ),
1757 std::unique_ptr<PCB_DIM_RADIAL> dimension = std::make_unique<PCB_DIM_RADIAL>(
m_board );
1760 dimension->SetLayer( klayer );
1761 dimension->SetStart( referencePoint0 );
1762 dimension->SetEnd( aElem.
xy1 );
1763 dimension->SetLineThickness( aElem.
linewidth );
1764 dimension->SetKeepTextAligned(
false );
1785 m_reporter->Report( wxT(
"No text position present for leader dimension object" ),
1792 dimension->SetTextPos( aElem.
textPoint.at( 0 ) );
1798 dimension->SetBold( aElem.
textbold );
1801 dimension->SetTextThickness( dimension->GetTextThickness() *
BOLD_FACTOR );
1809 int yAdjust = dimension->GetTextBox(
nullptr ).GetCenter().y - dimension->GetTextPos().y;
1810 dimension->SetTextPos( dimension->GetTextPos() +
VECTOR2I( 0, yAdjust + aElem.
textgap ) );
1827 msg.Printf(
_(
"Dimension found on an Altium layer (%d) with no KiCad equivalent. "
1828 "It has been moved to KiCad layer Eco1_User." ), aElem.
layer );
1845 shape->SetLayer( klayer );
1847 shape->SetStart( last );
1859 if( dirVec.
x != 0 || dirVec.
y != 0 )
1868 shape1->SetLayer( klayer );
1870 shape1->SetStart( referencePoint0 );
1871 shape1->SetEnd( referencePoint0 + arrVec );
1881 shape2->SetLayer( klayer );
1883 shape2->SetStart( referencePoint0 );
1884 shape2->SetEnd( referencePoint0 + arrVec );
1896 m_reporter->Report( wxT(
"No text position present for leader dimension object" ),
1903 std::unique_ptr<PCB_TEXT>
text = std::make_unique<PCB_TEXT>(
m_board );
1907 text->SetLayer( klayer );
1926 msg.Printf(
_(
"Dimension found on an Altium layer (%d) with no KiCad equivalent. "
1927 "It has been moved to KiCad layer Eco1_User." ), aElem.
layer );
1938 shape->SetLayer( klayer );
1957 msg.Printf(
_(
"Dimension found on an Altium layer (%d) with no KiCad equivalent. "
1958 "It has been moved to KiCad layer Eco1_User." ), aElem.
layer );
1968 std::unique_ptr<PCB_DIM_CENTER> dimension = std::make_unique<PCB_DIM_CENTER>(
m_board );
1970 dimension->SetLayer( klayer );
1971 dimension->SetLineThickness( aElem.
linewidth );
1972 dimension->SetStart( aElem.
xy1 );
1973 dimension->SetEnd( aElem.
xy1 + vec );
1980 const CFB::COMPOUND_FILE_ENTRY* aEntry )
2000 m_reporter->Report( wxString::Format(
_(
"Ignored Angular dimension (not yet supported)." ) ),
2013 m_reporter->Report( wxString::Format(
_(
"Ignored Datum dimension (not yet supported)." ) ),
2021 m_reporter->Report( wxString::Format(
_(
"Ignored Baseline dimension (not yet supported)." ) ),
2031 m_reporter->Report( wxString::Format(
_(
"Ignored Linear dimension (not yet supported)." ) ),
2038 m_reporter->Report( wxString::Format(
_(
"Ignored Radial dimension (not yet supported)." ) ),
2046 msg.Printf(
_(
"Ignored dimension of kind %d (not yet supported)." ), elem.
kind );
2054 THROW_IO_ERROR( wxT(
"Dimensions6 stream is not fully parsed" ) );
2059 const CFB::COMPOUND_FILE_ENTRY* aEntry,
2060 const std::vector<std::string>& aRootDir )
2071 wxString invalidChars = wxFileName::GetForbiddenChars();
2078 std::vector<std::string> stepPath = aRootDir;
2079 stepPath.emplace_back( std::to_string( idx ) );
2081 bool validName = !elem.
name.IsEmpty() && elem.
name.IsAscii()
2082 && wxString::npos == elem.
name.find_first_of( invalidChars );
2083 wxString storageName = validName ? elem.
name : wxString::Format( wxT(
"model_%d" ), idx );
2087 const CFB::COMPOUND_FILE_ENTRY* stepEntry = aAltiumPcbFile.
FindStream( stepPath );
2089 if( stepEntry ==
nullptr )
2094 msg.Printf(
_(
"File not found: '%s'. 3D-model not imported." ),
FormatPath( stepPath ) );
2101 size_t stepSize =
static_cast<size_t>( stepEntry->size );
2102 std::vector<char> stepContent( stepSize );
2110 std::move( stepContent ) ) ) );
2114 std::map<wxString, std::vector<wxString>> nameIdMap;
2117 nameIdMap[data.m_modelname].push_back(
id );
2119 for(
auto& [
name, ids] : nameIdMap )
2121 for(
size_t i = 1; i < ids.size(); i++ )
2123 const wxString&
id = ids[i];
2130 wxString modelName = modelTuple->second.m_modelname;
2132 if( modelName.Contains(
"." ) )
2135 wxString baseName = modelName.BeforeLast(
'.', &ext );
2137 modelTuple->second.m_modelname = baseName +
'_' + std::to_string( i ) +
'.' + ext;
2141 modelTuple->second.m_modelname = modelName +
'_' + std::to_string( i );
2152 const CFB::COMPOUND_FILE_ENTRY* aEntry )
2164 ANET6 elem( reader );
2178 const CFB::COMPOUND_FILE_ENTRY* aEntry )
2221 msg.Printf(
_(
"Polygon outline count is %d, expected 1." ), outline.
OutlineCount() );
2229 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>(
m_board);
2235 zone->SetPosition( elem.
vertices.at( 0 ).position );
2236 zone->SetLocked( elem.
locked );
2238 zone->Outline()->AddOutline( outline.
Outline( 0 ) );
2245 int planeLayers = 0;
2246 int signalLayers = 0;
2260 if( planeLayers > 0 && planeClearanceRule )
2263 if( signalLayers > 0 && zoneClearanceRule )
2271 if( polygonConnectRule !=
nullptr )
2290 zone->SetThermalReliefSpokeWidth(
2301 zone->SetAssignedPriority( 1 );
2306 || zone->GetBoundingBox().Contains( outer_plane->second->GetBoundingBox() ) )
2321 const BOX2I& bbox = zone->GetBoundingBox();
2330 zone->SetHatchOrientation(
ANGLE_45 );
2345 const CFB::COMPOUND_FILE_ENTRY* aEntry )
2363 std::sort( val.second.begin(), val.second.end(),
2366 return lhs.priority < rhs.priority;
2379 if( trackWidthRule )
2381 m_board->GetDesignSettings().m_TrackMinWidth = trackWidthRule->
minLimit;
2385 if( routingViasRule )
2387 m_board->GetDesignSettings().m_ViasMinSize = routingViasRule->
minWidth;
2396 if( holeToHoleRule )
2402 if( soldermaskRule )
2413 const CFB::COMPOUND_FILE_ENTRY* aEntry )
2429 THROW_IO_ERROR( wxT(
"BoardRegions stream is not fully parsed" ) );
2433 const CFB::COMPOUND_FILE_ENTRY* aEntry )
2441 for(
int primitiveIndex = 0; reader.
GetRemainingBytes() >= 4; primitiveIndex++ )
2460 THROW_IO_ERROR(
"ShapeBasedRegions6 stream is not fully parsed" );
2484 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>(
m_board );
2486 zone->SetIsRuleArea(
true );
2494 zone->SetDoNotAllowZoneFills(
true );
2495 zone->SetDoNotAllowVias(
false );
2496 zone->SetDoNotAllowTracks(
false );
2497 zone->SetDoNotAllowPads(
false );
2498 zone->SetDoNotAllowFootprints(
false );
2501 zone->SetPosition( aElem.
outline.at( 0 ).position );
2502 zone->Outline()->AddOutline( linechain );
2522 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>(
m_board );
2524 zone->SetPosition( aElem.
outline.at( 0 ).position );
2525 zone->Outline()->AddOutline( linechain );
2533 fill.
Append( linechain );
2537 zone->SetFilledPolysList( klayer, fill );
2539 zone->SetIsFilled(
true );
2540 zone->SetNeedRefill(
false );
2553 msg.Printf(
_(
"Dashed outline found on an Altium layer (%d) with no KiCad equivalent. "
2554 "It has been moved to KiCad layer Eco1_User." ), aElem.
layer );
2575 shape->SetPolyShape( linechain );
2576 shape->SetFilled(
false );
2577 shape->SetLayer( klayer );
2599 msg.Printf(
_(
"Ignored polygon shape of kind %d (not yet supported)." ), aElem.
kind );
2608 const int aPrimitiveIndex )
2624 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>( aFootprint );
2626 zone->SetIsRuleArea(
true );
2634 zone->SetDoNotAllowZoneFills(
true );
2635 zone->SetDoNotAllowVias(
false );
2636 zone->SetDoNotAllowTracks(
false );
2637 zone->SetDoNotAllowPads(
false );
2638 zone->SetDoNotAllowFootprints(
false );
2641 zone->SetPosition( aElem.
outline.at( 0 ).position );
2642 zone->Outline()->AddOutline( linechain );
2676 msg.Printf(
_(
"Loading library '%s':\n"
2677 "Footprint %s contains a dashed outline on Altium layer (%d) with "
2678 "no KiCad equivalent. It has been moved to KiCad layer Eco1_User." ),
2690 msg.Printf(
_(
"Footprint %s contains a dashed outline on Altium layer (%d) with "
2691 "no KiCad equivalent. It has been moved to KiCad layer Eco1_User." ),
2713 std::unique_ptr<PCB_SHAPE> shape = std::make_unique<PCB_SHAPE>( aFootprint,
SHAPE_T::POLY );
2715 shape->SetPolyShape( linechain );
2716 shape->SetFilled(
false );
2717 shape->SetLayer( klayer );
2733 msg.Printf(
_(
"Error loading library '%s':\n"
2734 "Footprint %s contains polygon shape of kind %d (not yet supported)." ),
2746 msg.Printf(
_(
"Footprint %s contains polygon shape of kind %d (not yet supported)." ),
2774 for(
const std::vector<ALTIUM_VERTICE>& hole : aElem.
holes )
2782 polySet.
AddHole( hole_linechain );
2787 shape->SetPolyShape( polySet );
2788 shape->SetFilled(
true );
2789 shape->SetLayer( aLayer );
2804 const int aPrimitiveIndex )
2821 for(
const std::vector<ALTIUM_VERTICE>& hole : aElem.
holes )
2829 polySet.
AddHole( hole_linechain );
2832 if( aLayer ==
F_Cu || aLayer ==
B_Cu )
2835 std::unique_ptr<PAD>
pad = std::make_unique<PAD>( aFootprint );
2838 padLayers.
set( aLayer );
2849 pad->SetPosition( anchorPos );
2852 shapePolys.
Move( -anchorPos );
2856 auto it = map.find( aPrimitiveIndex );
2858 if( it != map.end() )
2864 pad->SetLocalSolderPasteMargin(
info.pastemaskexpansionmanual );
2869 pad->SetLocalSolderMaskMargin(
info.soldermaskexpansionmanual );
2879 pad->SetLayerSet( padLayers );
2885 std::unique_ptr<PCB_SHAPE> shape = std::make_unique<PCB_SHAPE>( aFootprint,
SHAPE_T::POLY );
2887 shape->SetPolyShape( polySet );
2888 shape->SetFilled(
true );
2889 shape->SetLayer( aLayer );
2898 const CFB::COMPOUND_FILE_ENTRY* aEntry )
2914 THROW_IO_ERROR( wxString::Format(
"Region stream tries to access polygon id %d "
2915 "of %d existing polygons.",
2922 if( zone ==
nullptr )
2944 for(
const std::vector<ALTIUM_VERTICE>& hole : elem.
holes )
2951 hole_linechain.
Append( hole.at( 0 ).position );
2953 fill.
AddHole( hole_linechain );
2973 const CFB::COMPOUND_FILE_ENTRY* aEntry )
2980 for(
int primitiveIndex = 0; reader.
GetRemainingBytes() >= 4; primitiveIndex++ )
2983 AARC6 elem( reader );
3034 THROW_IO_ERROR( wxString::Format(
"Tracks stream tries to access polygon id %u "
3035 "of %zu existing polygons.",
3041 if( zone ==
nullptr )
3089 for(
const auto& layerExpansionMask :
3092 int width = aElem.
width + ( layerExpansionMask.second * 2 );
3096 std::unique_ptr<PCB_SHAPE> arc = std::make_unique<PCB_SHAPE>(
m_board );
3100 arc->SetLayer( layerExpansionMask.first );
3109 const int aPrimitiveIndex,
const bool aIsBoardImport )
3113 wxFAIL_MSG( wxString::Format(
"Altium: Unexpected footprint Arc with polygon id %d",
3146 for(
const auto& layerExpansionMask :
3149 int width = aElem.
width + ( layerExpansionMask.second * 2 );
3153 std::unique_ptr<PCB_SHAPE> arc = std::make_unique<PCB_SHAPE>( aFootprint );
3157 arc->SetLayer( layerExpansionMask.first );
3189 std::unique_ptr<PCB_ARC> arc = std::make_unique<PCB_ARC>(
m_board, &shapeArc );
3191 arc->SetWidth( aElem.
width );
3192 arc->SetLayer( aLayer );
3200 std::unique_ptr<PCB_SHAPE> arc = std::make_unique<PCB_SHAPE>(
m_board);
3204 arc->SetLayer( aLayer );
3214 std::unique_ptr<PCB_SHAPE> arc = std::make_unique<PCB_SHAPE>( aFootprint );
3218 arc->SetLayer( aLayer );
3225 const CFB::COMPOUND_FILE_ENTRY* aEntry )
3235 APAD6 elem( reader );
3264 std::unique_ptr<FOOTPRINT> footprint = std::make_unique<FOOTPRINT>(
m_board );
3265 footprint->SetPosition( aElem.
position );
3276 std::unique_ptr<PAD>
pad = std::make_unique<PAD>( aFootprint );
3278 pad->SetNumber(
"" );
3289 pad->SetLayerSet(
LSET().AllCuMask() );
3316 pad->Padstack().FrontOuterLayers().has_solder_mask =
true;
3320 pad->Padstack().FrontOuterLayers().has_solder_mask =
false;
3326 pad->Padstack().BackOuterLayers().has_solder_mask =
true;
3330 pad->Padstack().BackOuterLayers().has_solder_mask =
false;
3335 pad->SetLocked(
true );
3365 std::unique_ptr<PAD>
pad = std::make_unique<PAD>( aFootprint );
3388 msg.Printf(
_(
"Error loading library '%s':\n"
3389 "Footprint %s pad %s is not marked as multilayer, but is a TH pad." ),
3401 msg.Printf(
_(
"Footprint %s pad %s is not marked as multilayer, but is a TH pad." ),
3421 wxFAIL_MSG( wxT(
"Round holes are handled before the switch" ) );
3430 msg.Printf(
_(
"Loading library '%s':\n"
3431 "Footprint %s pad %s has a square hole (not yet supported)." ),
3443 msg.Printf(
_(
"Footprint %s pad %s has a square hole (not yet supported)." ),
3478 msg.Printf(
_(
"Loading library '%s':\n"
3479 "Footprint %s pad %s has a hole-rotation of %d degrees. "
3480 "KiCad only supports 90 degree rotations." ),
3493 msg.Printf(
_(
"Footprint %s pad %s has a hole-rotation of %d degrees. "
3494 "KiCad only supports 90 degree rotations." ),
3513 msg.Printf(
_(
"Error loading library '%s':\n"
3514 "Footprint %s pad %s uses a hole of unknown kind %d." ),
3527 msg.Printf(
_(
"Footprint %s pad %s uses a hole of unknown kind %d." ),
3547 auto setCopperGeometry =
3592 msg.Printf(
_(
"Error loading library '%s':\n"
3593 "Footprint %s pad %s uses an unknown pad shape." ),
3605 msg.Printf(
_(
"Footprint %s pad %s uses an unknown pad shape." ),
3656 switch( aElem.
layer )
3674 pad->SetLayer( klayer );
3675 pad->SetLayerSet(
LSET( { klayer } ) );
3686 pad->SetLayerSet(
pad->GetLayerSet().reset(
F_Mask ) );
3689 pad->SetLayerSet(
pad->GetLayerSet().reset(
B_Mask ) );
3707 msg.Printf(
_(
"Non-copper pad %s found on an Altium layer (%d) with no KiCad "
3708 "equivalent. It has been moved to KiCad layer Eco1_User." ),
3716 std::unique_ptr<PCB_SHAPE>
pad = std::make_unique<PCB_SHAPE>(
m_board );
3735 msg.Printf(
_(
"Loading library '%s':\n"
3736 "Footprint %s non-copper pad %s found on an Altium layer (%d) with no "
3737 "KiCad equivalent. It has been moved to KiCad layer Eco1_User." ),
3750 msg.Printf(
_(
"Footprint %s non-copper pad %s found on an Altium layer (%d) with no "
3751 "KiCad equivalent. It has been moved to KiCad layer Eco1_User." ),
3762 std::unique_ptr<PCB_SHAPE>
pad = std::make_unique<PCB_SHAPE>( aFootprint );
3778 msg.Printf(
_(
"Non-copper pad %s is connected to a net, which is not supported." ),
3789 msg.Printf(
_(
"Non-copper pad %s has a hole, which is not supported." ), aElem.
name );
3799 msg.Printf(
_(
"Non-copper pad %s has a complex pad stack (not yet supported)." ),
3832 int offset = ( std::min( aElem.
topsize.
x, aElem.
topsize.
y ) * cornerradius ) / 200;
3837 if( cornerradius < 100 )
3839 int offsetX = aElem.
topsize.
x / 2 - offset;
3840 int offsetY = aElem.
topsize.
y / 2 - offset;
3933 aShape->
SetPolyPoints( { p11 - chamferX, p11 - chamferY, p12 + chamferY, p12 - chamferX,
3934 p22 + chamferX, p22 + chamferY, p21 - chamferY, p21 + chamferX } );
3946 msg.Printf(
_(
"Non-copper pad %s uses an unknown pad shape." ), aElem.
name );
3956 const CFB::COMPOUND_FILE_ENTRY* aEntry )
3966 AVIA6 elem( reader );
3968 std::unique_ptr<PCB_VIA>
via = std::make_unique<PCB_VIA>(
m_board );
3980 if( start_layer_outside && end_layer_outside )
3984 else if( ( !start_layer_outside ) && ( !end_layer_outside ) )
4007 msg.Printf(
_(
"Via from layer %d to %d uses a non-copper layer, which is not "
4018 via->SetLayerPair( start_klayer, end_klayer );
4041 wxCHECK2_MSG( altiumLayer < 32,
break,
4042 "Altium importer expects 32 or fewer copper layers" );
4067 const CFB::COMPOUND_FILE_ENTRY* aEntry )
4074 for(
int primitiveIndex = 0; reader.
GetRemainingBytes() >= 4; primitiveIndex++ )
4105 msg.Printf( wxT(
"ATRACK6 stream tries to access polygon id %u "
4106 "of %u existing polygons; skipping it" ),
4107 static_cast<unsigned>( aElem.
polygon ),
4108 static_cast<unsigned>(
m_polygons.size() ) );
4117 if( zone ==
nullptr )
4167 int width = aElem.
width + ( layerExpansionMask.second * 2 );
4172 seg->SetStart( aElem.
start );
4173 seg->SetEnd( aElem.
end );
4175 seg->SetLayer( layerExpansionMask.first );
4184 const int aPrimitiveIndex,
4185 const bool aIsBoardImport )
4189 wxFAIL_MSG( wxString::Format(
"Altium: Unexpected footprint Track with polygon id %u",
4225 int width = aElem.
width + ( layerExpansionMask.second * 2 );
4228 std::unique_ptr<PCB_SHAPE> seg = std::make_unique<PCB_SHAPE>( aFootprint,
SHAPE_T::SEGMENT );
4230 seg->SetStart( aElem.
start );
4231 seg->SetEnd( aElem.
end );
4233 seg->SetLayer( layerExpansionMask.first );
4245 std::unique_ptr<PCB_TRACK> track = std::make_unique<PCB_TRACK>(
m_board );
4247 track->SetStart( aElem.
start );
4248 track->SetEnd( aElem.
end );
4249 track->SetWidth( aElem.
width );
4250 track->SetLayer( aLayer );
4259 seg->SetStart( aElem.
start );
4260 seg->SetEnd( aElem.
end );
4262 seg->SetLayer( aLayer );
4272 std::unique_ptr<PCB_SHAPE> seg = std::make_unique<PCB_SHAPE>( aFootprint,
SHAPE_T::SEGMENT );
4274 seg->SetStart( aElem.
start );
4275 seg->SetEnd( aElem.
end );
4277 seg->SetLayer( aLayer );
4284 const CFB::COMPOUND_FILE_ENTRY* aEntry )
4294 THROW_IO_ERROR( wxT(
"WideStrings6 stream is not fully parsed" ) );
4298 const CFB::COMPOUND_FILE_ENTRY* aEntry )
4356 std::unique_ptr<PCB_TEXTBOX> pcbTextbox = std::make_unique<PCB_TEXTBOX>(
m_board );
4357 std::unique_ptr<PCB_TEXT> pcbText = std::make_unique<PCB_TEXT>(
m_board );
4361 static const std::map<wxString, wxString> variableMap = {
4362 {
"LAYER_NAME",
"LAYER" },
4363 {
"PRINT_DATE",
"CURRENT_DATE"},
4373 item = pcbTextbox.get();
4374 text = pcbTextbox.get();
4385 text->SetText( kicadText );
4399 std::unique_ptr<PCB_TEXTBOX> fpTextbox = std::make_unique<PCB_TEXTBOX>( aFootprint );
4400 std::unique_ptr<PCB_TEXT> fpText = std::make_unique<PCB_TEXT>( aFootprint );
4417 item = &aFootprint->
Value();
4419 field = &aFootprint->
Value();
4423 item = fpText.get();
4424 text = fpText.get();
4428 static const std::map<wxString, wxString> variableMap = {
4429 {
"DESIGNATOR",
"REFERENCE" },
4430 {
"COMMENT",
"VALUE" },
4431 {
"VALUE",
"ALTIUM_VALUE" },
4432 {
"LAYER_NAME",
"LAYER" },
4433 {
"PRINT_DATE",
"CURRENT_DATE"},
4438 item = fpTextbox.get();
4439 text = fpTextbox.get();
4452 text->SetText( kicadText );
4453 text->SetKeepUpright(
false );
4469 std::unique_ptr<PCB_BARCODE> pcbBarcode = std::make_unique<PCB_BARCODE>(
m_board );
4471 pcbBarcode->SetLayer( aLayer );
4472 pcbBarcode->SetPosition( aElem.
position );
4476 pcbBarcode->SetText( aElem.
text );
4486 pcbBarcode->AssembleBarcode();
4495 std::unique_ptr<PCB_BARCODE> fpBarcode = std::make_unique<PCB_BARCODE>( aFootprint );
4497 fpBarcode->SetLayer( aLayer );
4498 fpBarcode->SetPosition( aElem.
position );
4502 fpBarcode->SetText( aElem.
text );
4512 fpBarcode->AssembleBarcode();
4541 kicadMargin =
VECTOR2I( charWidth * 0.933, charHeight * 0.67 );
4543 kicadMargin =
VECTOR2I( charWidth * 0.808, charHeight * 0.844 );
4546 + kicadMargin * 2 - margin * 2 );
4548 kposition = kposition - kicadMargin + margin;
4566 switch( justification )
4590 msg.Printf(
_(
"Unknown textbox justification %d, aText %s" ), justification,
4610 int rectHeight = aElem.
height;
4613 rectWidth = -rectWidth;
4619 switch( justification )
4625 kposition.
y -= rectHeight;
4631 kposition.
y -= rectHeight / 2;
4641 kposition.
x += rectWidth / 2;
4642 kposition.
y -= rectHeight;
4648 kposition.
x += rectWidth / 2;
4649 kposition.
y -= rectHeight / 2;
4655 kposition.
x += rectWidth / 2;
4661 kposition.
x += rectWidth;
4662 kposition.
y -= rectHeight;
4668 kposition.
x += rectWidth;
4669 kposition.
y -= rectHeight / 2;
4675 kposition.
x += rectWidth;
4728 if( font->
GetName().Contains( wxS(
"Arial" ) ) )
4743 const CFB::COMPOUND_FILE_ENTRY* aEntry )
4801 const bool aIsBoardImport )
4843 fill->SetFilled(
true );
4844 fill->SetLayer( aLayer );
4847 fill->SetStart( aElem.
pos1 );
4848 fill->SetEnd( aElem.
pos2 );
4870 if( aLayer ==
F_Cu || aLayer ==
B_Cu )
4872 std::unique_ptr<PAD>
pad = std::make_unique<PAD>( aFootprint );
4875 padLayers.
set( aLayer );
4890 std::swap( width, height );
4893 pad->SetPosition( aElem.
pos1 / 2 + aElem.
pos2 / 2 );
4905 pad->SetPosition( anchorPos );
4916 aElem.
pos1.
y / 2 + aElem.
pos2.
y / 2 - anchorPos.
y );
4918 pad->AddPrimitivePoly(
F_Cu, shapePolys, 0,
true );
4922 pad->SetLayerSet( padLayers );
4928 std::unique_ptr<PCB_SHAPE> fill =
4931 fill->SetFilled(
true );
4932 fill->SetLayer( aLayer );
4935 fill->SetStart( aElem.
pos1 );
4936 fill->SetEnd( aElem.
pos2 );
4955 layerSet.
set( klayer );
4963 bool keepoutRestrictionVia = ( aKeepoutRestrictions & 0x01 ) != 0;
4964 bool keepoutRestrictionTrack = ( aKeepoutRestrictions & 0x02 ) != 0;
4965 bool keepoutRestrictionCopper = ( aKeepoutRestrictions & 0x04 ) != 0;
4966 bool keepoutRestrictionSMDPad = ( aKeepoutRestrictions & 0x08 ) != 0;
4967 bool keepoutRestrictionTHPad = ( aKeepoutRestrictions & 0x10 ) != 0;
4979 const uint8_t aKeepoutRestrictions )
4981 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>(
m_board );
4983 zone->SetIsRuleArea(
true );
5000 const uint8_t aKeepoutRestrictions )
5002 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>( aFootprint );
5004 zone->SetIsRuleArea(
true );
5028 if( elems.first == elems.second )
5031 std::vector<std::pair<PCB_LAYER_ID, int>> layerExpansionPairs;
5033 for(
auto it = elems.first; it != elems.second; ++it )
5073 return layerExpansionPairs;
std::string FormatPath(const std::vector< std::string > &aVectorPath)
Helper for debug logging (vector -> string)
const uint16_t ALTIUM_NET_UNCONNECTED
const uint16_t ALTIUM_POLYGON_NONE
const uint16_t ALTIUM_POLYGON_BOARD
const int ALTIUM_COMPONENT_NONE
LIB_ID AltiumToKiCadLibID(const wxString &aLibName, const wxString &aLibReference)
wxString AltiumPcbSpecialStringsToKiCadStrings(const wxString &aString, const std::map< wxString, wxString > &aOverrides)
void HelperShapeLineChainFromAltiumVertices(SHAPE_LINE_CHAIN &aLine, const std::vector< ALTIUM_VERTICE > &aVertices)
double normalizeAngleDegrees(double Angle, double aMin, double aMax)
Normalize angle to be aMin < angle <= aMax angle is in degrees.
constexpr double BOLD_FACTOR
bool IsAltiumLayerCopper(ALTIUM_LAYER aLayer)
bool IsAltiumLayerAPlane(ALTIUM_LAYER aLayer)
@ EXTENDPRIMITIVEINFORMATION
std::function< void(const ALTIUM_PCB_COMPOUND_FILE &, const CFB::COMPOUND_FILE_ENTRY *)> PARSE_FUNCTION_POINTER_fp
constexpr int ARC_HIGH_DEF
constexpr EDA_IU_SCALE pcbIUScale
LAYER_T
The allowed types of layers, same as Specctra DSN spec.
#define DEFAULT_BOARD_THICKNESS_MM
@ BS_ITEM_TYPE_DIELECTRIC
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
size_t GetRemainingBytes() const
std::map< uint32_t, wxString > ReadWideStringTable()
size_t ReadAndSetSubrecordLength()
std::map< wxString, wxString > ReadProperties(std::function< std::map< wxString, wxString >(const std::string &)> handleBinaryData=[](const std::string &) { return std::map< wxString, wxString >();})
const CFB::CompoundFileReader & GetCompoundFileReader() const
const CFB::COMPOUND_FILE_ENTRY * FindStream(const std::vector< std::string > &aStreamPath) const
const std::pair< AMODEL, std::vector< char > > * GetLibModel(const wxString &aModelID) const
std::tuple< wxString, const CFB::COMPOUND_FILE_ENTRY * > FindLibFootprintDirName(const wxString &aFpUnicodeName)
PROGRESS_REPORTER * m_progressReporter
optional; may be nullptr
void ParseClasses6Data(const ALTIUM_PCB_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry)
std::vector< PCB_DIM_RADIAL * > m_radialDimensions
void ConvertArcs6ToFootprintItemOnLayer(FOOTPRINT *aFootprint, const AARC6 &aElem, PCB_LAYER_ID aLayer)
void ConvertTracks6ToBoardItem(const ATRACK6 &aElem, const int aPrimitiveIndex)
void ConvertTracks6ToFootprintItem(FOOTPRINT *aFootprint, const ATRACK6 &aElem, const int aPrimitiveIndex, const bool aIsBoardImport)
int m_highest_pour_index
Altium stores pour order across all layers.
void ConvertTexts6ToFootprintItemOnLayer(FOOTPRINT *aFootprint, const ATEXT6 &aElem, PCB_LAYER_ID aLayer)
std::map< ALTIUM_LAYER, PCB_LAYER_ID > m_layermap
void ConvertShapeBasedRegions6ToBoardItemOnLayer(const AREGION6 &aElem, PCB_LAYER_ID aLayer)
void ParseVias6Data(const ALTIUM_PCB_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry)
void HelperParseDimensions6Leader(const ADIMENSION6 &aElem)
wxString m_footprintName
for footprint library loading error reporting
std::vector< FOOTPRINT * > m_components
void ParseShapeBasedRegions6Data(const ALTIUM_PCB_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry)
const ARULE6 * GetRuleDefault(ALTIUM_RULE_KIND aKind) const
void HelperParsePad6NonCopper(const APAD6 &aElem, PCB_LAYER_ID aLayer, PCB_SHAPE *aShape)
void ParseRegions6Data(const ALTIUM_PCB_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry)
std::vector< PCB_LAYER_ID > GetKicadLayersToIterate(ALTIUM_LAYER aAltiumLayer) const
void ConvertShapeBasedRegions6ToFootprintItem(FOOTPRINT *aFootprint, const AREGION6 &aElem, const int aPrimitiveIndex)
void HelperPcpShapeAsFootprintKeepoutRegion(FOOTPRINT *aFootprint, const PCB_SHAPE &aShape, const ALTIUM_LAYER aAltiumLayer, const uint8_t aKeepoutRestrictions)
void ConvertArcs6ToBoardItem(const AARC6 &aElem, const int aPrimitiveIndex)
void ConvertShapeBasedRegions6ToFootprintItemOnLayer(FOOTPRINT *aFootprint, const AREGION6 &aElem, PCB_LAYER_ID aLayer, const int aPrimitiveIndex)
std::map< ALTIUM_LAYER, ZONE * > m_outer_plane
std::vector< int > m_altiumToKicadNetcodes
unsigned m_totalCount
for progress reporting
void ParseComponents6Data(const ALTIUM_PCB_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry)
void HelperPcpShapeAsBoardKeepoutRegion(const PCB_SHAPE &aShape, const ALTIUM_LAYER aAltiumLayer, const uint8_t aKeepoutRestrictions)
std::map< wxString, ALTIUM_EMBEDDED_MODEL_DATA > m_EmbeddedModels
void ConvertFills6ToBoardItemOnLayer(const AFILL6 &aElem, PCB_LAYER_ID aLayer)
std::vector< std::pair< PCB_LAYER_ID, int > > HelperGetSolderAndPasteMaskExpansions(const ALTIUM_RECORD aType, const int aPrimitiveIndex, const ALTIUM_LAYER aAltiumLayer)
void ConvertBarcodes6ToBoardItemOnLayer(const ATEXT6 &aElem, PCB_LAYER_ID aLayer)
void ConvertComponentBody6ToFootprintItem(const ALTIUM_PCB_COMPOUND_FILE &aAltiumPcbFile, FOOTPRINT *aFootprint, const ACOMPONENTBODY6 &aElem)
void HelperSetTextAlignmentAndPos(const ATEXT6 &aElem, EDA_TEXT *aEdaText)
void ParseBoard6Data(const ALTIUM_PCB_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry)
void ConvertFills6ToFootprintItem(FOOTPRINT *aFootprint, const AFILL6 &aElem, const bool aIsBoardImport)
void ParseExtendedPrimitiveInformationData(const ALTIUM_PCB_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry)
void ParseFileHeader(const ALTIUM_PCB_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry)
void ConvertShapeBasedRegions6ToBoardItem(const AREGION6 &aElem)
void HelperCreateBoardOutline(const std::vector< ALTIUM_VERTICE > &aVertices)
std::map< ALTIUM_RULE_KIND, std::vector< ARULE6 > > m_rules
void ConvertVias6ToFootprintItem(FOOTPRINT *aFootprint, const AVIA6 &aElem)
void ParseRules6Data(const ALTIUM_PCB_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry)
void HelperSetZoneKeepoutRestrictions(ZONE &aZone, const uint8_t aKeepoutRestrictions)
void HelperParseDimensions6Linear(const ADIMENSION6 &aElem)
void ParseTracks6Data(const ALTIUM_PCB_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry)
std::map< uint32_t, wxString > m_unicodeStrings
void ConvertTexts6ToBoardItem(const ATEXT6 &aElem)
void HelperParseDimensions6Center(const ADIMENSION6 &aElem)
void HelperParseDimensions6Radial(const ADIMENSION6 &aElem)
void ParseBoardRegionsData(const ALTIUM_PCB_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry)
void ParseArcs6Data(const ALTIUM_PCB_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry)
void ConvertTexts6ToBoardItemOnLayer(const ATEXT6 &aElem, PCB_LAYER_ID aLayer)
void ConvertPads6ToFootprintItemOnCopper(FOOTPRINT *aFootprint, const APAD6 &aElem)
FOOTPRINT * ParseFootprint(ALTIUM_PCB_COMPOUND_FILE &altiumLibFile, const wxString &aFootprintName)
REPORTER * m_reporter
optional; may be nullptr
int GetNetCode(uint16_t aId) const
void ConvertTexts6ToEdaTextSettings(const ATEXT6 &aElem, EDA_TEXT &aEdaText)
wxString m_library
for footprint library loading error reporting
void ConvertPads6ToFootprintItemOnNonCopper(FOOTPRINT *aFootprint, const APAD6 &aElem)
void ConvertTexts6ToFootprintItem(FOOTPRINT *aFootprint, const ATEXT6 &aElem)
unsigned m_lastProgressCount
void ParseFills6Data(const ALTIUM_PCB_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry)
void ConvertArcs6ToFootprintItem(FOOTPRINT *aFootprint, const AARC6 &aElem, const int aPrimitiveIndex, const bool aIsBoardImport)
void HelperParseDimensions6Datum(const ADIMENSION6 &aElem)
void ConvertPads6ToBoardItem(const APAD6 &aElem)
void ConvertFills6ToFootprintItemOnLayer(FOOTPRINT *aFootprint, const AFILL6 &aElem, PCB_LAYER_ID aLayer)
void ParseWideStrings6Data(const ALTIUM_PCB_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry)
void remapUnsureLayers(std::vector< ABOARD6_LAYER_STACKUP > &aStackup)
std::vector< ZONE * > m_polygons
void ParsePads6Data(const ALTIUM_PCB_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry)
void ConvertArcs6ToPcbShape(const AARC6 &aElem, PCB_SHAPE *aShape)
void ConvertTracks6ToBoardItemOnLayer(const ATRACK6 &aElem, PCB_LAYER_ID aLayer)
void ConvertFills6ToBoardItem(const AFILL6 &aElem)
FOOTPRINT * HelperGetFootprint(uint16_t aComponent) const
LAYER_MAPPING_HANDLER m_layerMappingHandler
void ParsePolygons6Data(const ALTIUM_PCB_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry)
PCB_LAYER_ID GetKicadLayer(ALTIUM_LAYER aAltiumLayer) const
void ParseComponentsBodies6Data(const ALTIUM_PCB_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry)
void ConvertTracks6ToFootprintItemOnLayer(FOOTPRINT *aFootprint, const ATRACK6 &aElem, PCB_LAYER_ID aLayer)
void Parse(const ALTIUM_PCB_COMPOUND_FILE &aAltiumPcbFile, const std::map< ALTIUM_PCB_DIR, std::string > &aFileMapping)
ALTIUM_PCB(BOARD *aBoard, PROGRESS_REPORTER *aProgressReporter, LAYER_MAPPING_HANDLER &aLayerMappingHandler, REPORTER *aReporter=nullptr, const wxString &aLibrary=wxEmptyString, const wxString &aFootprintName=wxEmptyString)
void ConvertArcs6ToBoardItemOnLayer(const AARC6 &aElem, PCB_LAYER_ID aLayer)
void ParseTexts6Data(const ALTIUM_PCB_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry)
std::map< ALTIUM_RECORD, std::multimap< int, const AEXTENDED_PRIMITIVE_INFORMATION > > m_extendedPrimitiveInformationMaps
void ParseModelsData(const ALTIUM_PCB_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry, const std::vector< std::string > &aRootDir)
std::map< ALTIUM_LAYER, wxString > m_layerNames
void ConvertPads6ToBoardItemOnNonCopper(const APAD6 &aElem)
void HelperSetTextboxAlignmentAndPos(const ATEXT6 &aElem, PCB_TEXTBOX *aPcbTextbox)
void ConvertBarcodes6ToFootprintItemOnLayer(FOOTPRINT *aFootprint, const ATEXT6 &aElem, PCB_LAYER_ID aLayer)
void ParseNets6Data(const ALTIUM_PCB_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry)
void ConvertPads6ToFootprintItem(FOOTPRINT *aFootprint, const APAD6 &aElem)
const ARULE6 * GetRule(ALTIUM_RULE_KIND aKind, const wxString &aName) const
void ParseDimensions6Data(const ALTIUM_PCB_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry)
void HelperSetZoneLayers(ZONE &aZone, const ALTIUM_LAYER aAltiumLayer)
static wxString ReadString(const std::map< wxString, wxString > &aProps, const wxString &aKey, const wxString &aDefault)
BASE_SET & set(size_t pos)
Container for design settings for a BOARD object.
void SetGridOrigin(const VECTOR2I &aOrigin)
const VECTOR2I & GetGridOrigin() const
void SetAuxOrigin(const VECTOR2I &aOrigin)
const VECTOR2I & GetAuxOrigin() const
BOARD_STACKUP & GetStackupDescriptor()
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
virtual void SetIsKnockout(bool aKnockout)
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
virtual LSET BoardLayerSet() const
Return the LSET for the board that this item resides on.
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.
constexpr coord_type GetY() const
constexpr size_type GetWidth() const
constexpr coord_type GetX() const
constexpr size_type GetHeight() const
bool IsHorizontal() const
bool IsCardinal90() const
EDA_ANGLE GetArcAngle() const
void SetCenter(const VECTOR2I &aCenter)
virtual void SetFilled(bool aFlag)
void SetStart(const VECTOR2I &aStart)
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
void SetShape(SHAPE_T aShape)
void SetEnd(const VECTOR2I &aEnd)
void SetArcAngleAndEnd(const EDA_ANGLE &aAngle, bool aCheckNegativeAngle=false)
Set the end point from the angle center and start.
void SetPolyPoints(const std::vector< VECTOR2I > &aPoints)
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
int GetTextHeight() const
void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true)
void SetTextPos(const VECTOR2I &aPoint)
KIFONT::FONT * GetFont() const
void SetMirrored(bool isMirrored)
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
void SetBoldFlag(bool aBold)
Set only the bold flag, without changing the font.
void SetTextThickness(int aWidth)
The TextThickness is that set by the user.
GR_TEXT_V_ALIGN_T GetVertJustify() const
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
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)
wxString GetEmbeddedFileLink(const EMBEDDED_FILE &aFile) const
Return the link for an embedded file.
EMBEDDED_FILE * AddFile(const wxFileName &aName, bool aOverwrite)
Load a file from disk and adds it to the collection.
static RETURN_CODE CompressAndEncode(EMBEDDED_FILE &aFile)
Take data from the #decompressedData buffer and compresses it using ZSTD into the #compressedEncodedD...
VECTOR3D m_Offset
3D model offset (mm)
VECTOR3D m_Rotation
3D model rotation (degrees)
wxString m_Filename
The 3D shape filename in 3D library.
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)
virtual bool IsStroke() const
const wxString & GetName() const
virtual bool IsOutline() const
LAYER_RANGE_ITERATOR begin() const
A logical library item identifier and consists of various portions much like a URI.
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 & UserMask()
static LSET UserDefinedLayersMask(int aUserDefinedLayerCount=MAX_USER_DEFINED_LAYERS)
Return a mask with the requested number of user defined layers.
static const LSET & InternalCuMask()
Return a complete set of internal copper layers which is all Cu layers except F_Cu and B_Cu.
Handle the data for a net.
static const int UNCONNECTED
Constant that holds the "unconnected net" number (typically 0) all items "connected" to this net are ...
A PADSTACK defines the characteristics of a single or multi-layer pad, in the IPC sense of the word.
void SetRoundRectRadiusRatio(double aRatio, PCB_LAYER_ID aLayer)
void SetChamferRatio(double aRatio, PCB_LAYER_ID aLayer)
void SetShape(PAD_SHAPE aShape, PCB_LAYER_ID aLayer)
void SetChamferPositions(int aPositions, PCB_LAYER_ID aLayer)
@ NORMAL
Shape is the same on all layers.
@ CUSTOM
Shapes can be defined on arbitrary layers.
@ FRONT_INNER_BACK
Up to three shapes can be defined (F_Cu, inner copper layers, B_Cu)
void SetSize(const VECTOR2I &aSize, PCB_LAYER_ID aLayer)
static constexpr PCB_LAYER_ID ALL_LAYERS
! Temporary layer identifier to identify code that is not padstack-aware
static constexpr PCB_LAYER_ID INNER_LAYERS
! The layer identifier to use for "inner layers" on top/inner/bottom padstacks
static LSET PTHMask()
layer set for a through hole pad
static LSET UnplatedHoleMask()
layer set for a mechanical unplated through hole pad
static LSET SMDMask()
layer set for a SMD pad on Front layer
virtual VECTOR2I GetCenter() const override
This defaults to the center of the bounding box if not overridden.
A radial dimension indicates either the radius or diameter of an arc or circle.
VECTOR2I GetCenter() const override
This defaults to the center of the bounding box if not overridden.
void Rotate(const VECTOR2I &aRotCentre, const EDA_ANGLE &aAngle) override
Rotate this object.
void SetPosition(const VECTOR2I &aPos) override
void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
void SetStroke(const STROKE_PARAMS &aStroke) override
VECTOR2I GetPosition() const override
void SetBorderEnabled(bool enabled)
void SetMarginTop(int aTop)
void SetMarginLeft(int aLeft)
void SetMarginBottom(int aBottom)
void SetTextAngle(const EDA_ANGLE &aAngle) override
void SetMarginRight(int aRight)
A progress reporter interface for use in multi-threaded environments.
A pure virtual class used to derive REPORTER objects from.
OPT_VECTOR2I Intersect(const SEG &aSeg, bool aIgnoreEndpoints=false, bool aLines=false) const
Compute intersection point of segment (this) with segment aSeg.
const VECTOR2I & GetArcMid() const
const VECTOR2I & GetP1() const
const VECTOR2I & GetP0() const
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
const SHAPE_ARC & Arc(size_t aArc) const
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.
ssize_t ArcIndex(size_t aSegment) const
Return the arc index for the given segment index.
SEG Segment(int aIndex) const
Return a copy of the aIndex-th segment in the line chain.
int NextShape(int aPointIndex) const
Return the vertex index of the next shape in the chain, or -1 if aPointIndex is the last shape.
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
bool IsArcStart(size_t aIndex) const
Represent a set of closed polygons.
void Rotate(const EDA_ANGLE &aAngle, const VECTOR2I &aCenter={ 0, 0 }) override
Rotate all vertices by a given angle.
void BooleanAdd(const SHAPE_POLY_SET &b)
Perform boolean polyset union.
int AddOutline(const SHAPE_LINE_CHAIN &aOutline)
Adds a new outline to the set and returns its index.
void Fracture()
Convert a set of polygons with holes to a single outline with "slits"/"fractures" connecting the oute...
void Inflate(int aAmount, CORNER_STRATEGY aCornerStrategy, int aMaxError, bool aSimplify=false)
Perform outline inflation/deflation.
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Appends a vertex at the end of the given outline/hole (default: the last 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.
int NewOutline()
Creates a new empty polygon in the set and returns its index.
int OutlineCount() const
Return the number of outlines in the set.
void Move(const VECTOR2I &aVector) override
Simple container to manage line stroke parameters.
constexpr extended_type Cross(const VECTOR2< T > &aVector) const
Compute cross product of self with aVector.
double Distance(const VECTOR2< extended_type > &aVector) const
Compute the distance between two vectors.
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
constexpr VECTOR2< T > Perpendicular() const
Compute the perpendicular vector.
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 SetNeedRefill(bool aNeedRefill)
void SetDoNotAllowPads(bool aEnable)
SHAPE_POLY_SET * GetFill(PCB_LAYER_ID aLayer)
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)
bool HasFilledPolysForLayer(PCB_LAYER_ID aLayer) const
void SetLayerSet(const LSET &aLayerSet) override
void SetDoNotAllowVias(bool aEnable)
void SetDoNotAllowFootprints(bool aEnable)
void SetDoNotAllowZoneFills(bool aEnable)
static int GetDefaultHatchPitch()
@ CHAMFER_ACUTE_CORNERS
Acute angles are chamfered.
static constexpr EDA_ANGLE ANGLE_90
static constexpr EDA_ANGLE ANGLE_45
@ RECTANGLE
Use RECTANGLE instead of RECT to avoid collision in a Windows header.
bool m_ImportSkipComponentBodies
Skip importing component bodies when importing some format files, such as Altium.
#define THROW_IO_ERROR(msg)
macro which captures the "call site" values of FILE_, __FUNCTION & LINE
bool IsCopperLayer(int aLayerId)
Test whether a layer is a copper layer.
size_t CopperLayerToOrdinal(PCB_LAYER_ID aLayer)
Converts KiCad copper layer enum to an ordinal between the front and back layers.
PCB_LAYER_ID
A quick note on layer IDs:
void for_all_pairs(_InputIterator __first, _InputIterator __last, _Function __f)
Apply a function to every possible pair of elements of a sequence.
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.
BARCODE class definition.
std::function< std::map< wxString, PCB_LAYER_ID >(const std::vector< INPUT_LAYER_DESC > &)> LAYER_MAPPING_HANDLER
Pointer to a function that takes a map of source and KiCad layers and returns a re-mapped version.
std::optional< VECTOR2I > OPT_VECTOR2I
wxString NotSpecifiedPrm()
uint8_t keepoutrestrictions
wxString dielectricmaterial
std::vector< ABOARD6_LAYER_STACKUP > stackup
std::vector< ALTIUM_VERTICE > board_vertices
std::vector< wxString > names
wxString sourceHierachicalPath
wxString sourcefootprintlibrary
wxString sourcedesignator
std::vector< VECTOR2I > textPoint
ALTIUM_DIMENSION_KIND kind
std::vector< VECTOR2I > referencePoint
uint8_t keepoutrestrictions
std::vector< char > m_data
ALTIUM_PAD_SHAPE inner_shape[29]
ALTIUM_PAD_HOLE_SHAPE holeshape
ALTIUM_PAD_SHAPE_ALT alt_shape[32]
int32_t soldermaskexpansionmanual
std::unique_ptr< APAD6_SIZE_AND_SHAPE > sizeAndShape
ALTIUM_PAD_SHAPE topshape
ALTIUM_MODE pastemaskexpansionmode
ALTIUM_MODE soldermaskexpansionmode
ALTIUM_PAD_SHAPE botshape
ALTIUM_PAD_SHAPE midshape
int32_t pastemaskexpansionmanual
int32_t pad_to_die_length
std::vector< ALTIUM_VERTICE > vertices
ALTIUM_POLYGON_HATCHSTYLE hatchstyle
uint8_t keepoutrestrictions
std::vector< ALTIUM_VERTICE > outline
std::vector< std::vector< ALTIUM_VERTICE > > holes
ALTIUM_CONNECT_STYLE polygonconnectStyle
int planeclearanceClearance
int32_t polygonconnectReliefconductorwidth
int32_t polygonconnectAirgapwidth
uint32_t text_offset_width
uint32_t textbox_rect_height
ALTIUM_TEXT_POSITION textbox_rect_justification
uint32_t textbox_rect_width
uint32_t margin_border_width
bool isJustificationValid
ALTIUM_BARCODE_TYPE barcode_type
ALTIUM_TEXT_TYPE fonttype
uint8_t keepoutrestrictions
int32_t soldermask_expansion_front
bool soldermask_expansion_manual
int32_t soldermask_expansion_back
uint32_t diameter_by_layer[32]
std::vector< char > decompressedData
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_SHAPE_T
class PCB_SHAPE, a segment not on copper layers
@ PCB_DIM_ALIGNED_T
class PCB_DIM_ALIGNED, a linear dimension (graphic item)
@ PCB_ARC_T
class PCB_ARC, an arc track segment on a copper layer
VECTOR2< int32_t > VECTOR2I
VECTOR3< double > VECTOR3D
@ THERMAL
Use thermal relief for pads.
@ NONE
Pads are not covered.
@ FULL
pads are covered by copper