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_ERRORF( wxT(
"Component creator tries to access component id %u of %u existing components" ),
97 const std::vector<ALTIUM_VERTICE>& aVertices )
106 double startradiant =
DEG2RAD( vertex.startangle );
107 double endradiant =
DEG2RAD( vertex.endangle );
108 VECTOR2I arcStartOffset =
KiROUND( std::cos( startradiant ) * vertex.radius,
109 -std::sin( startradiant ) * vertex.radius );
111 VECTOR2I arcEndOffset =
KiROUND( std::cos( endradiant ) * vertex.radius,
112 -std::sin( endradiant ) * vertex.radius );
114 VECTOR2I arcStart = vertex.center + arcStartOffset;
115 VECTOR2I arcEnd = vertex.center + arcEndOffset;
120 if( arcStart.
Distance( vertex.position )
121 < arcEnd.
Distance( vertex.position ) )
148 aLine.
Append( vertex.position );
158 auto override =
m_layermap.find( aAltiumLayer );
162 return override->second;
177 switch( aAltiumLayer )
279 std::vector<PCB_LAYER_ID> layers;
280 layers.reserve( layerCount );
285 layers.emplace_back( layer );
302 const wxString& aLibrary,
const wxString& aFootprintName )
322 const unsigned PROGRESS_DELTA = 250;
340 const std::map<ALTIUM_PCB_DIR, std::string>& aFileMapping )
343 const std::vector<std::tuple<bool, ALTIUM_PCB_DIR, PARSE_FUNCTION_POINTER_fp>> parserOrder = {
460 for(
const std::tuple<bool, ALTIUM_PCB_DIR, PARSE_FUNCTION_POINTER_fp>& cur : parserOrder )
465 std::tie( isRequired,
directory, fp ) = cur;
470 const auto& mappedDirectory = aFileMapping.find(
directory );
472 if( mappedDirectory == aFileMapping.end() )
475 const std::vector<std::string> mappedFile{ mappedDirectory->second,
"Header" };
476 const CFB::COMPOUND_FILE_ENTRY* file = altiumPcbFile.
FindStream( mappedFile );
478 if( file ==
nullptr )
482 uint32_t numOfRecords = reader.
Read<uint32_t>();
488 m_reporter->Report( wxString::Format(
_(
"'%s' was not parsed correctly." ),
502 m_reporter->Report( wxString::Format(
_(
"'%s' was not fully parsed." ),
514 if( boardDirectory != aFileMapping.end() )
516 std::vector<std::string> mappedFile{ boardDirectory->second,
"Data" };
518 const CFB::COMPOUND_FILE_ENTRY* file = altiumPcbFile.
FindStream( mappedFile );
522 THROW_IO_ERROR(
_(
"This file does not appear to be in a valid PCB Binary Version 6.0 format. In "
523 "Altium Designer, 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'." ),
580 if( zone->GetAssignedPriority() == 1000 )
591 zone->SetAssignedPriority( priority >= 0 ? priority : 0 );
595 for( std::pair<const ALTIUM_LAYER, ZONE*>& zone :
m_outer_plane )
596 zone.second->SetAssignedPriority( 0 );
606 if( !zone->HasFilledPolysForLayer( layer ) )
609 zone->GetFilledPolysList( layer )->Fracture();
647 if( arc->
GetCenter() == dim->GetPosition() )
656 VECTOR2I radialLine = dim->GetEnd() - dim->GetStart();
661 radialLine = radialLine.
Resize( std::max(
radius, 2 ) );
662 dim->SetEnd( dim->GetStart() + (
VECTOR2I) radialLine );
663 dim->SetLeaderLength( totalLength -
radius );
673 int desired_x = ( w - bbbox.
GetWidth() ) / 2;
674 int desired_y = ( h - bbbox.
GetHeight() ) / 2;
676 VECTOR2I movementVector( desired_x - bbbox.
GetX(), desired_y - bbbox.
GetY() );
677 m_board->Move( movementVector );
688 const wxString& aFootprintName )
690 std::unique_ptr<FOOTPRINT> footprint = std::make_unique<FOOTPRINT>(
m_board );
695 const std::vector<std::string> libStreamName{
"Library",
"Data" };
696 const CFB::COMPOUND_FILE_ENTRY* libStream = altiumLibFile.
FindStream( libStreamName );
698 if( libStream ==
nullptr )
714 std::tuple<wxString, const CFB::COMPOUND_FILE_ENTRY*> ret =
717 wxString fpDirName = std::get<0>( ret );
718 const CFB::COMPOUND_FILE_ENTRY* footprintStream = std::get<1>( ret );
720 if( fpDirName.IsEmpty() )
721 THROW_IO_ERRORF(
_(
"Footprint directory not found: '%s'." ), aFootprintName );
723 const std::vector<std::string> streamName{ fpDirName.ToStdString(),
"Data" };
724 const CFB::COMPOUND_FILE_ENTRY* footprintData = altiumLibFile.
FindStream( footprintStream, {
"Data" } );
736 footprint->SetFPID( fpID );
738 const std::vector<std::string> parametersStreamName{ fpDirName.ToStdString(),
"Parameters" };
739 const CFB::COMPOUND_FILE_ENTRY* parametersData = altiumLibFile.
FindStream( footprintStream, {
"Parameters" } );
741 if( parametersData !=
nullptr )
744 std::map<wxString, wxString> parameterProperties = parametersReader.
ReadProperties();
746 footprint->SetLibDescription( description );
752 m_reporter->Report( wxString::Format(
_(
"File not found: '%s'." ),
FormatPath( parametersStreamName ) ),
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 );
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() )
877 if( parser.GetRemainingBytes() != 0 )
880 return footprint.release();
891 THROW_IO_ERRORF( wxT(
"Netcode with id %d does not exist. Only %d nets are known" ),
902 const auto rules =
m_rules.find( aKind );
907 for(
const ARULE6& rule : rules->second )
909 if( rule.
name == aName )
918 const auto rules =
m_rules.find( aKind );
923 for(
const ARULE6& rule : rules->second )
935 const auto rules =
m_rules.find( aKind );
949 const CFB::COMPOUND_FILE_ENTRY* aEntry )
967 const CFB::COMPOUND_FILE_ENTRY* aEntry )
984 THROW_IO_ERROR( wxT(
"ExtendedPrimitiveInformation stream is not fully parsed" ) );
989 const CFB::COMPOUND_FILE_ENTRY* aEntry )
1006 size_t layercount = 0;
1009 while( layerid < elem.
stackup.size() && layerid != 0 )
1011 layerid = elem.
stackup[ layerid - 1 ].nextId;
1015 size_t kicadLayercount = ( layercount % 2 == 0 ) ? layercount : layercount + 1;
1016 m_board->SetCopperLayerCount( kicadLayercount );
1025 auto it = stackup.
GetList().begin();
1034 altiumLayerId < elem.
stackup.size() && altiumLayerId != 0;
1035 altiumLayerId = elem.
stackup[altiumLayerId - 1].nextId )
1041 if( layer.
nextId == 0 && layercount != kicadLayercount )
1043 m_board->SetLayerName( ( *it )->GetBrdLayerId(), wxT(
"[unused]" ) );
1046 THROW_IO_ERROR( wxT(
"Board6 stream, unexpected item while parsing stackup" ) );
1048 ( *it )->SetThickness( 0 );
1053 THROW_IO_ERROR( wxT(
"Board6 stream, unexpected item while parsing stackup" ) );
1055 ( *it )->SetThickness( 0, 0 );
1056 ( *it )->SetThicknessLocked(
true, 0 );
1064 THROW_IO_ERROR( wxT(
"Board6 stream, unexpected item while parsing stackup" ) );
1078 if( klayer ==
B_Cu )
1081 THROW_IO_ERROR( wxT(
"Board6 stream, unexpected id while parsing last stackup layer" ) );
1091 THROW_IO_ERROR( wxT(
"Board6 stream, unexpected item while parsing stackup" ) );
1130 wxString nameLower = aName.Lower();
1131 return nameLower.Contains( wxT(
"courtyard" ) ) || nameLower.Contains( wxT(
"court yard" ) )
1132 || nameLower.Contains( wxT(
"crtyd" ) );
1139 wxString nameLower = aName.Lower();
1140 return nameLower.Contains( wxT(
"assembly" ) ) || nameLower.Contains( wxT(
"assy" ) );
1149 auto check = [&isTop](
bool aTopCond,
bool aBotCond )
1151 if( aTopCond && aBotCond )
1154 if( !aTopCond && !aBotCond )
1161 wxString lower = aName.Lower();
1163 if( check( lower.StartsWith(
"top" ), lower.StartsWith(
"bot" ) ) )
1166 if( check( lower.EndsWith(
"_t" ), lower.EndsWith(
"_b" ) ) )
1169 if( check( lower.EndsWith(
".t" ), lower.EndsWith(
".b" ) ) )
1172 if( check( lower.Contains(
"top" ), lower.Contains(
"bot" ) ) )
1185 if( aStackup.size() == 0 )
1188 std::vector<INPUT_LAYER_DESC> inputLayers;
1189 std::map<wxString, ALTIUM_LAYER> altiumLayerNameMap;
1196 bool frontCourtyardMapped =
false;
1197 bool backCourtyardMapped =
false;
1199 for(
size_t ii = 0; ii < aStackup.size(); ii++ )
1201 curLayer = aStackup[ii];
1220 auto existingMapping =
m_layermap.find( layer_num );
1247 if( isTopSide && !frontCourtyardMapped )
1250 frontCourtyardMapped =
true;
1252 else if( !isTopSide && !backCourtyardMapped )
1255 backCourtyardMapped =
true;
1257 else if( !frontCourtyardMapped )
1260 frontCourtyardMapped =
true;
1262 else if( !backCourtyardMapped )
1265 backCourtyardMapped =
true;
1288 inputLayers.push_back( iLdesc );
1289 altiumLayerNameMap.insert( { curLayer.
name, layer_num } );
1293 if( inputLayers.size() == 0 )
1299 for( std::pair<wxString, PCB_LAYER_ID> layerPair : reMappedLayers )
1307 m_reporter->Report( wxString::Format(
_(
"Layer '%s' could not be mapped and "
1308 "will be skipped." ),
1316 ALTIUM_LAYER altiumID = altiumLayerNameMap.at( layerPair.first );
1317 m_layermap.insert_or_assign( altiumID, layerPair.second );
1318 enabledLayers |=
LSET( { layerPair.second } );
1323 for(
const auto& [
name, altLayer] : altiumLayerNameMap )
1325 if( reMappedLayers.find(
name ) == reMappedLayers.end()
1332 m_board->SetEnabledLayers( enabledLayers );
1333 m_board->SetVisibleLayers( enabledLayers );
1346 if( !layer.mechenabled )
1354 switch( layer.mechkind )
1415 shape->SetStroke( stroke );
1427 shape->SetStroke( stroke );
1429 shape->SetStart( seg.
A );
1430 shape->SetEnd( seg.
B );
1439 const CFB::COMPOUND_FILE_ENTRY* aEntry )
1453 std::shared_ptr<NETCLASS> nc = std::make_shared<NETCLASS>( elem.
name );
1455 for(
const wxString&
name : elem.
names )
1457 m_board->GetDesignSettings().m_NetSettings->SetNetclassPatternAssignment(
1458 name, nc->GetName() );
1461 if(
m_board->GetDesignSettings().m_NetSettings->HasNetclass( nc->GetName() ) )
1468 msg.Printf(
_(
"More than one Altium netclass with name '%s' found. "
1469 "Only the first one will be imported." ), elem.
name );
1475 m_board->GetDesignSettings().m_NetSettings->SetNetclass( nc->GetName(), nc );
1485 std::shared_ptr<NET_SETTINGS> netSettings =
m_board->GetDesignSettings().m_NetSettings;
1489 if( net->GetNetCode() > 0 )
1491 std::shared_ptr<NETCLASS> netclass = netSettings->GetEffectiveNetClass( net->GetNetname() );
1494 net->SetNetClass( netclass );
1498 m_board->m_LegacyNetclassesLoaded =
true;
1503 const CFB::COMPOUND_FILE_ENTRY* aEntry )
1515 std::unique_ptr<FOOTPRINT> footprint = std::make_unique<FOOTPRINT>(
m_board );
1526 wxString fpName = elem.
pattern;
1528 if( fpName.Contains( wxT(
"\\" ) ) || fpName.Contains( wxT(
"/" ) ) )
1530 wxFileName fpPath( fpName, wxPATH_WIN );
1531 fpName = fpPath.GetFullName();
1536 footprint->SetFPID( fpID );
1538 footprint->SetPosition( elem.
position );
1539 footprint->SetOrientationDegrees( elem.
rotation );
1545 if( reference.find_first_not_of(
"0123456789" ) == wxString::npos )
1546 reference.Prepend( wxT(
"UNK" ) );
1548 footprint->SetReference( reference );
1553 path.push_back( pathid );
1554 path.push_back(
id );
1556 footprint->SetPath(
path );
1560 footprint->SetLocked( elem.
locked );
1561 footprint->Reference().SetVisible( elem.
nameon );
1562 footprint->Value().SetVisible( elem.
commenton );
1570 THROW_IO_ERROR( wxT(
"Components6 stream is not fully parsed" ) );
1577 while( Angle < aMin )
1580 while( Angle >= aMax )
1603 m_reporter->Report( wxString::Format( wxT(
"Model %s not found for footprint %s" ),
1614 if( file->
name.IsEmpty() )
1618 std::vector<char> decompressedData;
1619 wxMemoryInputStream compressedStream(
model->second.data(),
model->second.size() );
1620 wxZlibInputStream zlibStream( compressedStream );
1624 decompressedData.resize(
model->second.size() * 6 );
1627 while( !zlibStream.Eof() )
1629 zlibStream.Read( decompressedData.data() + offset, decompressedData.size() - offset );
1630 size_t bytesRead = zlibStream.LastRead();
1635 offset += bytesRead;
1637 if( offset >= decompressedData.size() )
1638 decompressedData.resize( 2 * decompressedData.size() );
1641 decompressedData.resize( offset );
1662 orientation = -orientation;
1669 modelRotation.
x += 180;
1670 modelRotation.
z = -modelRotation.
z;
1684 aFootprint->
Models().push_back( modelSettings );
1689 const CFB::COMPOUND_FILE_ENTRY* aEntry )
1695 BS::multi_future<void> embeddedFutures;
1706 if( skipComponentBodies )
1714 THROW_IO_ERRORF( wxT(
"ComponentsBodies6 stream tries to access component id %d of %zu existing "
1730 msg.Printf( wxT(
"ComponentsBodies6 stream tries to access model id %s which does "
1731 "not exist" ), elem.
modelId );
1744 wxMemoryInputStream compressedStream( modelData.
m_data.data(), modelData.
m_data.size() );
1745 wxZlibInputStream zlibStream( compressedStream );
1746 wxMemoryOutputStream decompressedStream;
1748 zlibStream.Read( decompressedStream );
1754 embeddedFutures.push_back(
tp.submit_task(
1757 EMBEDDED_FILES::CompressAndEncode( *file );
1776 orientation = -orientation;
1799 footprint->
Models().push_back( modelSettings );
1802 embeddedFutures.wait();
1805 THROW_IO_ERROR( wxT(
"ComponentsBodies6 stream is not fully parsed" ) );
1812 THROW_IO_ERROR( wxT(
"Incorrect number of reference points for linear dimension object" ) );
1821 _(
"Dimension found on an Altium layer (%d) with no KiCad equivalent. "
1822 "It has been moved to KiCad layer Eco1_User." ), aElem.
layer ),
1835 dimension->SetLayer( klayer );
1836 dimension->SetStart( referencePoint0 );
1838 if( referencePoint0 != aElem.
xy1 )
1850 VECTOR2I referenceDiff = referencePoint1 - referencePoint0;
1852 SEG segm1( referencePoint0, referencePoint0 + directionNormalVector );
1853 SEG segm2( referencePoint1, referencePoint1 + direction );
1857 THROW_IO_ERROR( wxT(
"Invalid dimension. This should never happen." ) );
1859 dimension->SetEnd( *intersection );
1863 if( direction.
Cross( referenceDiff ) > 0 )
1866 dimension->SetHeight( height );
1870 dimension->SetEnd( referencePoint1 );
1873 dimension->SetLineThickness( aElem.
linewidth );
1879 int dist = ( dimension->GetEnd() - dimension->GetStart() ).EuclideanNorm();
1881 if( dist < 3 * dimension->GetArrowLength() )
1885 wxRegEx units( wxS(
"(mm)|(in)|(mils)|(thou)|(')|(\")" ), wxRE_ADVANCED );
1897 dimension->Text().SetBold( aElem.
textbold );
1900 dimension->SetTextThickness( dimension->GetTextThickness() *
BOLD_FACTOR );
1919 THROW_IO_ERROR( wxT(
"Not enough reference points for radial dimension object" ) );
1928 _(
"Dimension found on an Altium layer (%d) with no KiCad equivalent. "
1929 "It has been moved to KiCad layer Eco1_User." ),
1938 std::unique_ptr<PCB_DIM_RADIAL> dimension = std::make_unique<PCB_DIM_RADIAL>(
m_board );
1941 dimension->SetLayer( klayer );
1942 dimension->SetStart( referencePoint0 );
1943 dimension->SetEnd( aElem.
xy1 );
1944 dimension->SetLineThickness( aElem.
linewidth );
1945 dimension->SetKeepTextAligned(
false );
1966 m_reporter->Report( wxT(
"No text position present for leader dimension object" ),
1973 dimension->SetTextPos( aElem.
textPoint.at( 0 ) );
1979 dimension->SetBold( aElem.
textbold );
1982 dimension->SetTextThickness( dimension->GetTextThickness() *
BOLD_FACTOR );
1990 int yAdjust = dimension->GetTextBox(
nullptr ).GetCenter().y - dimension->GetTextPos().y;
1991 dimension->SetTextPos( dimension->GetTextPos() +
VECTOR2I( 0, yAdjust + aElem.
textgap ) );
2008 msg.Printf(
_(
"Dimension found on an Altium layer (%d) with no KiCad equivalent. "
2009 "It has been moved to KiCad layer Eco1_User." ), aElem.
layer );
2026 shape->SetLayer( klayer );
2028 shape->SetStart( last );
2040 if( dirVec.
x != 0 || dirVec.
y != 0 )
2049 shape1->SetLayer( klayer );
2051 shape1->SetStart( referencePoint0 );
2052 shape1->SetEnd( referencePoint0 + arrVec );
2062 shape2->SetLayer( klayer );
2064 shape2->SetStart( referencePoint0 );
2065 shape2->SetEnd( referencePoint0 + arrVec );
2077 m_reporter->Report( wxT(
"No text position present for leader dimension object" ),
2084 std::unique_ptr<PCB_TEXT>
text = std::make_unique<PCB_TEXT>(
m_board );
2088 text->SetLayer( klayer );
2107 msg.Printf(
_(
"Dimension found on an Altium layer (%d) with no KiCad equivalent. "
2108 "It has been moved to KiCad layer Eco1_User." ), aElem.
layer );
2119 shape->SetLayer( klayer );
2138 msg.Printf(
_(
"Dimension found on an Altium layer (%d) with no KiCad equivalent. "
2139 "It has been moved to KiCad layer Eco1_User." ), aElem.
layer );
2149 std::unique_ptr<PCB_DIM_CENTER> dimension = std::make_unique<PCB_DIM_CENTER>(
m_board );
2151 dimension->SetLayer( klayer );
2152 dimension->SetLineThickness( aElem.
linewidth );
2153 dimension->SetStart( aElem.
xy1 );
2154 dimension->SetEnd( aElem.
xy1 + vec );
2161 const CFB::COMPOUND_FILE_ENTRY* aEntry )
2181 m_reporter->Report( wxString::Format(
_(
"Ignored Angular dimension (not yet supported)." ) ),
2194 m_reporter->Report( wxString::Format(
_(
"Ignored Datum dimension (not yet supported)." ) ),
2202 m_reporter->Report( wxString::Format(
_(
"Ignored Baseline dimension (not yet supported)." ) ),
2212 m_reporter->Report( wxString::Format(
_(
"Ignored Linear dimension (not yet supported)." ) ),
2219 m_reporter->Report( wxString::Format(
_(
"Ignored Radial dimension (not yet supported)." ) ),
2227 msg.Printf(
_(
"Ignored dimension of kind %d (not yet supported)." ), elem.
kind );
2235 THROW_IO_ERROR( wxT(
"Dimensions6 stream is not fully parsed" ) );
2240 const CFB::COMPOUND_FILE_ENTRY* aEntry,
2241 const std::vector<std::string>& aRootDir )
2252 wxString invalidChars = wxFileName::GetForbiddenChars();
2259 std::vector<std::string> stepPath = aRootDir;
2260 stepPath.emplace_back( std::to_string( idx ) );
2262 bool validName = !elem.
name.IsEmpty() && elem.
name.IsAscii()
2263 && wxString::npos == elem.
name.find_first_of( invalidChars );
2264 wxString storageName = validName ? elem.
name : wxString::Format( wxT(
"model_%d" ), idx );
2268 const CFB::COMPOUND_FILE_ENTRY* stepEntry = aAltiumPcbFile.
FindStream( stepPath );
2270 if( stepEntry ==
nullptr )
2275 msg.Printf(
_(
"File not found: '%s'. 3D-model not imported." ),
FormatPath( stepPath ) );
2282 size_t stepSize =
static_cast<size_t>( stepEntry->size );
2283 std::vector<char> stepContent( stepSize );
2291 std::move( stepContent ) ) ) );
2295 std::map<wxString, std::vector<wxString>> nameIdMap;
2298 nameIdMap[data.m_modelname].push_back(
id );
2300 for(
auto& [
name, ids] : nameIdMap )
2302 for(
size_t i = 1; i < ids.size(); i++ )
2304 const wxString&
id = ids[i];
2311 wxString modelName = modelTuple->second.m_modelname;
2313 if( modelName.Contains(
"." ) )
2316 wxString baseName = modelName.BeforeLast(
'.', &ext );
2318 modelTuple->second.m_modelname = baseName +
'_' + std::to_string( i ) +
'.' + ext;
2322 modelTuple->second.m_modelname = modelName +
'_' + std::to_string( i );
2333 const CFB::COMPOUND_FILE_ENTRY* aEntry )
2345 ANET6 elem( reader );
2359 const CFB::COMPOUND_FILE_ENTRY* aEntry )
2402 msg.Printf(
_(
"Polygon outline count is %d, expected 1." ), outline.
OutlineCount() );
2410 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>(
m_board);
2416 zone->SetPosition( elem.
vertices.at( 0 ).position );
2417 zone->SetLocked( elem.
locked );
2419 zone->Outline()->AddOutline( outline.
Outline( 0 ) );
2426 int planeLayers = 0;
2427 int signalLayers = 0;
2441 if( planeLayers > 0 && planeClearanceRule )
2444 if( signalLayers > 0 && zoneClearanceRule )
2452 if( polygonConnectRule !=
nullptr )
2471 zone->SetThermalReliefSpokeWidth(
2482 zone->SetAssignedPriority( 1 );
2487 || zone->GetBoundingBox().Contains( outer_plane->second->GetBoundingBox() ) )
2502 const BOX2I& bbox = zone->GetBoundingBox();
2511 zone->SetHatchOrientation(
ANGLE_45 );
2526 const CFB::COMPOUND_FILE_ENTRY* aEntry )
2545 std::sort( val.second.begin(), val.second.end(),
2548 return lhs.priority < rhs.priority;
2561 if( trackWidthRule )
2563 m_board->GetDesignSettings().m_TrackMinWidth = trackWidthRule->
minLimit;
2567 if( routingViasRule )
2569 m_board->GetDesignSettings().m_ViasMinSize = routingViasRule->
minWidth;
2578 if( holeToHoleRule )
2584 if( soldermaskRule )
2595 const CFB::COMPOUND_FILE_ENTRY* aEntry )
2611 THROW_IO_ERROR( wxT(
"BoardRegions stream is not fully parsed" ) );
2615 const CFB::COMPOUND_FILE_ENTRY* aEntry )
2623 for(
int primitiveIndex = 0; reader.
GetRemainingBytes() >= 4; primitiveIndex++ )
2642 THROW_IO_ERROR( wxT(
"ShapeBasedRegions6 stream is not fully parsed" ) );
2666 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>(
m_board );
2668 zone->SetIsRuleArea(
true );
2676 zone->SetDoNotAllowZoneFills(
true );
2677 zone->SetDoNotAllowVias(
false );
2678 zone->SetDoNotAllowTracks(
false );
2679 zone->SetDoNotAllowPads(
false );
2680 zone->SetDoNotAllowFootprints(
false );
2683 zone->SetPosition( aElem.
outline.at( 0 ).position );
2684 zone->Outline()->AddOutline( linechain );
2704 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>(
m_board );
2706 zone->SetPosition( aElem.
outline.at( 0 ).position );
2707 zone->Outline()->AddOutline( linechain );
2715 fill.
Append( linechain );
2719 zone->SetFilledPolysList( klayer, fill );
2721 zone->SetIsFilled(
true );
2722 zone->SetNeedRefill(
false );
2735 msg.Printf(
_(
"Dashed outline found on an Altium layer (%d) with no KiCad equivalent. "
2736 "It has been moved to KiCad layer Eco1_User." ), aElem.
layer );
2757 shape->SetPolyShape( linechain );
2758 shape->SetFilled(
false );
2759 shape->SetLayer( klayer );
2777 msg.Printf(
_(
"Ignored polygon shape of kind %d (not yet supported)." ), aElem.
kind );
2786 const int aPrimitiveIndex )
2802 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>( aFootprint );
2804 zone->SetIsRuleArea(
true );
2812 zone->SetDoNotAllowZoneFills(
true );
2813 zone->SetDoNotAllowVias(
false );
2814 zone->SetDoNotAllowTracks(
false );
2815 zone->SetDoNotAllowPads(
false );
2816 zone->SetDoNotAllowFootprints(
false );
2819 zone->SetPosition( aElem.
outline.at( 0 ).position );
2820 zone->Outline()->AddOutline( linechain );
2856 msg.Printf(
_(
"Loading library '%s':\n"
2857 "Footprint %s contains a dashed outline on Altium layer (%d) with "
2858 "no KiCad equivalent. It has been moved to KiCad layer Eco1_User." ),
2870 msg.Printf(
_(
"Footprint %s contains a dashed outline on Altium layer (%d) with "
2871 "no KiCad equivalent. It has been moved to KiCad layer Eco1_User." ),
2893 std::unique_ptr<PCB_SHAPE> shape = std::make_unique<PCB_SHAPE>( aFootprint,
SHAPE_T::POLY );
2895 shape->SetPolyShape( linechain );
2896 shape->SetFilled(
false );
2897 shape->SetLayer( klayer );
2913 msg.Printf(
_(
"Error loading library '%s':\n"
2914 "Footprint %s contains polygon shape of kind %d (not yet supported)." ),
2926 msg.Printf(
_(
"Footprint %s contains polygon shape of kind %d (not yet supported)." ),
2937 const int aPrimitiveIndex )
2954 for(
const std::vector<ALTIUM_VERTICE>& hole : aElem.
holes )
2962 polySet.
AddHole( hole_linechain );
2967 shape->SetPolyShape( polySet );
2968 shape->SetFilled(
true );
2969 shape->SetLayer( aLayer );
2980 if( aLayer ==
F_Cu || aLayer ==
B_Cu )
2982 for(
const auto& layerExpansionMask :
2985 const PCB_LAYER_ID maskLayer = layerExpansionMask.first;
2993 int expansion = layerExpansionMask.second;
3000 maskShape->SetPolyShape( expandedPolySet );
3001 maskShape->SetFilled(
true );
3002 maskShape->SetLayer( maskLayer );
3014 const int aPrimitiveIndex )
3031 for(
const std::vector<ALTIUM_VERTICE>& hole : aElem.
holes )
3039 polySet.
AddHole( hole_linechain );
3042 if( aLayer ==
F_Cu || aLayer ==
B_Cu )
3045 std::unique_ptr<PAD>
pad = std::make_unique<PAD>( aFootprint );
3048 padLayers.
set( aLayer );
3059 pad->SetPosition( anchorPos );
3062 shapePolys.
Move( -anchorPos );
3066 auto it = map.find( aPrimitiveIndex );
3068 if( it != map.end() )
3074 pad->SetLocalSolderPasteMargin(
info.pastemaskexpansionmanual );
3079 pad->SetLocalSolderMaskMargin(
info.soldermaskexpansionmanual );
3089 pad->SetLayerSet( padLayers );
3095 std::unique_ptr<PCB_SHAPE> shape = std::make_unique<PCB_SHAPE>( aFootprint,
SHAPE_T::POLY );
3097 shape->SetPolyShape( polySet );
3098 shape->SetFilled(
true );
3099 shape->SetLayer( aLayer );
3108 const CFB::COMPOUND_FILE_ENTRY* aEntry )
3124 THROW_IO_ERRORF( wxT(
"Region stream tries to access polygon id %d of %d existing polygons." ),
3130 if( zone ==
nullptr )
3149 for(
const std::vector<ALTIUM_VERTICE>& hole : elem.
holes )
3156 hole_linechain.
Append( hole.at( 0 ).position );
3158 fill.
AddHole( hole_linechain );
3178 const CFB::COMPOUND_FILE_ENTRY* aEntry )
3185 for(
int primitiveIndex = 0; reader.
GetRemainingBytes() >= 4; primitiveIndex++ )
3188 AARC6 elem( reader );
3239 THROW_IO_ERRORF( wxT(
"Tracks stream tries to access polygon id %u of %zu existing polygons." ),
3245 if( zone ==
nullptr )
3293 for(
const auto& layerExpansionMask :
3296 int width = aElem.
width + ( layerExpansionMask.second * 2 );
3300 std::unique_ptr<PCB_SHAPE> arc = std::make_unique<PCB_SHAPE>(
m_board );
3304 arc->SetLayer( layerExpansionMask.first );
3313 const int aPrimitiveIndex,
const bool aIsBoardImport )
3317 wxFAIL_MSG( wxString::Format(
"Altium: Unexpected footprint Arc with polygon id %d",
3350 for(
const auto& layerExpansionMask :
3353 int width = aElem.
width + ( layerExpansionMask.second * 2 );
3357 std::unique_ptr<PCB_SHAPE> arc = std::make_unique<PCB_SHAPE>( aFootprint );
3361 arc->SetLayer( layerExpansionMask.first );
3393 std::unique_ptr<PCB_ARC> arc = std::make_unique<PCB_ARC>(
m_board, &shapeArc );
3395 arc->SetWidth( aElem.
width );
3396 arc->SetLayer( aLayer );
3399 PCB_ARC* added = arc.release();
3408 std::unique_ptr<PCB_SHAPE> arc = std::make_unique<PCB_SHAPE>(
m_board);
3412 arc->SetLayer( aLayer );
3422 std::unique_ptr<PCB_SHAPE> arc = std::make_unique<PCB_SHAPE>( aFootprint );
3426 arc->SetLayer( aLayer );
3433 const CFB::COMPOUND_FILE_ENTRY* aEntry )
3443 APAD6 elem( reader );
3472 std::unique_ptr<FOOTPRINT> footprint = std::make_unique<FOOTPRINT>(
m_board );
3473 footprint->SetPosition( aElem.
position );
3484 std::unique_ptr<PAD>
pad = std::make_unique<PAD>( aFootprint );
3486 pad->SetNumber(
"" );
3497 pad->SetLayerSet(
LSET().AllCuMask() );
3516 cuLayers &=
m_board->GetEnabledLayers();
3522 if( altiumIdx < 32 )
3532 pad->Padstack().FrontOuterLayers().has_solder_mask =
true;
3536 pad->Padstack().FrontOuterLayers().has_solder_mask =
false;
3542 pad->Padstack().BackOuterLayers().has_solder_mask =
true;
3546 pad->Padstack().BackOuterLayers().has_solder_mask =
false;
3551 pad->SetLocked(
true );
3581 std::unique_ptr<PAD>
pad = std::make_unique<PAD>( aFootprint );
3604 msg.Printf(
_(
"Error loading library '%s':\n"
3605 "Footprint %s pad %s is not marked as multilayer, but is a TH pad." ),
3617 msg.Printf(
_(
"Footprint %s pad %s is not marked as multilayer, but is a TH pad." ),
3637 wxFAIL_MSG( wxT(
"Round holes are handled before the switch" ) );
3646 msg.Printf(
_(
"Loading library '%s':\n"
3647 "Footprint %s pad %s has a square hole (not yet supported)." ),
3659 msg.Printf(
_(
"Footprint %s pad %s has a square hole (not yet supported)." ),
3694 msg.Printf(
_(
"Loading library '%s':\n"
3695 "Footprint %s pad %s has a hole-rotation of %d degrees. "
3696 "KiCad only supports 90 degree rotations." ),
3709 msg.Printf(
_(
"Footprint %s pad %s has a hole-rotation of %d degrees. "
3710 "KiCad only supports 90 degree rotations." ),
3729 msg.Printf(
_(
"Error loading library '%s':\n"
3730 "Footprint %s pad %s uses a hole of unknown kind %d." ),
3743 msg.Printf(
_(
"Footprint %s pad %s uses a hole of unknown kind %d." ),
3763 auto setCopperGeometry =
3808 msg.Printf(
_(
"Error loading library '%s':\n"
3809 "Footprint %s pad %s uses an unknown pad shape." ),
3821 msg.Printf(
_(
"Footprint %s pad %s uses an unknown pad shape." ),
3872 switch( aElem.
layer )
3890 pad->SetLayer( klayer );
3891 pad->SetLayerSet(
LSET( { klayer } ) );
3902 pad->SetLayerSet(
pad->GetLayerSet().reset(
F_Mask ) );
3905 pad->SetLayerSet(
pad->GetLayerSet().reset(
B_Mask ) );
3923 msg.Printf(
_(
"Non-copper pad %s found on an Altium layer (%d) with no KiCad "
3924 "equivalent. It has been moved to KiCad layer Eco1_User." ),
3932 std::unique_ptr<PCB_SHAPE>
pad = std::make_unique<PCB_SHAPE>(
m_board );
3951 msg.Printf(
_(
"Loading library '%s':\n"
3952 "Footprint %s non-copper pad %s found on an Altium layer (%d) with no "
3953 "KiCad equivalent. It has been moved to KiCad layer Eco1_User." ),
3966 msg.Printf(
_(
"Footprint %s non-copper pad %s found on an Altium layer (%d) with no "
3967 "KiCad equivalent. It has been moved to KiCad layer Eco1_User." ),
3978 std::unique_ptr<PCB_SHAPE>
pad = std::make_unique<PCB_SHAPE>( aFootprint );
3994 msg.Printf(
_(
"Non-copper pad %s is connected to a net, which is not supported." ),
4005 msg.Printf(
_(
"Non-copper pad %s has a hole, which is not supported." ), aElem.
name );
4015 msg.Printf(
_(
"Non-copper pad %s has a complex pad stack (not yet supported)." ),
4048 int offset = ( std::min( aElem.
topsize.
x, aElem.
topsize.
y ) * cornerradius ) / 200;
4053 if( cornerradius < 100 )
4055 int offsetX = aElem.
topsize.
x / 2 - offset;
4056 int offsetY = aElem.
topsize.
y / 2 - offset;
4149 aShape->
SetPolyPoints( { p11 - chamferX, p11 - chamferY, p12 + chamferY, p12 - chamferX,
4150 p22 + chamferX, p22 + chamferY, p21 - chamferY, p21 + chamferX } );
4162 msg.Printf(
_(
"Non-copper pad %s uses an unknown pad shape." ), aElem.
name );
4172 const CFB::COMPOUND_FILE_ENTRY* aEntry )
4182 AVIA6 elem( reader );
4184 std::unique_ptr<PCB_VIA>
via = std::make_unique<PCB_VIA>(
m_board );
4196 if( start_layer_outside && end_layer_outside )
4200 else if( ( !start_layer_outside ) && ( !end_layer_outside ) )
4223 msg.Printf(
_(
"Via from layer %d to %d uses a non-copper layer, which is not "
4234 via->SetLayerPair( start_klayer, end_klayer );
4259 wxCHECK2_MSG( altiumLayer < 32,
break,
4260 "Altium importer expects 32 or fewer copper layers" );
4294 const CFB::COMPOUND_FILE_ENTRY* aEntry )
4301 for(
int primitiveIndex = 0; reader.
GetRemainingBytes() >= 4; primitiveIndex++ )
4332 msg.Printf( wxT(
"ATRACK6 stream tries to access polygon id %u "
4333 "of %u existing polygons; skipping it" ),
4334 static_cast<unsigned>( aElem.
polygon ),
4335 static_cast<unsigned>(
m_polygons.size() ) );
4344 if( zone ==
nullptr )
4394 int width = aElem.
width + ( layerExpansionMask.second * 2 );
4399 seg->SetStart( aElem.
start );
4400 seg->SetEnd( aElem.
end );
4402 seg->SetLayer( layerExpansionMask.first );
4411 const int aPrimitiveIndex,
4412 const bool aIsBoardImport )
4416 wxFAIL_MSG( wxString::Format(
"Altium: Unexpected footprint Track with polygon id %u",
4452 int width = aElem.
width + ( layerExpansionMask.second * 2 );
4455 std::unique_ptr<PCB_SHAPE> seg = std::make_unique<PCB_SHAPE>( aFootprint,
SHAPE_T::SEGMENT );
4457 seg->SetStart( aElem.
start );
4458 seg->SetEnd( aElem.
end );
4460 seg->SetLayer( layerExpansionMask.first );
4472 std::unique_ptr<PCB_TRACK> track = std::make_unique<PCB_TRACK>(
m_board );
4474 track->SetStart( aElem.
start );
4475 track->SetEnd( aElem.
end );
4476 track->SetWidth( aElem.
width );
4477 track->SetLayer( aLayer );
4490 seg->SetStart( aElem.
start );
4491 seg->SetEnd( aElem.
end );
4493 seg->SetLayer( aLayer );
4503 std::unique_ptr<PCB_SHAPE> seg = std::make_unique<PCB_SHAPE>( aFootprint,
SHAPE_T::SEGMENT );
4505 seg->SetStart( aElem.
start );
4506 seg->SetEnd( aElem.
end );
4508 seg->SetLayer( aLayer );
4515 const CFB::COMPOUND_FILE_ENTRY* aEntry )
4525 THROW_IO_ERROR( wxT(
"WideStrings6 stream is not fully parsed" ) );
4529 const CFB::COMPOUND_FILE_ENTRY* aEntry )
4543 THROW_IO_ERROR( wxT(
"SmartUnions6 stream is not fully parsed" ) );
4560 const std::vector<BOARD_ITEM*>& items = itemsIt->second;
4572 std::unique_ptr<PCB_TUNING_PATTERN> pattern(
static_cast<PCB_TUNING_PATTERN*
>( generator ) );
4573 pattern->SetParent(
m_board );
4574 pattern->SetLayer( layer );
4575 pattern->SetTuningMode( mode );
4577 pattern->SetMaxAmplitude( tuning.amplitude );
4578 pattern->SetMinAmplitude( tuning.minamplitude );
4579 pattern->SetSpacing( tuning.gap );
4580 pattern->SetSingleSided( tuning.singleside );
4584 pattern->SetRounded( tuning.style != 0 );
4586 if( tuning.mitterradiusratio > 0.0 )
4588 int percent =
KiROUND( tuning.mitterradiusratio * 100.0 );
4589 pattern->SetCornerRadiusPercentage( std::clamp( percent, 0, 100 ) );
4594 bool singleNet =
true;
4598 pattern->AddItem( item );
4599 bbox.
Merge( item->GetBoundingBox() );
4604 netCode = bci->GetNetCode();
4605 else if( netCode != bci->GetNetCode() )
4612 if( netCode >= 0 && singleNet )
4613 pattern->SetNetCode( netCode );
4616 pattern->SetWidth( track->GetWidth() );
4620 pattern->SetPosition( bbox.
GetOrigin() );
4621 pattern->SetEnd( bbox.
GetEnd() );
4629 m_reporter->Report( wxString::Format(
_(
"Imported %d length-tuning pattern(s)." ),
4637 const CFB::COMPOUND_FILE_ENTRY* aEntry )
4695 std::unique_ptr<PCB_TEXTBOX> pcbTextbox = std::make_unique<PCB_TEXTBOX>(
m_board );
4696 std::unique_ptr<PCB_TEXT> pcbText = std::make_unique<PCB_TEXT>(
m_board );
4700 static const std::map<wxString, wxString> variableMap = {
4701 {
"LAYER_NAME",
"LAYER" },
4702 {
"PRINT_DATE",
"CURRENT_DATE"},
4711 item = pcbTextbox.get();
4712 text = pcbTextbox.get();
4715 text->SetText( kicadText );
4740 std::unique_ptr<PCB_TEXTBOX> fpTextbox = std::make_unique<PCB_TEXTBOX>( aFootprint );
4741 std::unique_ptr<PCB_TEXT> fpText = std::make_unique<PCB_TEXT>( aFootprint );
4756 item = &aFootprint->
Value();
4761 item = fpText.get();
4762 text = fpText.get();
4766 static const std::map<wxString, wxString> variableMap = {
4767 {
"DESIGNATOR",
"REFERENCE" },
4768 {
"COMMENT",
"VALUE" },
4769 {
"VALUE",
"ALTIUM_VALUE" },
4770 {
"LAYER_NAME",
"LAYER" },
4771 {
"PRINT_DATE",
"CURRENT_DATE"},
4776 item = fpTextbox.get();
4777 text = fpTextbox.get();
4782 text->SetText( kicadText );
4795 text->SetKeepUpright(
false );
4810 std::unique_ptr<PCB_BARCODE> pcbBarcode = std::make_unique<PCB_BARCODE>(
m_board );
4812 pcbBarcode->SetLayer( aLayer );
4813 pcbBarcode->SetPosition( aElem.
position );
4817 pcbBarcode->SetText( aElem.
text );
4827 pcbBarcode->AssembleBarcode();
4836 std::unique_ptr<PCB_BARCODE> fpBarcode = std::make_unique<PCB_BARCODE>( aFootprint );
4838 fpBarcode->SetLayer( aLayer );
4839 fpBarcode->SetPosition( aElem.
position );
4843 fpBarcode->SetText( aElem.
text );
4853 fpBarcode->AssembleBarcode();
4882 kicadMargin =
VECTOR2I( charWidth * 0.933, charHeight * 0.67 );
4884 kicadMargin =
VECTOR2I( charWidth * 0.808, charHeight * 0.844 );
4887 + kicadMargin * 2 - margin * 2 );
4889 kposition = kposition - kicadMargin + margin;
4907 switch( justification )
4931 msg.Printf(
_(
"Unknown textbox justification %d, aText %s" ), justification,
4951 int rectHeight = aElem.
height;
4969 rectWidth = -rectWidth;
4975 switch( justification )
4981 kposition.
y -= rectHeight;
4987 kposition.
y -= rectHeight / 2;
4997 kposition.
x += rectWidth / 2;
4998 kposition.
y -= rectHeight;
5004 kposition.
x += rectWidth / 2;
5005 kposition.
y -= rectHeight / 2;
5011 kposition.
x += rectWidth / 2;
5017 kposition.
x += rectWidth;
5018 kposition.
y -= rectHeight;
5024 kposition.
x += rectWidth;
5025 kposition.
y -= rectHeight / 2;
5031 kposition.
x += rectWidth;
5084 if( font->
GetName().Contains( wxS(
"Arial" ) ) )
5099 const CFB::COMPOUND_FILE_ENTRY* aEntry )
5157 const bool aIsBoardImport )
5199 fill->SetFilled(
true );
5200 fill->SetLayer( aLayer );
5203 fill->SetStart( aElem.
pos1 );
5204 fill->SetEnd( aElem.
pos2 );
5226 if( aLayer ==
F_Cu || aLayer ==
B_Cu )
5228 std::unique_ptr<PAD>
pad = std::make_unique<PAD>( aFootprint );
5231 padLayers.
set( aLayer );
5246 std::swap( width, height );
5249 pad->SetPosition( aElem.
pos1 / 2 + aElem.
pos2 / 2 );
5261 pad->SetPosition( anchorPos );
5272 aElem.
pos1.
y / 2 + aElem.
pos2.
y / 2 - anchorPos.
y );
5274 pad->AddPrimitivePoly(
F_Cu, shapePolys, 0,
true );
5278 pad->SetLayerSet( padLayers );
5284 std::unique_ptr<PCB_SHAPE> fill =
5287 fill->SetFilled(
true );
5288 fill->SetLayer( aLayer );
5291 fill->SetStart( aElem.
pos1 );
5292 fill->SetEnd( aElem.
pos2 );
5311 layerSet.
set( klayer );
5319 bool keepoutRestrictionVia = ( aKeepoutRestrictions & 0x01 ) != 0;
5320 bool keepoutRestrictionTrack = ( aKeepoutRestrictions & 0x02 ) != 0;
5321 bool keepoutRestrictionCopper = ( aKeepoutRestrictions & 0x04 ) != 0;
5322 bool keepoutRestrictionSMDPad = ( aKeepoutRestrictions & 0x08 ) != 0;
5323 bool keepoutRestrictionTHPad = ( aKeepoutRestrictions & 0x10 ) != 0;
5349 const uint8_t aKeepoutRestrictions )
5351 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>(
m_board );
5353 zone->SetIsRuleArea(
true );
5370 const uint8_t aKeepoutRestrictions )
5372 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>( aFootprint );
5374 zone->SetIsRuleArea(
true );
5398 if( elems.first == elems.second )
5401 std::vector<std::pair<PCB_LAYER_ID, int>> layerExpansionPairs;
5403 for(
auto it = elems.first; it != elems.second; ++it )
5443 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 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 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 ConvertShapeBasedRegions6ToBoardItemOnLayer(const AREGION6 &aElem, PCB_LAYER_ID aLayer, const int aPrimitiveIndex)
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
void HelperFootprintZoneToLibFrame(ZONE &aZone, const FOOTPRINT &aFootprint)
LAYER_MAPPING_HANDLER m_layerMappingHandler
void ConvertShapeBasedRegions6ToBoardItem(const AREGION6 &aElem, const int aPrimitiveIndex)
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.
ITERATOR IterateWithHoles(int aOutline)
int AddOutline(const SHAPE_LINE_CHAIN &aOutline)
Adds a new outline to the set and returns its index.
void SetVertex(const VERTEX_INDEX &aIndex, const VECTOR2I &aPos)
Accessor function to set the position of a specific point.
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 * Outline()
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.
@ ROUND_ALL_CORNERS
All angles are rounded.
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 THROW_IO_ERRORF(msg,...)
#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
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