52#include <compoundfilereader.h>
59#include <wx/docview.h>
61#include <wx/mstream.h>
62#include <wx/wfstream.h>
63#include <wx/zstream.h>
65#include <magic_enum.hpp>
88 THROW_IO_ERROR( wxString::Format( wxT(
"Component creator tries to access component id %u "
89 "of %u existing components" ),
98 const std::vector<ALTIUM_VERTICE>& aVertices )
107 double startradiant =
DEG2RAD( vertex.startangle );
108 double endradiant =
DEG2RAD( vertex.endangle );
109 VECTOR2I arcStartOffset =
KiROUND( std::cos( startradiant ) * vertex.radius,
110 -std::sin( startradiant ) * vertex.radius );
112 VECTOR2I arcEndOffset =
KiROUND( std::cos( endradiant ) * vertex.radius,
113 -std::sin( endradiant ) * vertex.radius );
115 VECTOR2I arcStart = vertex.center + arcStartOffset;
116 VECTOR2I arcEnd = vertex.center + arcEndOffset;
121 if( arcStart.
Distance( vertex.position )
122 < arcEnd.
Distance( vertex.position ) )
149 aLine.
Append( vertex.position );
159 auto override =
m_layermap.find( aAltiumLayer );
163 return override->second;
178 switch( aAltiumLayer )
280 std::vector<PCB_LAYER_ID> layers;
281 layers.reserve( layerCount );
286 layers.emplace_back( layer );
303 const wxString& aLibrary,
const wxString& aFootprintName )
323 const unsigned PROGRESS_DELTA = 250;
341 const std::map<ALTIUM_PCB_DIR, std::string>& aFileMapping )
344 const std::vector<std::tuple<bool, ALTIUM_PCB_DIR, PARSE_FUNCTION_POINTER_fp>> parserOrder = {
461 for(
const std::tuple<bool, ALTIUM_PCB_DIR, PARSE_FUNCTION_POINTER_fp>& cur : parserOrder )
466 std::tie( isRequired,
directory, fp ) = cur;
471 const auto& mappedDirectory = aFileMapping.find(
directory );
473 if( mappedDirectory == aFileMapping.end() )
476 const std::vector<std::string> mappedFile{ mappedDirectory->second,
"Header" };
477 const CFB::COMPOUND_FILE_ENTRY* file = altiumPcbFile.
FindStream( mappedFile );
479 if( file ==
nullptr )
483 uint32_t numOfRecords = reader.
Read<uint32_t>();
489 m_reporter->Report( wxString::Format(
_(
"'%s' was not parsed correctly." ),
503 m_reporter->Report( wxString::Format(
_(
"'%s' was not fully parsed." ),
515 if( boardDirectory != aFileMapping.end() )
517 std::vector<std::string> mappedFile{ boardDirectory->second,
"Data" };
519 const CFB::COMPOUND_FILE_ENTRY* file = altiumPcbFile.
FindStream( mappedFile );
524 "This file does not appear to be in a valid PCB Binary Version 6.0 format. In "
526 "make sure to save as \"PCB Binary Files (*.PcbDoc)\"." ) );
531 for(
const std::tuple<bool, ALTIUM_PCB_DIR, PARSE_FUNCTION_POINTER_fp>& cur : parserOrder )
536 std::tie( isRequired,
directory, fp ) = cur;
538 const auto& mappedDirectory = aFileMapping.find(
directory );
540 if( mappedDirectory == aFileMapping.end() )
542 wxASSERT_MSG( !isRequired, wxString::Format( wxT(
"Altium Directory of kind %d was "
543 "expected, but no mapping is "
544 "present in the code" ),
549 std::vector<std::string> mappedFile{ mappedDirectory->second };
552 mappedFile.emplace_back(
"Data" );
554 const CFB::COMPOUND_FILE_ENTRY* file = altiumPcbFile.
FindStream( mappedFile );
556 if( file !=
nullptr )
558 fp( altiumPcbFile, file );
560 else if( isRequired )
564 m_reporter->Report( wxString::Format(
_(
"File not found: '%s' for directory '%s'." ),
583 if( zone->GetAssignedPriority() == 1000 )
594 zone->SetAssignedPriority( priority >= 0 ? priority : 0 );
598 for( std::pair<const ALTIUM_LAYER, ZONE*>& zone :
m_outer_plane )
599 zone.second->SetAssignedPriority( 0 );
609 if( !zone->HasFilledPolysForLayer( layer ) )
612 zone->GetFilledPolysList( layer )->Fracture();
650 if( arc->
GetCenter() == dim->GetPosition() )
659 VECTOR2I radialLine = dim->GetEnd() - dim->GetStart();
664 radialLine = radialLine.
Resize( std::max(
radius, 2 ) );
665 dim->SetEnd( dim->GetStart() + (
VECTOR2I) radialLine );
666 dim->SetLeaderLength( totalLength -
radius );
676 int desired_x = ( w - bbbox.
GetWidth() ) / 2;
677 int desired_y = ( h - bbbox.
GetHeight() ) / 2;
679 VECTOR2I movementVector( desired_x - bbbox.
GetX(), desired_y - bbbox.
GetY() );
680 m_board->Move( movementVector );
691 const wxString& aFootprintName )
693 std::unique_ptr<FOOTPRINT> footprint = std::make_unique<FOOTPRINT>(
m_board );
698 const std::vector<std::string> libStreamName{
"Library",
"Data" };
699 const CFB::COMPOUND_FILE_ENTRY* libStream = altiumLibFile.
FindStream( libStreamName );
701 if( libStream ==
nullptr )
719 std::tuple<wxString, const CFB::COMPOUND_FILE_ENTRY*> ret =
722 wxString fpDirName = std::get<0>( ret );
723 const CFB::COMPOUND_FILE_ENTRY* footprintStream = std::get<1>( ret );
725 if( fpDirName.IsEmpty() )
728 wxString::Format(
_(
"Footprint directory not found: '%s'." ), aFootprintName ) );
731 const std::vector<std::string> streamName{ fpDirName.ToStdString(),
"Data" };
732 const CFB::COMPOUND_FILE_ENTRY* footprintData = altiumLibFile.
FindStream( footprintStream, {
"Data" } );
734 if( footprintData ==
nullptr )
747 footprint->SetFPID( fpID );
749 const std::vector<std::string> parametersStreamName{ fpDirName.ToStdString(),
751 const CFB::COMPOUND_FILE_ENTRY* parametersData =
752 altiumLibFile.
FindStream( footprintStream, {
"Parameters" } );
754 if( parametersData !=
nullptr )
757 std::map<wxString, wxString> parameterProperties = parametersReader.
ReadProperties();
759 wxT(
"DESCRIPTION" ), wxT(
"" ) );
760 footprint->SetLibDescription( description );
766 m_reporter->Report( wxString::Format(
_(
"File not found: '%s'." ),
771 footprint->SetLibDescription( wxT(
"" ) );
774 const std::vector<std::string> extendedPrimitiveInformationStreamName{
775 "ExtendedPrimitiveInformation",
"Data"
777 const CFB::COMPOUND_FILE_ENTRY* extendedPrimitiveInformationData =
778 altiumLibFile.
FindStream( footprintStream, extendedPrimitiveInformationStreamName );
780 if( extendedPrimitiveInformationData !=
nullptr )
783 footprint->SetReference( wxT(
"REF**" ) );
784 footprint->SetValue( aFootprintName );
785 footprint->Reference().SetVisible(
true );
786 footprint->Value().SetVisible(
true );
789 const int defaultTextThickness(
pcbIUScale.mmToIU( 0.15 ) );
791 for(
PCB_FIELD* field : footprint->GetFields() )
793 field->SetTextSize( defaultTextSize );
794 field->SetTextThickness( defaultTextThickness );
852 THROW_IO_ERROR( wxString::Format(
_(
"Record of unknown type: '%d'." ), recordtype ) );
858 for(
bool changes =
true; changes; )
863 [&changes](
PAD* aPad1,
PAD* aPad2 )
865 if( !( aPad1->GetNumber().IsEmpty() ^ aPad2->GetNumber().IsEmpty() ) )
868 for( PCB_LAYER_ID layer : aPad1->GetLayerSet() )
870 std::shared_ptr<SHAPE> shape1 = aPad1->GetEffectiveShape( layer );
871 std::shared_ptr<SHAPE> shape2 = aPad2->GetEffectiveShape( layer );
873 if( shape1->Collide( shape2.get() ) )
875 if( aPad1->GetNumber().IsEmpty() )
876 aPad1->SetNumber( aPad2->GetNumber() );
878 aPad2->SetNumber( aPad1->GetNumber() );
887 footprint->AutoPositionFields();
889 if( parser.HasParsingError() )
891 THROW_IO_ERROR( wxString::Format( wxT(
"%s stream was not parsed correctly" ),
895 if( parser.GetRemainingBytes() != 0 )
897 THROW_IO_ERROR( wxString::Format( wxT(
"%s stream is not fully parsed" ),
901 return footprint.release();
912 THROW_IO_ERROR( wxString::Format( wxT(
"Netcode with id %d does not exist. Only %d nets "
924 const auto rules =
m_rules.find( aKind );
929 for(
const ARULE6& rule : rules->second )
931 if( rule.
name == aName )
940 const auto rules =
m_rules.find( aKind );
945 for(
const ARULE6& rule : rules->second )
957 const auto rules =
m_rules.find( aKind );
971 const CFB::COMPOUND_FILE_ENTRY* aEntry )
989 const CFB::COMPOUND_FILE_ENTRY* aEntry )
1002 std::move( elem ) );
1006 THROW_IO_ERROR( wxT(
"ExtendedPrimitiveInformation stream is not fully parsed" ) );
1011 const CFB::COMPOUND_FILE_ENTRY* aEntry )
1028 size_t layercount = 0;
1031 while( layerid < elem.
stackup.size() && layerid != 0 )
1033 layerid = elem.
stackup[ layerid - 1 ].nextId;
1037 size_t kicadLayercount = ( layercount % 2 == 0 ) ? layercount : layercount + 1;
1038 m_board->SetCopperLayerCount( kicadLayercount );
1047 auto it = stackup.
GetList().begin();
1056 altiumLayerId < elem.
stackup.size() && altiumLayerId != 0;
1057 altiumLayerId = elem.
stackup[altiumLayerId - 1].nextId )
1063 if( layer.
nextId == 0 && layercount != kicadLayercount )
1065 m_board->SetLayerName( ( *it )->GetBrdLayerId(), wxT(
"[unused]" ) );
1068 THROW_IO_ERROR( wxT(
"Board6 stream, unexpected item while parsing stackup" ) );
1070 ( *it )->SetThickness( 0 );
1075 THROW_IO_ERROR( wxT(
"Board6 stream, unexpected item while parsing stackup" ) );
1077 ( *it )->SetThickness( 0, 0 );
1078 ( *it )->SetThicknessLocked(
true, 0 );
1086 THROW_IO_ERROR( wxT(
"Board6 stream, unexpected item while parsing stackup" ) );
1100 if( klayer ==
B_Cu )
1103 THROW_IO_ERROR( wxT(
"Board6 stream, unexpected id while parsing last stackup layer" ) );
1113 THROW_IO_ERROR( wxT(
"Board6 stream, unexpected item while parsing stackup" ) );
1152 wxString nameLower = aName.Lower();
1153 return nameLower.Contains( wxT(
"courtyard" ) ) || nameLower.Contains( wxT(
"court yard" ) )
1154 || nameLower.Contains( wxT(
"crtyd" ) );
1161 wxString nameLower = aName.Lower();
1162 return nameLower.Contains( wxT(
"assembly" ) ) || nameLower.Contains( wxT(
"assy" ) );
1171 auto check = [&isTop](
bool aTopCond,
bool aBotCond )
1173 if( aTopCond && aBotCond )
1176 if( !aTopCond && !aBotCond )
1183 wxString lower = aName.Lower();
1185 if( check( lower.StartsWith(
"top" ), lower.StartsWith(
"bot" ) ) )
1188 if( check( lower.EndsWith(
"_t" ), lower.EndsWith(
"_b" ) ) )
1191 if( check( lower.EndsWith(
".t" ), lower.EndsWith(
".b" ) ) )
1194 if( check( lower.Contains(
"top" ), lower.Contains(
"bot" ) ) )
1207 if( aStackup.size() == 0 )
1210 std::vector<INPUT_LAYER_DESC> inputLayers;
1211 std::map<wxString, ALTIUM_LAYER> altiumLayerNameMap;
1218 bool frontCourtyardMapped =
false;
1219 bool backCourtyardMapped =
false;
1221 for(
size_t ii = 0; ii < aStackup.size(); ii++ )
1223 curLayer = aStackup[ii];
1242 auto existingMapping =
m_layermap.find( layer_num );
1269 if( isTopSide && !frontCourtyardMapped )
1272 frontCourtyardMapped =
true;
1274 else if( !isTopSide && !backCourtyardMapped )
1277 backCourtyardMapped =
true;
1279 else if( !frontCourtyardMapped )
1282 frontCourtyardMapped =
true;
1284 else if( !backCourtyardMapped )
1287 backCourtyardMapped =
true;
1310 inputLayers.push_back( iLdesc );
1311 altiumLayerNameMap.insert( { curLayer.
name, layer_num } );
1315 if( inputLayers.size() == 0 )
1321 for( std::pair<wxString, PCB_LAYER_ID> layerPair : reMappedLayers )
1329 m_reporter->Report( wxString::Format(
_(
"Layer '%s' could not be mapped and "
1330 "will be skipped." ),
1338 ALTIUM_LAYER altiumID = altiumLayerNameMap.at( layerPair.first );
1339 m_layermap.insert_or_assign( altiumID, layerPair.second );
1340 enabledLayers |=
LSET( { layerPair.second } );
1345 for(
const auto& [
name, altLayer] : altiumLayerNameMap )
1347 if( reMappedLayers.find(
name ) == reMappedLayers.end()
1354 m_board->SetEnabledLayers( enabledLayers );
1355 m_board->SetVisibleLayers( enabledLayers );
1368 if( !layer.mechenabled )
1376 switch( layer.mechkind )
1437 shape->SetStroke( stroke );
1449 shape->SetStroke( stroke );
1451 shape->SetStart( seg.
A );
1452 shape->SetEnd( seg.
B );
1461 const CFB::COMPOUND_FILE_ENTRY* aEntry )
1475 std::shared_ptr<NETCLASS> nc = std::make_shared<NETCLASS>( elem.
name );
1477 for(
const wxString&
name : elem.
names )
1479 m_board->GetDesignSettings().m_NetSettings->SetNetclassPatternAssignment(
1480 name, nc->GetName() );
1483 if(
m_board->GetDesignSettings().m_NetSettings->HasNetclass( nc->GetName() ) )
1490 msg.Printf(
_(
"More than one Altium netclass with name '%s' found. "
1491 "Only the first one will be imported." ), elem.
name );
1497 m_board->GetDesignSettings().m_NetSettings->SetNetclass( nc->GetName(), nc );
1507 std::shared_ptr<NET_SETTINGS> netSettings =
m_board->GetDesignSettings().m_NetSettings;
1511 if( net->GetNetCode() > 0 )
1513 std::shared_ptr<NETCLASS> netclass = netSettings->GetEffectiveNetClass( net->GetNetname() );
1516 net->SetNetClass( netclass );
1520 m_board->m_LegacyNetclassesLoaded =
true;
1525 const CFB::COMPOUND_FILE_ENTRY* aEntry )
1537 std::unique_ptr<FOOTPRINT> footprint = std::make_unique<FOOTPRINT>(
m_board );
1548 wxString fpName = elem.
pattern;
1550 if( fpName.Contains( wxT(
"\\" ) ) || fpName.Contains( wxT(
"/" ) ) )
1552 wxFileName fpPath( fpName, wxPATH_WIN );
1553 fpName = fpPath.GetFullName();
1558 footprint->SetFPID( fpID );
1560 footprint->SetPosition( elem.
position );
1561 footprint->SetOrientationDegrees( elem.
rotation );
1567 if( reference.find_first_not_of(
"0123456789" ) == wxString::npos )
1568 reference.Prepend( wxT(
"UNK" ) );
1570 footprint->SetReference( reference );
1575 path.push_back( pathid );
1576 path.push_back(
id );
1578 footprint->SetPath(
path );
1582 footprint->SetLocked( elem.
locked );
1583 footprint->Reference().SetVisible( elem.
nameon );
1584 footprint->Value().SetVisible( elem.
commenton );
1592 THROW_IO_ERROR( wxT(
"Components6 stream is not fully parsed" ) );
1599 while( Angle < aMin )
1602 while( Angle >= aMax )
1625 m_reporter->Report( wxString::Format( wxT(
"Model %s not found for footprint %s" ),
1636 if( file->
name.IsEmpty() )
1640 std::vector<char> decompressedData;
1641 wxMemoryInputStream compressedStream(
model->second.data(),
model->second.size() );
1642 wxZlibInputStream zlibStream( compressedStream );
1646 decompressedData.resize(
model->second.size() * 6 );
1649 while( !zlibStream.Eof() )
1651 zlibStream.Read( decompressedData.data() + offset, decompressedData.size() - offset );
1652 size_t bytesRead = zlibStream.LastRead();
1657 offset += bytesRead;
1659 if( offset >= decompressedData.size() )
1660 decompressedData.resize( 2 * decompressedData.size() );
1663 decompressedData.resize( offset );
1684 orientation = -orientation;
1691 modelRotation.
x += 180;
1692 modelRotation.
z = -modelRotation.
z;
1706 aFootprint->
Models().push_back( modelSettings );
1711 const CFB::COMPOUND_FILE_ENTRY* aEntry )
1717 BS::multi_future<void> embeddedFutures;
1728 if( skipComponentBodies )
1736 THROW_IO_ERROR( wxString::Format( wxT(
"ComponentsBodies6 stream tries to access "
1737 "component id %d of %zu existing components" ),
1752 msg.Printf( wxT(
"ComponentsBodies6 stream tries to access model id %s which does "
1753 "not exist" ), elem.
modelId );
1766 wxMemoryInputStream compressedStream( modelData.
m_data.data(), modelData.
m_data.size() );
1767 wxZlibInputStream zlibStream( compressedStream );
1768 wxMemoryOutputStream decompressedStream;
1770 zlibStream.Read( decompressedStream );
1776 embeddedFutures.push_back(
tp.submit_task(
1779 EMBEDDED_FILES::CompressAndEncode( *file );
1798 orientation = -orientation;
1821 footprint->
Models().push_back( modelSettings );
1824 embeddedFutures.wait();
1827 THROW_IO_ERROR( wxT(
"ComponentsBodies6 stream is not fully parsed" ) );
1834 THROW_IO_ERROR( wxT(
"Incorrect number of reference points for linear dimension object" ) );
1843 _(
"Dimension found on an Altium layer (%d) with no KiCad equivalent. "
1844 "It has been moved to KiCad layer Eco1_User." ), aElem.
layer ),
1857 dimension->SetLayer( klayer );
1858 dimension->SetStart( referencePoint0 );
1860 if( referencePoint0 != aElem.
xy1 )
1872 VECTOR2I referenceDiff = referencePoint1 - referencePoint0;
1874 SEG segm1( referencePoint0, referencePoint0 + directionNormalVector );
1875 SEG segm2( referencePoint1, referencePoint1 + direction );
1879 THROW_IO_ERROR( wxT(
"Invalid dimension. This should never happen." ) );
1881 dimension->SetEnd( *intersection );
1885 if( direction.
Cross( referenceDiff ) > 0 )
1888 dimension->SetHeight( height );
1892 dimension->SetEnd( referencePoint1 );
1895 dimension->SetLineThickness( aElem.
linewidth );
1901 int dist = ( dimension->GetEnd() - dimension->GetStart() ).EuclideanNorm();
1903 if( dist < 3 * dimension->GetArrowLength() )
1907 wxRegEx units( wxS(
"(mm)|(in)|(mils)|(thou)|(')|(\")" ), wxRE_ADVANCED );
1919 dimension->Text().SetBold( aElem.
textbold );
1922 dimension->SetTextThickness( dimension->GetTextThickness() *
BOLD_FACTOR );
1941 THROW_IO_ERROR( wxT(
"Not enough reference points for radial dimension object" ) );
1950 _(
"Dimension found on an Altium layer (%d) with no KiCad equivalent. "
1951 "It has been moved to KiCad layer Eco1_User." ),
1960 std::unique_ptr<PCB_DIM_RADIAL> dimension = std::make_unique<PCB_DIM_RADIAL>(
m_board );
1963 dimension->SetLayer( klayer );
1964 dimension->SetStart( referencePoint0 );
1965 dimension->SetEnd( aElem.
xy1 );
1966 dimension->SetLineThickness( aElem.
linewidth );
1967 dimension->SetKeepTextAligned(
false );
1988 m_reporter->Report( wxT(
"No text position present for leader dimension object" ),
1995 dimension->SetTextPos( aElem.
textPoint.at( 0 ) );
2001 dimension->SetBold( aElem.
textbold );
2004 dimension->SetTextThickness( dimension->GetTextThickness() *
BOLD_FACTOR );
2012 int yAdjust = dimension->GetTextBox(
nullptr ).GetCenter().y - dimension->GetTextPos().y;
2013 dimension->SetTextPos( dimension->GetTextPos() +
VECTOR2I( 0, yAdjust + aElem.
textgap ) );
2030 msg.Printf(
_(
"Dimension found on an Altium layer (%d) with no KiCad equivalent. "
2031 "It has been moved to KiCad layer Eco1_User." ), aElem.
layer );
2048 shape->SetLayer( klayer );
2050 shape->SetStart( last );
2062 if( dirVec.
x != 0 || dirVec.
y != 0 )
2071 shape1->SetLayer( klayer );
2073 shape1->SetStart( referencePoint0 );
2074 shape1->SetEnd( referencePoint0 + arrVec );
2084 shape2->SetLayer( klayer );
2086 shape2->SetStart( referencePoint0 );
2087 shape2->SetEnd( referencePoint0 + arrVec );
2099 m_reporter->Report( wxT(
"No text position present for leader dimension object" ),
2106 std::unique_ptr<PCB_TEXT>
text = std::make_unique<PCB_TEXT>(
m_board );
2110 text->SetLayer( klayer );
2129 msg.Printf(
_(
"Dimension found on an Altium layer (%d) with no KiCad equivalent. "
2130 "It has been moved to KiCad layer Eco1_User." ), aElem.
layer );
2141 shape->SetLayer( klayer );
2160 msg.Printf(
_(
"Dimension found on an Altium layer (%d) with no KiCad equivalent. "
2161 "It has been moved to KiCad layer Eco1_User." ), aElem.
layer );
2171 std::unique_ptr<PCB_DIM_CENTER> dimension = std::make_unique<PCB_DIM_CENTER>(
m_board );
2173 dimension->SetLayer( klayer );
2174 dimension->SetLineThickness( aElem.
linewidth );
2175 dimension->SetStart( aElem.
xy1 );
2176 dimension->SetEnd( aElem.
xy1 + vec );
2183 const CFB::COMPOUND_FILE_ENTRY* aEntry )
2203 m_reporter->Report( wxString::Format(
_(
"Ignored Angular dimension (not yet supported)." ) ),
2216 m_reporter->Report( wxString::Format(
_(
"Ignored Datum dimension (not yet supported)." ) ),
2224 m_reporter->Report( wxString::Format(
_(
"Ignored Baseline dimension (not yet supported)." ) ),
2234 m_reporter->Report( wxString::Format(
_(
"Ignored Linear dimension (not yet supported)." ) ),
2241 m_reporter->Report( wxString::Format(
_(
"Ignored Radial dimension (not yet supported)." ) ),
2249 msg.Printf(
_(
"Ignored dimension of kind %d (not yet supported)." ), elem.
kind );
2257 THROW_IO_ERROR( wxT(
"Dimensions6 stream is not fully parsed" ) );
2262 const CFB::COMPOUND_FILE_ENTRY* aEntry,
2263 const std::vector<std::string>& aRootDir )
2274 wxString invalidChars = wxFileName::GetForbiddenChars();
2281 std::vector<std::string> stepPath = aRootDir;
2282 stepPath.emplace_back( std::to_string( idx ) );
2284 bool validName = !elem.
name.IsEmpty() && elem.
name.IsAscii()
2285 && wxString::npos == elem.
name.find_first_of( invalidChars );
2286 wxString storageName = validName ? elem.
name : wxString::Format( wxT(
"model_%d" ), idx );
2290 const CFB::COMPOUND_FILE_ENTRY* stepEntry = aAltiumPcbFile.
FindStream( stepPath );
2292 if( stepEntry ==
nullptr )
2297 msg.Printf(
_(
"File not found: '%s'. 3D-model not imported." ),
FormatPath( stepPath ) );
2304 size_t stepSize =
static_cast<size_t>( stepEntry->size );
2305 std::vector<char> stepContent( stepSize );
2313 std::move( stepContent ) ) ) );
2317 std::map<wxString, std::vector<wxString>> nameIdMap;
2320 nameIdMap[data.m_modelname].push_back(
id );
2322 for(
auto& [
name, ids] : nameIdMap )
2324 for(
size_t i = 1; i < ids.size(); i++ )
2326 const wxString&
id = ids[i];
2333 wxString modelName = modelTuple->second.m_modelname;
2335 if( modelName.Contains(
"." ) )
2338 wxString baseName = modelName.BeforeLast(
'.', &ext );
2340 modelTuple->second.m_modelname = baseName +
'_' + std::to_string( i ) +
'.' + ext;
2344 modelTuple->second.m_modelname = modelName +
'_' + std::to_string( i );
2355 const CFB::COMPOUND_FILE_ENTRY* aEntry )
2367 ANET6 elem( reader );
2381 const CFB::COMPOUND_FILE_ENTRY* aEntry )
2424 msg.Printf(
_(
"Polygon outline count is %d, expected 1." ), outline.
OutlineCount() );
2432 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>(
m_board);
2438 zone->SetPosition( elem.
vertices.at( 0 ).position );
2439 zone->SetLocked( elem.
locked );
2441 zone->Outline()->AddOutline( outline.
Outline( 0 ) );
2448 int planeLayers = 0;
2449 int signalLayers = 0;
2463 if( planeLayers > 0 && planeClearanceRule )
2466 if( signalLayers > 0 && zoneClearanceRule )
2474 if( polygonConnectRule !=
nullptr )
2493 zone->SetThermalReliefSpokeWidth(
2504 zone->SetAssignedPriority( 1 );
2509 || zone->GetBoundingBox().Contains( outer_plane->second->GetBoundingBox() ) )
2524 const BOX2I& bbox = zone->GetBoundingBox();
2533 zone->SetHatchOrientation(
ANGLE_45 );
2548 const CFB::COMPOUND_FILE_ENTRY* aEntry )
2567 std::sort( val.second.begin(), val.second.end(),
2570 return lhs.priority < rhs.priority;
2583 if( trackWidthRule )
2585 m_board->GetDesignSettings().m_TrackMinWidth = trackWidthRule->
minLimit;
2589 if( routingViasRule )
2591 m_board->GetDesignSettings().m_ViasMinSize = routingViasRule->
minWidth;
2600 if( holeToHoleRule )
2606 if( soldermaskRule )
2617 const CFB::COMPOUND_FILE_ENTRY* aEntry )
2633 THROW_IO_ERROR( wxT(
"BoardRegions stream is not fully parsed" ) );
2637 const CFB::COMPOUND_FILE_ENTRY* aEntry )
2645 for(
int primitiveIndex = 0; reader.
GetRemainingBytes() >= 4; primitiveIndex++ )
2664 THROW_IO_ERROR(
"ShapeBasedRegions6 stream is not fully parsed" );
2688 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>(
m_board );
2690 zone->SetIsRuleArea(
true );
2698 zone->SetDoNotAllowZoneFills(
true );
2699 zone->SetDoNotAllowVias(
false );
2700 zone->SetDoNotAllowTracks(
false );
2701 zone->SetDoNotAllowPads(
false );
2702 zone->SetDoNotAllowFootprints(
false );
2705 zone->SetPosition( aElem.
outline.at( 0 ).position );
2706 zone->Outline()->AddOutline( linechain );
2726 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>(
m_board );
2728 zone->SetPosition( aElem.
outline.at( 0 ).position );
2729 zone->Outline()->AddOutline( linechain );
2737 fill.
Append( linechain );
2741 zone->SetFilledPolysList( klayer, fill );
2743 zone->SetIsFilled(
true );
2744 zone->SetNeedRefill(
false );
2757 msg.Printf(
_(
"Dashed outline found on an Altium layer (%d) with no KiCad equivalent. "
2758 "It has been moved to KiCad layer Eco1_User." ), aElem.
layer );
2779 shape->SetPolyShape( linechain );
2780 shape->SetFilled(
false );
2781 shape->SetLayer( klayer );
2799 msg.Printf(
_(
"Ignored polygon shape of kind %d (not yet supported)." ), aElem.
kind );
2808 const int aPrimitiveIndex )
2824 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>( aFootprint );
2826 zone->SetIsRuleArea(
true );
2834 zone->SetDoNotAllowZoneFills(
true );
2835 zone->SetDoNotAllowVias(
false );
2836 zone->SetDoNotAllowTracks(
false );
2837 zone->SetDoNotAllowPads(
false );
2838 zone->SetDoNotAllowFootprints(
false );
2841 zone->SetPosition( aElem.
outline.at( 0 ).position );
2842 zone->Outline()->AddOutline( linechain );
2876 msg.Printf(
_(
"Loading library '%s':\n"
2877 "Footprint %s contains a dashed outline on Altium layer (%d) with "
2878 "no KiCad equivalent. It has been moved to KiCad layer Eco1_User." ),
2890 msg.Printf(
_(
"Footprint %s contains a dashed outline on Altium layer (%d) with "
2891 "no KiCad equivalent. It has been moved to KiCad layer Eco1_User." ),
2913 std::unique_ptr<PCB_SHAPE> shape = std::make_unique<PCB_SHAPE>( aFootprint,
SHAPE_T::POLY );
2915 shape->SetPolyShape( linechain );
2916 shape->SetFilled(
false );
2917 shape->SetLayer( klayer );
2933 msg.Printf(
_(
"Error loading library '%s':\n"
2934 "Footprint %s contains polygon shape of kind %d (not yet supported)." ),
2946 msg.Printf(
_(
"Footprint %s contains polygon shape of kind %d (not yet supported)." ),
2974 for(
const std::vector<ALTIUM_VERTICE>& hole : aElem.
holes )
2982 polySet.
AddHole( hole_linechain );
2987 shape->SetPolyShape( polySet );
2988 shape->SetFilled(
true );
2989 shape->SetLayer( aLayer );
3004 const int aPrimitiveIndex )
3021 for(
const std::vector<ALTIUM_VERTICE>& hole : aElem.
holes )
3029 polySet.
AddHole( hole_linechain );
3032 if( aLayer ==
F_Cu || aLayer ==
B_Cu )
3035 std::unique_ptr<PAD>
pad = std::make_unique<PAD>( aFootprint );
3038 padLayers.
set( aLayer );
3049 pad->SetPosition( anchorPos );
3052 shapePolys.
Move( -anchorPos );
3056 auto it = map.find( aPrimitiveIndex );
3058 if( it != map.end() )
3064 pad->SetLocalSolderPasteMargin(
info.pastemaskexpansionmanual );
3069 pad->SetLocalSolderMaskMargin(
info.soldermaskexpansionmanual );
3079 pad->SetLayerSet( padLayers );
3085 std::unique_ptr<PCB_SHAPE> shape = std::make_unique<PCB_SHAPE>( aFootprint,
SHAPE_T::POLY );
3087 shape->SetPolyShape( polySet );
3088 shape->SetFilled(
true );
3089 shape->SetLayer( aLayer );
3098 const CFB::COMPOUND_FILE_ENTRY* aEntry )
3114 THROW_IO_ERROR( wxString::Format(
"Region stream tries to access polygon id %d "
3115 "of %d existing polygons.",
3122 if( zone ==
nullptr )
3144 for(
const std::vector<ALTIUM_VERTICE>& hole : elem.
holes )
3151 hole_linechain.
Append( hole.at( 0 ).position );
3153 fill.
AddHole( hole_linechain );
3173 const CFB::COMPOUND_FILE_ENTRY* aEntry )
3180 for(
int primitiveIndex = 0; reader.
GetRemainingBytes() >= 4; primitiveIndex++ )
3183 AARC6 elem( reader );
3234 THROW_IO_ERROR( wxString::Format(
"Tracks stream tries to access polygon id %u "
3235 "of %zu existing polygons.",
3241 if( zone ==
nullptr )
3289 for(
const auto& layerExpansionMask :
3292 int width = aElem.
width + ( layerExpansionMask.second * 2 );
3296 std::unique_ptr<PCB_SHAPE> arc = std::make_unique<PCB_SHAPE>(
m_board );
3300 arc->SetLayer( layerExpansionMask.first );
3309 const int aPrimitiveIndex,
const bool aIsBoardImport )
3313 wxFAIL_MSG( wxString::Format(
"Altium: Unexpected footprint Arc with polygon id %d",
3346 for(
const auto& layerExpansionMask :
3349 int width = aElem.
width + ( layerExpansionMask.second * 2 );
3353 std::unique_ptr<PCB_SHAPE> arc = std::make_unique<PCB_SHAPE>( aFootprint );
3357 arc->SetLayer( layerExpansionMask.first );
3389 std::unique_ptr<PCB_ARC> arc = std::make_unique<PCB_ARC>(
m_board, &shapeArc );
3391 arc->SetWidth( aElem.
width );
3392 arc->SetLayer( aLayer );
3395 PCB_ARC* added = arc.release();
3404 std::unique_ptr<PCB_SHAPE> arc = std::make_unique<PCB_SHAPE>(
m_board);
3408 arc->SetLayer( aLayer );
3418 std::unique_ptr<PCB_SHAPE> arc = std::make_unique<PCB_SHAPE>( aFootprint );
3422 arc->SetLayer( aLayer );
3429 const CFB::COMPOUND_FILE_ENTRY* aEntry )
3439 APAD6 elem( reader );
3468 std::unique_ptr<FOOTPRINT> footprint = std::make_unique<FOOTPRINT>(
m_board );
3469 footprint->SetPosition( aElem.
position );
3480 std::unique_ptr<PAD>
pad = std::make_unique<PAD>( aFootprint );
3482 pad->SetNumber(
"" );
3493 pad->SetLayerSet(
LSET().AllCuMask() );
3512 cuLayers &=
m_board->GetEnabledLayers();
3518 if( altiumIdx < 32 )
3528 pad->Padstack().FrontOuterLayers().has_solder_mask =
true;
3532 pad->Padstack().FrontOuterLayers().has_solder_mask =
false;
3538 pad->Padstack().BackOuterLayers().has_solder_mask =
true;
3542 pad->Padstack().BackOuterLayers().has_solder_mask =
false;
3547 pad->SetLocked(
true );
3577 std::unique_ptr<PAD>
pad = std::make_unique<PAD>( aFootprint );
3600 msg.Printf(
_(
"Error loading library '%s':\n"
3601 "Footprint %s pad %s is not marked as multilayer, but is a TH pad." ),
3613 msg.Printf(
_(
"Footprint %s pad %s is not marked as multilayer, but is a TH pad." ),
3633 wxFAIL_MSG( wxT(
"Round holes are handled before the switch" ) );
3642 msg.Printf(
_(
"Loading library '%s':\n"
3643 "Footprint %s pad %s has a square hole (not yet supported)." ),
3655 msg.Printf(
_(
"Footprint %s pad %s has a square hole (not yet supported)." ),
3690 msg.Printf(
_(
"Loading library '%s':\n"
3691 "Footprint %s pad %s has a hole-rotation of %d degrees. "
3692 "KiCad only supports 90 degree rotations." ),
3705 msg.Printf(
_(
"Footprint %s pad %s has a hole-rotation of %d degrees. "
3706 "KiCad only supports 90 degree rotations." ),
3725 msg.Printf(
_(
"Error loading library '%s':\n"
3726 "Footprint %s pad %s uses a hole of unknown kind %d." ),
3739 msg.Printf(
_(
"Footprint %s pad %s uses a hole of unknown kind %d." ),
3759 auto setCopperGeometry =
3804 msg.Printf(
_(
"Error loading library '%s':\n"
3805 "Footprint %s pad %s uses an unknown pad shape." ),
3817 msg.Printf(
_(
"Footprint %s pad %s uses an unknown pad shape." ),
3868 switch( aElem.
layer )
3886 pad->SetLayer( klayer );
3887 pad->SetLayerSet(
LSET( { klayer } ) );
3898 pad->SetLayerSet(
pad->GetLayerSet().reset(
F_Mask ) );
3901 pad->SetLayerSet(
pad->GetLayerSet().reset(
B_Mask ) );
3919 msg.Printf(
_(
"Non-copper pad %s found on an Altium layer (%d) with no KiCad "
3920 "equivalent. It has been moved to KiCad layer Eco1_User." ),
3928 std::unique_ptr<PCB_SHAPE>
pad = std::make_unique<PCB_SHAPE>(
m_board );
3947 msg.Printf(
_(
"Loading library '%s':\n"
3948 "Footprint %s non-copper pad %s found on an Altium layer (%d) with no "
3949 "KiCad equivalent. It has been moved to KiCad layer Eco1_User." ),
3962 msg.Printf(
_(
"Footprint %s non-copper pad %s found on an Altium layer (%d) with no "
3963 "KiCad equivalent. It has been moved to KiCad layer Eco1_User." ),
3974 std::unique_ptr<PCB_SHAPE>
pad = std::make_unique<PCB_SHAPE>( aFootprint );
3990 msg.Printf(
_(
"Non-copper pad %s is connected to a net, which is not supported." ),
4001 msg.Printf(
_(
"Non-copper pad %s has a hole, which is not supported." ), aElem.
name );
4011 msg.Printf(
_(
"Non-copper pad %s has a complex pad stack (not yet supported)." ),
4044 int offset = ( std::min( aElem.
topsize.
x, aElem.
topsize.
y ) * cornerradius ) / 200;
4049 if( cornerradius < 100 )
4051 int offsetX = aElem.
topsize.
x / 2 - offset;
4052 int offsetY = aElem.
topsize.
y / 2 - offset;
4145 aShape->
SetPolyPoints( { p11 - chamferX, p11 - chamferY, p12 + chamferY, p12 - chamferX,
4146 p22 + chamferX, p22 + chamferY, p21 - chamferY, p21 + chamferX } );
4158 msg.Printf(
_(
"Non-copper pad %s uses an unknown pad shape." ), aElem.
name );
4168 const CFB::COMPOUND_FILE_ENTRY* aEntry )
4178 AVIA6 elem( reader );
4180 std::unique_ptr<PCB_VIA>
via = std::make_unique<PCB_VIA>(
m_board );
4192 if( start_layer_outside && end_layer_outside )
4196 else if( ( !start_layer_outside ) && ( !end_layer_outside ) )
4219 msg.Printf(
_(
"Via from layer %d to %d uses a non-copper layer, which is not "
4230 via->SetLayerPair( start_klayer, end_klayer );
4255 wxCHECK2_MSG( altiumLayer < 32,
break,
4256 "Altium importer expects 32 or fewer copper layers" );
4290 const CFB::COMPOUND_FILE_ENTRY* aEntry )
4297 for(
int primitiveIndex = 0; reader.
GetRemainingBytes() >= 4; primitiveIndex++ )
4328 msg.Printf( wxT(
"ATRACK6 stream tries to access polygon id %u "
4329 "of %u existing polygons; skipping it" ),
4330 static_cast<unsigned>( aElem.
polygon ),
4331 static_cast<unsigned>(
m_polygons.size() ) );
4340 if( zone ==
nullptr )
4390 int width = aElem.
width + ( layerExpansionMask.second * 2 );
4395 seg->SetStart( aElem.
start );
4396 seg->SetEnd( aElem.
end );
4398 seg->SetLayer( layerExpansionMask.first );
4407 const int aPrimitiveIndex,
4408 const bool aIsBoardImport )
4412 wxFAIL_MSG( wxString::Format(
"Altium: Unexpected footprint Track with polygon id %u",
4448 int width = aElem.
width + ( layerExpansionMask.second * 2 );
4451 std::unique_ptr<PCB_SHAPE> seg = std::make_unique<PCB_SHAPE>( aFootprint,
SHAPE_T::SEGMENT );
4453 seg->SetStart( aElem.
start );
4454 seg->SetEnd( aElem.
end );
4456 seg->SetLayer( layerExpansionMask.first );
4468 std::unique_ptr<PCB_TRACK> track = std::make_unique<PCB_TRACK>(
m_board );
4470 track->SetStart( aElem.
start );
4471 track->SetEnd( aElem.
end );
4472 track->SetWidth( aElem.
width );
4473 track->SetLayer( aLayer );
4486 seg->SetStart( aElem.
start );
4487 seg->SetEnd( aElem.
end );
4489 seg->SetLayer( aLayer );
4499 std::unique_ptr<PCB_SHAPE> seg = std::make_unique<PCB_SHAPE>( aFootprint,
SHAPE_T::SEGMENT );
4501 seg->SetStart( aElem.
start );
4502 seg->SetEnd( aElem.
end );
4504 seg->SetLayer( aLayer );
4511 const CFB::COMPOUND_FILE_ENTRY* aEntry )
4521 THROW_IO_ERROR( wxT(
"WideStrings6 stream is not fully parsed" ) );
4525 const CFB::COMPOUND_FILE_ENTRY* aEntry )
4539 THROW_IO_ERROR( wxT(
"SmartUnions6 stream is not fully parsed" ) );
4556 const std::vector<BOARD_ITEM*>& items = itemsIt->second;
4568 std::unique_ptr<PCB_TUNING_PATTERN> pattern(
static_cast<PCB_TUNING_PATTERN*
>( generator ) );
4569 pattern->SetParent(
m_board );
4570 pattern->SetLayer( layer );
4571 pattern->SetTuningMode( mode );
4573 pattern->SetMaxAmplitude( tuning.amplitude );
4574 pattern->SetMinAmplitude( tuning.minamplitude );
4575 pattern->SetSpacing( tuning.gap );
4576 pattern->SetSingleSided( tuning.singleside );
4580 pattern->SetRounded( tuning.style != 0 );
4582 if( tuning.mitterradiusratio > 0.0 )
4584 int percent =
KiROUND( tuning.mitterradiusratio * 100.0 );
4585 pattern->SetCornerRadiusPercentage( std::clamp( percent, 0, 100 ) );
4590 bool singleNet =
true;
4594 pattern->AddItem( item );
4595 bbox.
Merge( item->GetBoundingBox() );
4600 netCode = bci->GetNetCode();
4601 else if( netCode != bci->GetNetCode() )
4608 if( netCode >= 0 && singleNet )
4609 pattern->SetNetCode( netCode );
4612 pattern->SetWidth( track->GetWidth() );
4616 pattern->SetPosition( bbox.
GetOrigin() );
4617 pattern->SetEnd( bbox.
GetEnd() );
4625 m_reporter->Report( wxString::Format(
_(
"Imported %d length-tuning pattern(s)." ),
4633 const CFB::COMPOUND_FILE_ENTRY* aEntry )
4691 std::unique_ptr<PCB_TEXTBOX> pcbTextbox = std::make_unique<PCB_TEXTBOX>(
m_board );
4692 std::unique_ptr<PCB_TEXT> pcbText = std::make_unique<PCB_TEXT>(
m_board );
4696 static const std::map<wxString, wxString> variableMap = {
4697 {
"LAYER_NAME",
"LAYER" },
4698 {
"PRINT_DATE",
"CURRENT_DATE"},
4707 item = pcbTextbox.get();
4708 text = pcbTextbox.get();
4711 text->SetText( kicadText );
4736 std::unique_ptr<PCB_TEXTBOX> fpTextbox = std::make_unique<PCB_TEXTBOX>( aFootprint );
4737 std::unique_ptr<PCB_TEXT> fpText = std::make_unique<PCB_TEXT>( aFootprint );
4752 item = &aFootprint->
Value();
4757 item = fpText.get();
4758 text = fpText.get();
4762 static const std::map<wxString, wxString> variableMap = {
4763 {
"DESIGNATOR",
"REFERENCE" },
4764 {
"COMMENT",
"VALUE" },
4765 {
"VALUE",
"ALTIUM_VALUE" },
4766 {
"LAYER_NAME",
"LAYER" },
4767 {
"PRINT_DATE",
"CURRENT_DATE"},
4772 item = fpTextbox.get();
4773 text = fpTextbox.get();
4778 text->SetText( kicadText );
4791 text->SetKeepUpright(
false );
4806 std::unique_ptr<PCB_BARCODE> pcbBarcode = std::make_unique<PCB_BARCODE>(
m_board );
4808 pcbBarcode->SetLayer( aLayer );
4809 pcbBarcode->SetPosition( aElem.
position );
4813 pcbBarcode->SetText( aElem.
text );
4823 pcbBarcode->AssembleBarcode();
4832 std::unique_ptr<PCB_BARCODE> fpBarcode = std::make_unique<PCB_BARCODE>( aFootprint );
4834 fpBarcode->SetLayer( aLayer );
4835 fpBarcode->SetPosition( aElem.
position );
4839 fpBarcode->SetText( aElem.
text );
4849 fpBarcode->AssembleBarcode();
4878 kicadMargin =
VECTOR2I( charWidth * 0.933, charHeight * 0.67 );
4880 kicadMargin =
VECTOR2I( charWidth * 0.808, charHeight * 0.844 );
4883 + kicadMargin * 2 - margin * 2 );
4885 kposition = kposition - kicadMargin + margin;
4903 switch( justification )
4927 msg.Printf(
_(
"Unknown textbox justification %d, aText %s" ), justification,
4947 int rectHeight = aElem.
height;
4965 rectWidth = -rectWidth;
4971 switch( justification )
4977 kposition.
y -= rectHeight;
4983 kposition.
y -= rectHeight / 2;
4993 kposition.
x += rectWidth / 2;
4994 kposition.
y -= rectHeight;
5000 kposition.
x += rectWidth / 2;
5001 kposition.
y -= rectHeight / 2;
5007 kposition.
x += rectWidth / 2;
5013 kposition.
x += rectWidth;
5014 kposition.
y -= rectHeight;
5020 kposition.
x += rectWidth;
5021 kposition.
y -= rectHeight / 2;
5027 kposition.
x += rectWidth;
5080 if( font->
GetName().Contains( wxS(
"Arial" ) ) )
5095 const CFB::COMPOUND_FILE_ENTRY* aEntry )
5153 const bool aIsBoardImport )
5195 fill->SetFilled(
true );
5196 fill->SetLayer( aLayer );
5199 fill->SetStart( aElem.
pos1 );
5200 fill->SetEnd( aElem.
pos2 );
5222 if( aLayer ==
F_Cu || aLayer ==
B_Cu )
5224 std::unique_ptr<PAD>
pad = std::make_unique<PAD>( aFootprint );
5227 padLayers.
set( aLayer );
5242 std::swap( width, height );
5245 pad->SetPosition( aElem.
pos1 / 2 + aElem.
pos2 / 2 );
5257 pad->SetPosition( anchorPos );
5268 aElem.
pos1.
y / 2 + aElem.
pos2.
y / 2 - anchorPos.
y );
5270 pad->AddPrimitivePoly(
F_Cu, shapePolys, 0,
true );
5274 pad->SetLayerSet( padLayers );
5280 std::unique_ptr<PCB_SHAPE> fill =
5283 fill->SetFilled(
true );
5284 fill->SetLayer( aLayer );
5287 fill->SetStart( aElem.
pos1 );
5288 fill->SetEnd( aElem.
pos2 );
5307 layerSet.
set( klayer );
5315 bool keepoutRestrictionVia = ( aKeepoutRestrictions & 0x01 ) != 0;
5316 bool keepoutRestrictionTrack = ( aKeepoutRestrictions & 0x02 ) != 0;
5317 bool keepoutRestrictionCopper = ( aKeepoutRestrictions & 0x04 ) != 0;
5318 bool keepoutRestrictionSMDPad = ( aKeepoutRestrictions & 0x08 ) != 0;
5319 bool keepoutRestrictionTHPad = ( aKeepoutRestrictions & 0x10 ) != 0;
5331 const uint8_t aKeepoutRestrictions )
5333 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>(
m_board );
5335 zone->SetIsRuleArea(
true );
5352 const uint8_t aKeepoutRestrictions )
5354 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>( aFootprint );
5356 zone->SetIsRuleArea(
true );
5380 if( elems.first == elems.second )
5383 std::vector<std::pair<PCB_LAYER_ID, int>> layerExpansionPairs;
5385 for(
auto it = elems.first; it != elems.second; ++it )
5425 return layerExpansionPairs;
std::string FormatPath(const std::vector< std::string > &aVectorPath)
Helper for debug logging (vector -> string)
const ARULE6 * selectAltiumPolygonRule(const std::vector< ARULE6 > &aRulesByPriorityAsc)
Select the highest Altium-priority rule whose scope references polygons.
bool altiumViaSideIsTented(bool aTentFlag, bool aManual, bool aFromHole, uint32_t aHoleSize, int32_t aMaskExpansion, int aLandDiameter)
Decide whether one side of an Altium via should be tented when imported into KiCad.
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)
static bool IsLayerNameAssembly(const wxString &aName)
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
static bool IsLayerNameCourtyard(const wxString &aName)
bool IsAltiumLayerCopper(ALTIUM_LAYER aLayer)
bool IsAltiumLayerAPlane(ALTIUM_LAYER aLayer)
static bool IsLayerNameTopSide(const wxString &aName)
@ EXTENDPRIMITIVEINFORMATION
std::function< void(const ALTIUM_PCB_COMPOUND_FILE &, const CFB::COMPOUND_FILE_ENTRY *)> PARSE_FUNCTION_POINTER_fp
KIID AltiumUniqueIdToKiid(const wxString &aUniqueId)
Derive a stable KIID from an Altium component unique id.
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
const ARULE6 * GetRuleForPolygon(ALTIUM_RULE_KIND aKind) const
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 HelperCreateTuningPatterns()
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 HelperFillMechanicalLayerAssignments(const std::vector< ABOARD6_LAYER_STACKUP > &aStackup)
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< int, std::vector< BOARD_ITEM * > > m_unionToBoardItems
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< ASMARTUNION6 > m_tuningUnions
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 ParseSmartUnions6Data(const ALTIUM_PCB_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry)
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)
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
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 const Vec GetEnd() const
constexpr coord_type GetY() const
constexpr size_type GetWidth() const
constexpr coord_type GetX() const
constexpr BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
constexpr size_type GetHeight() const
constexpr const Vec & GetOrigin() const
bool IsHorizontal() const
bool IsCardinal90() const
EDA_ANGLE GetArcAngle() const
void SetCenter(const VECTOR2I &aCenter)
virtual void SetFilled(bool aFlag)
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
void SetPolyPoints(const std::vector< VECTOR2I > &aPoints)
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
virtual void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true)
virtual void SetTextPos(const VECTOR2I &aPoint)
virtual int GetTextHeight() const
KIFONT::FONT * GetFont() const
void SetMirrored(bool isMirrored)
BOX2I GetTextBox(const RENDER_SETTINGS *aSettings, int aLine=-1) const
Useful in multiline texts to calculate the full text or a line area (for zones filling,...
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
virtual int GetTextWidth() const
void SetBoldFlag(bool aBold)
Set only the bold flag, without changing the font.
virtual void SetTextThickness(int aWidth)
The TextThickness is that set by the user.
int GetEffectiveTextPenWidth(int aDefaultPenWidth=0) const
The EffectiveTextPenWidth uses the text thickness if > 1 or aDefaultPenWidth.
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.
PCB_GENERATOR * CreateFromType(const wxString &aTypeStr)
static GENERATORS_MGR & Instance()
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 & AllCuMask()
return AllCuMask( MAX_CU_LAYERS );
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 SetArcAngleAndEnd(const EDA_ANGLE &aAngle, bool aCheckNegativeAngle=false)
void SetShape(SHAPE_T aShape) override
void SetPosition(const VECTOR2I &aPos) override
void SetEnd(const VECTOR2I &aEnd) override
void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
void SetStart(const VECTOR2I &aStart) override
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 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
void Fracture(bool aSimplify=true)
Convert a set of polygons with holes to a single outline with "slits"/"fractures" connecting the oute...
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
#define MAX_USER_DEFINED_LAYERS
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
double dielectriclosstangent
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< ABOARD6_LAYER_STACKUP > stackup
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
bool soldermask_expansion_from_hole
int32_t soldermask_expansion_front
bool soldermask_expansion_manual
int32_t soldermask_expansion_back
uint32_t diameter_by_layer[32]
std::vector< char > decompressedData
std::vector< std::string > header
table push_back({ "Source", "Layer", "Vertices", "Strategy", "Build(us)", "ns/query", "Mquery/s", "Inside" })
thread_pool & GetKiCadThreadPool()
Get a reference to the current thread pool.
BS::priority_thread_pool thread_pool
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