47#include <compoundfilereader.h>
54#include <wx/docview.h>
56#include <wx/mstream.h>
57#include <wx/wfstream.h>
58#include <wx/zstream.h>
60#include <magic_enum.hpp>
82 THROW_IO_ERROR( wxString::Format( wxT(
"Component creator tries to access component id %u "
83 "of %u existing components" ),
92 const std::vector<ALTIUM_VERTICE>& aVertices )
101 double startradiant =
DEG2RAD( vertex.startangle );
102 double endradiant =
DEG2RAD( vertex.endangle );
104 -
KiROUND( std::sin( startradiant ) * vertex.radius ) );
107 -
KiROUND( std::sin( endradiant ) * vertex.radius ) );
109 VECTOR2I arcStart = vertex.center + arcStartOffset;
110 VECTOR2I arcEnd = vertex.center + arcEndOffset;
115 if( arcStart.
Distance( vertex.position )
116 < arcEnd.
Distance( vertex.position ) )
143 aLine.
Append( vertex.position );
153 auto override =
m_layermap.find( aAltiumLayer );
157 return override->second;
160 switch( aAltiumLayer )
164 case ALTIUM_LAYER::TOP_LAYER:
return F_Cu;
165 case ALTIUM_LAYER::MID_LAYER_1:
return In1_Cu;
166 case ALTIUM_LAYER::MID_LAYER_2:
return In2_Cu;
167 case ALTIUM_LAYER::MID_LAYER_3:
return In3_Cu;
168 case ALTIUM_LAYER::MID_LAYER_4:
return In4_Cu;
169 case ALTIUM_LAYER::MID_LAYER_5:
return In5_Cu;
170 case ALTIUM_LAYER::MID_LAYER_6:
return In6_Cu;
171 case ALTIUM_LAYER::MID_LAYER_7:
return In7_Cu;
172 case ALTIUM_LAYER::MID_LAYER_8:
return In8_Cu;
173 case ALTIUM_LAYER::MID_LAYER_9:
return In9_Cu;
174 case ALTIUM_LAYER::MID_LAYER_10:
return In10_Cu;
175 case ALTIUM_LAYER::MID_LAYER_11:
return In11_Cu;
176 case ALTIUM_LAYER::MID_LAYER_12:
return In12_Cu;
177 case ALTIUM_LAYER::MID_LAYER_13:
return In13_Cu;
178 case ALTIUM_LAYER::MID_LAYER_14:
return In14_Cu;
179 case ALTIUM_LAYER::MID_LAYER_15:
return In15_Cu;
180 case ALTIUM_LAYER::MID_LAYER_16:
return In16_Cu;
181 case ALTIUM_LAYER::MID_LAYER_17:
return In17_Cu;
182 case ALTIUM_LAYER::MID_LAYER_18:
return In18_Cu;
183 case ALTIUM_LAYER::MID_LAYER_19:
return In19_Cu;
184 case ALTIUM_LAYER::MID_LAYER_20:
return In20_Cu;
185 case ALTIUM_LAYER::MID_LAYER_21:
return In21_Cu;
186 case ALTIUM_LAYER::MID_LAYER_22:
return In22_Cu;
187 case ALTIUM_LAYER::MID_LAYER_23:
return In23_Cu;
188 case ALTIUM_LAYER::MID_LAYER_24:
return In24_Cu;
189 case ALTIUM_LAYER::MID_LAYER_25:
return In25_Cu;
190 case ALTIUM_LAYER::MID_LAYER_26:
return In26_Cu;
191 case ALTIUM_LAYER::MID_LAYER_27:
return In27_Cu;
192 case ALTIUM_LAYER::MID_LAYER_28:
return In28_Cu;
193 case ALTIUM_LAYER::MID_LAYER_29:
return In29_Cu;
194 case ALTIUM_LAYER::MID_LAYER_30:
return In30_Cu;
195 case ALTIUM_LAYER::BOTTOM_LAYER:
return B_Cu;
197 case ALTIUM_LAYER::TOP_OVERLAY:
return F_SilkS;
198 case ALTIUM_LAYER::BOTTOM_OVERLAY:
return B_SilkS;
199 case ALTIUM_LAYER::TOP_PASTE:
return F_Paste;
200 case ALTIUM_LAYER::BOTTOM_PASTE:
return B_Paste;
201 case ALTIUM_LAYER::TOP_SOLDER:
return F_Mask;
202 case ALTIUM_LAYER::BOTTOM_SOLDER:
return B_Mask;
221 case ALTIUM_LAYER::DRILL_GUIDE:
return Dwgs_User;
222 case ALTIUM_LAYER::KEEP_OUT_LAYER:
return Margin;
224 case ALTIUM_LAYER::MECHANICAL_1:
return User_1;
225 case ALTIUM_LAYER::MECHANICAL_2:
return User_2;
226 case ALTIUM_LAYER::MECHANICAL_3:
return User_3;
227 case ALTIUM_LAYER::MECHANICAL_4:
return User_4;
228 case ALTIUM_LAYER::MECHANICAL_5:
return User_5;
229 case ALTIUM_LAYER::MECHANICAL_6:
return User_6;
230 case ALTIUM_LAYER::MECHANICAL_7:
return User_7;
231 case ALTIUM_LAYER::MECHANICAL_8:
return User_8;
232 case ALTIUM_LAYER::MECHANICAL_9:
return User_9;
233 case ALTIUM_LAYER::MECHANICAL_10:
return User_10;
234 case ALTIUM_LAYER::MECHANICAL_11:
return User_11;
235 case ALTIUM_LAYER::MECHANICAL_12:
return F_Fab;
236 case ALTIUM_LAYER::MECHANICAL_13:
return B_Fab;
237 case ALTIUM_LAYER::MECHANICAL_14:
return User_12;
238 case ALTIUM_LAYER::MECHANICAL_15:
return User_13;
239 case ALTIUM_LAYER::MECHANICAL_16:
return User_14;
241 case ALTIUM_LAYER::DRILL_DRAWING:
return Dwgs_User;
259 static std::set<ALTIUM_LAYER> altiumLayersWithWarning;
261 if( aAltiumLayer == ALTIUM_LAYER::MULTI_LAYER || aAltiumLayer == ALTIUM_LAYER::KEEP_OUT_LAYER )
264 std::vector<PCB_LAYER_ID> layers;
265 layers.reserve( layerCount );
270 layers.emplace_back( layer );
281 wxString layerName = it !=
m_layerNames.end() ? it->second : wxString::Format( wxT(
"(%d)" ),
282 (
int) aAltiumLayer );
284 if(
m_reporter && altiumLayersWithWarning.insert( aAltiumLayer ).second )
287 _(
"Altium layer %s has no KiCad equivalent. It has been moved to KiCad "
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 = {
345 {
true, ALTIUM_PCB_DIR::FILE_HEADER,
350 {
true, ALTIUM_PCB_DIR::BOARD6,
355 {
false, ALTIUM_PCB_DIR::EXTENDPRIMITIVEINFORMATION,
360 {
true, ALTIUM_PCB_DIR::COMPONENTS6,
365 {
false, ALTIUM_PCB_DIR::MODELS,
368 std::vector<std::string> dir{ aFileMapping.at( ALTIUM_PCB_DIR::MODELS ) };
371 {
true, ALTIUM_PCB_DIR::COMPONENTBODIES6,
376 {
true, ALTIUM_PCB_DIR::NETS6,
381 {
true, ALTIUM_PCB_DIR::CLASSES6,
386 {
true, ALTIUM_PCB_DIR::RULES6,
391 {
true, ALTIUM_PCB_DIR::DIMENSIONS6,
396 {
true, ALTIUM_PCB_DIR::POLYGONS6,
401 {
true, ALTIUM_PCB_DIR::ARCS6,
406 {
true, ALTIUM_PCB_DIR::PADS6,
411 {
true, ALTIUM_PCB_DIR::VIAS6,
416 {
true, ALTIUM_PCB_DIR::TRACKS6,
421 {
false, ALTIUM_PCB_DIR::WIDESTRINGS6,
426 {
true, ALTIUM_PCB_DIR::TEXTS6,
431 {
true, ALTIUM_PCB_DIR::FILLS6,
436 {
false, ALTIUM_PCB_DIR::BOARDREGIONS,
441 {
true, ALTIUM_PCB_DIR::SHAPEBASEDREGIONS6,
446 {
true, ALTIUM_PCB_DIR::REGIONS6,
456 for(
const std::tuple<bool, ALTIUM_PCB_DIR, PARSE_FUNCTION_POINTER_fp>& cur : parserOrder )
461 std::tie( isRequired,
directory, fp ) = cur;
463 if(
directory == ALTIUM_PCB_DIR::FILE_HEADER )
466 const auto& mappedDirectory = aFileMapping.find(
directory );
468 if( mappedDirectory == aFileMapping.end() )
471 const std::vector<std::string> mappedFile{ mappedDirectory->second,
"Header" };
472 const CFB::COMPOUND_FILE_ENTRY* file = altiumPcbFile.
FindStream( mappedFile );
474 if( file ==
nullptr )
478 uint32_t numOfRecords = reader.
Read<uint32_t>();
508 const auto& boardDirectory = aFileMapping.find( ALTIUM_PCB_DIR::BOARD6 );
510 if( boardDirectory != aFileMapping.end() )
512 std::vector<std::string> mappedFile{ boardDirectory->second,
"Data" };
514 const CFB::COMPOUND_FILE_ENTRY* file = altiumPcbFile.
FindStream( mappedFile );
519 "This file does not appear to be in a valid PCB Binary Version 6.0 format. In "
521 "make sure to save as \"PCB Binary Files (*.PcbDoc)\"." ) );
526 for(
const std::tuple<bool, ALTIUM_PCB_DIR, PARSE_FUNCTION_POINTER_fp>& cur : parserOrder )
531 std::tie( isRequired,
directory, fp ) = cur;
533 const auto& mappedDirectory = aFileMapping.find(
directory );
535 if( mappedDirectory == aFileMapping.end() )
537 wxASSERT_MSG( !isRequired, wxString::Format( wxT(
"Altium Directory of kind %d was "
538 "expected, but no mapping is "
539 "present in the code" ),
544 std::vector<std::string> mappedFile{ mappedDirectory->second };
546 if(
directory != ALTIUM_PCB_DIR::FILE_HEADER )
547 mappedFile.emplace_back(
"Data" );
549 const CFB::COMPOUND_FILE_ENTRY* file = altiumPcbFile.
FindStream( mappedFile );
551 if( file !=
nullptr )
553 fp( altiumPcbFile, file );
555 else if( isRequired )
559 m_reporter->
Report( wxString::Format(
_(
"File not found: '%s' for directory '%s'." ),
574 if( zone->GetAssignedPriority() == 1000 )
585 zone->SetAssignedPriority( priority >= 0 ? priority : 0 );
589 for( std::pair<const ALTIUM_LAYER, ZONE*>& zone :
m_outer_plane )
590 zone.second->SetAssignedPriority( 0 );
600 if( !zone->HasFilledPolysForLayer( layer ) )
603 zone->GetFilledPolysList( layer )->Fracture();
622 if( shape->
GetShape() != SHAPE_T::ARC && shape->
GetShape() != SHAPE_T::CIRCLE )
641 if( arc->
GetCenter() == dim->GetPosition() )
650 VECTOR2I radialLine = dim->GetEnd() - dim->GetStart();
655 radialLine = radialLine.
Resize( std::max(
radius, 2 ) );
656 dim->SetEnd( dim->GetStart() + (
VECTOR2I) radialLine );
657 dim->SetLeaderLength( totalLength -
radius );
667 int desired_x = ( w - bbbox.
GetWidth() ) / 2;
668 int desired_y = ( h - bbbox.
GetHeight() ) / 2;
670 VECTOR2I movementVector( desired_x - bbbox.
GetX(), desired_y - bbbox.
GetY() );
682 const wxString& aFootprintName )
684 std::unique_ptr<FOOTPRINT> footprint = std::make_unique<FOOTPRINT>(
m_board );
702 std::tuple<wxString, const CFB::COMPOUND_FILE_ENTRY*> ret =
705 wxString fpDirName = std::get<0>( ret );
706 const CFB::COMPOUND_FILE_ENTRY* footprintStream = std::get<1>( ret );
708 if( fpDirName.IsEmpty() )
711 wxString::Format(
_(
"Footprint directory not found: '%s'." ), aFootprintName ) );
714 const std::vector<std::string> streamName{ fpDirName.ToStdString(),
"Data" };
715 const CFB::COMPOUND_FILE_ENTRY* footprintData = altiumLibFile.
FindStream( footprintStream, {
"Data" } );
717 if( footprintData ==
nullptr )
730 footprint->SetFPID( fpID );
732 const std::vector<std::string> parametersStreamName{ fpDirName.ToStdString(),
734 const CFB::COMPOUND_FILE_ENTRY* parametersData =
735 altiumLibFile.
FindStream( footprintStream, {
"Parameters" } );
737 if( parametersData !=
nullptr )
740 std::map<wxString, wxString> parameterProperties = parametersReader.
ReadProperties();
742 wxT(
"DESCRIPTION" ), wxT(
"" ) );
743 footprint->SetLibDescription( description );
754 footprint->SetLibDescription( wxT(
"" ) );
757 const std::vector<std::string> extendedPrimitiveInformationStreamName{
758 "ExtendedPrimitiveInformation",
"Data"
760 const CFB::COMPOUND_FILE_ENTRY* extendedPrimitiveInformationData =
761 altiumLibFile.
FindStream( footprintStream, extendedPrimitiveInformationStreamName );
763 if( extendedPrimitiveInformationData !=
nullptr )
766 footprint->SetReference( wxT(
"REF**" ) );
767 footprint->SetValue( aFootprintName );
768 footprint->Reference().SetVisible(
true );
769 footprint->Value().SetVisible(
true );
774 for(
PCB_FIELD* field : footprint->GetFields() )
776 field->SetTextSize( defaultTextSize );
777 field->SetTextThickness( defaultTextThickness );
786 case ALTIUM_RECORD::ARC:
792 case ALTIUM_RECORD::PAD:
798 case ALTIUM_RECORD::VIA:
804 case ALTIUM_RECORD::TRACK:
810 case ALTIUM_RECORD::TEXT:
816 case ALTIUM_RECORD::FILL:
822 case ALTIUM_RECORD::REGION:
828 case ALTIUM_RECORD::MODEL:
835 THROW_IO_ERROR( wxString::Format(
_(
"Record of unknown type: '%d'." ), recordtype ) );
841 for(
bool changes =
true; changes; )
846 [&changes](
PAD* aPad1,
PAD* aPad2 )
848 if( !( aPad1->GetNumber().IsEmpty() ^ aPad2->GetNumber().IsEmpty() ) )
851 for( PCB_LAYER_ID layer : aPad1->GetLayerSet() )
853 std::shared_ptr<SHAPE> shape1 = aPad1->GetEffectiveShape( layer );
854 std::shared_ptr<SHAPE> shape2 = aPad2->GetEffectiveShape( layer );
856 if( shape1->Collide( shape2.get() ) )
858 if( aPad1->GetNumber().IsEmpty() )
859 aPad1->SetNumber( aPad2->GetNumber() );
861 aPad2->SetNumber( aPad1->GetNumber() );
870 footprint->AutoPositionFields();
872 if( parser.HasParsingError() )
874 THROW_IO_ERROR( wxString::Format( wxT(
"%s stream was not parsed correctly" ),
878 if( parser.GetRemainingBytes() != 0 )
880 THROW_IO_ERROR( wxString::Format( wxT(
"%s stream is not fully parsed" ),
884 return footprint.release();
895 THROW_IO_ERROR( wxString::Format( wxT(
"Netcode with id %d does not exist. Only %d nets "
907 const auto rules =
m_rules.find( aKind );
912 for(
const ARULE6& rule : rules->second )
914 if( rule.
name == aName )
923 const auto rules =
m_rules.find( aKind );
928 for(
const ARULE6& rule : rules->second )
938 const CFB::COMPOUND_FILE_ENTRY* aEntry )
956 const CFB::COMPOUND_FILE_ENTRY* aEntry )
973 THROW_IO_ERROR( wxT(
"ExtendedPrimitiveInformation stream is not fully parsed" ) );
978 const CFB::COMPOUND_FILE_ENTRY* aEntry )
995 size_t layercount = 0;
996 size_t layerid =
static_cast<size_t>( ALTIUM_LAYER::TOP_LAYER );
998 while( layerid < elem.
stackup.size() && layerid != 0 )
1000 layerid = elem.
stackup[ layerid - 1 ].nextId;
1004 size_t kicadLayercount = ( layercount % 2 == 0 ) ? layercount : layercount + 1;
1014 auto it = stackup.
GetList().begin();
1022 for(
size_t altiumLayerId =
static_cast<size_t>( ALTIUM_LAYER::TOP_LAYER );
1023 altiumLayerId < elem.
stackup.size() && altiumLayerId != 0;
1024 altiumLayerId = elem.
stackup[altiumLayerId - 1].nextId )
1030 if( layer.
nextId == 0 && layercount != kicadLayercount )
1035 THROW_IO_ERROR( wxT(
"Board6 stream, unexpected item while parsing stackup" ) );
1037 ( *it )->SetThickness( 0 );
1042 THROW_IO_ERROR( wxT(
"Board6 stream, unexpected item while parsing stackup" ) );
1044 ( *it )->SetThickness( 0, 0 );
1045 ( *it )->SetThicknessLocked(
true, 0 );
1053 THROW_IO_ERROR( wxT(
"Board6 stream, unexpected item while parsing stackup" ) );
1067 if( klayer ==
B_Cu )
1070 THROW_IO_ERROR( wxT(
"Board6 stream, unexpected id while parsing last stackup layer" ) );
1080 THROW_IO_ERROR( wxT(
"Board6 stream, unexpected item while parsing stackup" ) );
1094 for(
size_t altiumLayerId =
static_cast<size_t>( ALTIUM_LAYER::TOP_OVERLAY );
1095 altiumLayerId <= static_cast<size_t>( ALTIUM_LAYER::BOTTOM_SOLDER ); altiumLayerId++ )
1106 for(
size_t altiumLayerId =
static_cast<size_t>( ALTIUM_LAYER::MECHANICAL_1 );
1107 altiumLayerId <= static_cast<size_t>( ALTIUM_LAYER::MECHANICAL_16 ); altiumLayerId++ )
1129 if( aStackup.size() == 0 )
1132 std::vector<INPUT_LAYER_DESC> inputLayers;
1133 std::map<wxString, ALTIUM_LAYER> altiumLayerNameMap;
1140 [&](
size_t ii ) ->
size_t
1145 if( layer_num < ALTIUM_LAYER::BOTTOM_LAYER )
1146 return curLayer.
nextId - 1;
1151 for(
size_t ii = 0; ii < aStackup.size(); ii =
next( ii ) )
1153 curLayer = aStackup[ii];
1157 && !( layer_num >= ALTIUM_LAYER::TOP_OVERLAY
1158 && layer_num <= ALTIUM_LAYER::BOTTOM_SOLDER )
1159 && !( layer_num >= ALTIUM_LAYER::MECHANICAL_1
1160 && layer_num <= ALTIUM_LAYER::MECHANICAL_16 ) )
1162 if( layer_num < ALTIUM_LAYER::BOTTOM_LAYER )
1176 inputLayers.push_back( iLdesc );
1177 altiumLayerNameMap.insert( { curLayer.
name, layer_num } );
1181 if( inputLayers.size() == 0 )
1188 for( std::pair<wxString, PCB_LAYER_ID> layerPair : reMappedLayers )
1190 if( layerPair.second == PCB_LAYER_ID::UNDEFINED_LAYER )
1192 wxFAIL_MSG( wxT(
"Unexpected Layer ID" ) );
1196 ALTIUM_LAYER altiumID = altiumLayerNameMap.at( layerPair.first );
1197 m_layermap.insert_or_assign( altiumID, layerPair.second );
1198 enabledLayers |=
LSET( { layerPair.second } );
1212 LINE_STYLE::SOLID );
1219 int nextShape = lineChain.
NextShape( i );
1220 bool isLastShape = nextShape < 0;
1222 std::unique_ptr<PCB_SHAPE> shape = std::make_unique<PCB_SHAPE>(
m_board, SHAPE_T::ARC );
1224 shape->SetStroke( stroke );
1228 m_board->
Add( shape.release(), ADD_MODE::APPEND );
1234 std::unique_ptr<PCB_SHAPE> shape = std::make_unique<PCB_SHAPE>(
m_board, SHAPE_T::SEGMENT );
1236 shape->SetStroke( stroke );
1238 shape->SetStart( seg.
A );
1239 shape->SetEnd( seg.
B );
1241 m_board->
Add( shape.release(), ADD_MODE::APPEND );
1248 const CFB::COMPOUND_FILE_ENTRY* aEntry )
1260 if( elem.
kind == ALTIUM_CLASS_KIND::NET_CLASS )
1262 std::shared_ptr<NETCLASS> nc = std::make_shared<NETCLASS>( elem.
name );
1264 for(
const wxString&
name : elem.
names )
1267 name, nc->GetName() );
1277 msg.Printf(
_(
"More than one Altium netclass with name '%s' found. "
1278 "Only the first one will be imported." ), elem.
name );
1297 const CFB::COMPOUND_FILE_ENTRY* aEntry )
1304 uint16_t componentId = 0;
1311 std::unique_ptr<FOOTPRINT> footprint = std::make_unique<FOOTPRINT>(
m_board );
1321 footprint->SetFPID( fpID );
1323 footprint->SetPosition( elem.
position );
1324 footprint->SetOrientationDegrees( elem.
rotation );
1330 if( reference.find_first_not_of(
"0123456789" ) == wxString::npos )
1331 reference.Prepend( wxT(
"UNK" ) );
1333 footprint->SetReference( reference );
1338 path.push_back( pathid );
1339 path.push_back(
id );
1341 footprint->SetPath(
path );
1345 footprint->SetLocked( elem.
locked );
1346 footprint->Reference().SetVisible( elem.
nameon );
1347 footprint->Value().SetVisible( elem.
commenton );
1348 footprint->SetLayer( elem.
layer == ALTIUM_LAYER::TOP_LAYER ?
F_Cu :
B_Cu );
1351 m_board->
Add( footprint.release(), ADD_MODE::APPEND );
1357 THROW_IO_ERROR( wxT(
"Components6 stream is not fully parsed" ) );
1364 while( Angle < aMin )
1367 while( Angle >= aMax )
1390 m_reporter->
Report( wxString::Format( wxT(
"Model %s not found for footprint %s" ),
1403 if( file->
name.IsEmpty() )
1404 file->
name = model->first.name;
1407 std::vector<char> decompressedData;
1408 wxMemoryInputStream compressedStream( model->second.data(), model->second.size() );
1409 wxZlibInputStream zlibStream( compressedStream );
1413 decompressedData.resize( model->second.size() * 6 );
1416 while( !zlibStream.Eof() )
1418 zlibStream.Read( decompressedData.data() + offset, decompressedData.size() - offset );
1419 size_t bytesRead = zlibStream.LastRead();
1424 offset += bytesRead;
1426 if( offset >= decompressedData.size() )
1427 decompressedData.resize( 2 * decompressedData.size() );
1430 decompressedData.resize( offset );
1451 orientation = -orientation;
1458 modelRotation.
x += 180;
1459 modelRotation.
z += 180;
1471 aFootprint->
Models().push_back( modelSettings );
1476 const CFB::COMPOUND_FILE_ENTRY* aEntry )
1493 THROW_IO_ERROR( wxString::Format( wxT(
"ComponentsBodies6 stream tries to access "
1494 "component id %d of %zu existing components" ),
1509 msg.Printf( wxT(
"ComponentsBodies6 stream tries to access model id %s which does "
1510 "not exist" ), elem.
modelId );
1523 wxMemoryInputStream compressedStream( modelData.
m_data.data(), modelData.
m_data.size() );
1524 wxZlibInputStream zlibStream( compressedStream );
1525 wxMemoryOutputStream decompressedStream;
1527 zlibStream.Read( decompressedStream );
1550 orientation = -orientation;
1571 footprint->
Models().push_back( modelSettings );
1575 THROW_IO_ERROR( wxT(
"ComponentsBodies6 stream is not fully parsed" ) );
1582 THROW_IO_ERROR( wxT(
"Incorrect number of reference points for linear dimension object" ) );
1591 _(
"Dimension found on an Altium layer (%d) with no KiCad equivalent. "
1592 "It has been moved to KiCad layer Eco1_User." ), aElem.
layer ),
1605 dimension->SetLayer( klayer );
1606 dimension->SetStart( referencePoint0 );
1608 if( referencePoint0 != aElem.
xy1 )
1620 VECTOR2I referenceDiff = referencePoint1 - referencePoint0;
1622 SEG segm1( referencePoint0, referencePoint0 + directionNormalVector );
1623 SEG segm2( referencePoint1, referencePoint1 + direction );
1627 THROW_IO_ERROR( wxT(
"Invalid dimension. This should never happen." ) );
1629 dimension->SetEnd( *intersection );
1633 if( direction.
Cross( referenceDiff ) > 0 )
1636 dimension->SetHeight( height );
1640 dimension->SetEnd( referencePoint1 );
1643 dimension->SetLineThickness( aElem.
linewidth );
1645 dimension->SetUnitsFormat( DIM_UNITS_FORMAT::NO_SUFFIX );
1649 int dist = ( dimension->GetEnd() - dimension->GetStart() ).EuclideanNorm();
1651 if( dist < 3 * dimension->GetArrowLength() )
1652 dimension->SetArrowDirection( DIM_ARROW_DIRECTION::INWARD );
1655 wxRegEx units( wxS(
"(mm)|(in)|(mils)|(thou)|(')|(\")" ), wxRE_ADVANCED );
1658 dimension->SetUnitsFormat( DIM_UNITS_FORMAT::BARE_SUFFIX );
1667 dimension->Text().SetBold( aElem.
textbold );
1670 dimension->SetTextThickness( dimension->GetTextThickness() *
BOLD_FACTOR );
1675 case ALTIUM_UNIT::INCH: dimension->SetUnits( EDA_UNITS::INCH );
break;
1676 case ALTIUM_UNIT::MILS: dimension->SetUnits( EDA_UNITS::MILS );
break;
1677 case ALTIUM_UNIT::MM: dimension->SetUnits( EDA_UNITS::MM );
break;
1678 case ALTIUM_UNIT::CM: dimension->SetUnits( EDA_UNITS::MM );
break;
1682 m_board->
Add( dimension.release(), ADD_MODE::APPEND );
1689 THROW_IO_ERROR( wxT(
"Not enough reference points for radial dimension object" ) );
1698 _(
"Dimension found on an Altium layer (%d) with no KiCad equivalent. "
1699 "It has been moved to KiCad layer Eco1_User." ),
1709 std::unique_ptr<PCB_DIM_RADIAL> dimension = std::make_unique<PCB_DIM_RADIAL>(
m_board );
1712 dimension->SetLayer( klayer );
1713 dimension->SetStart( referencePoint0 );
1714 dimension->SetEnd( aElem.
xy1 );
1715 dimension->SetLineThickness( aElem.
linewidth );
1716 dimension->SetKeepTextAligned(
false );
1721 dimension->SetUnitsFormat( aElem.
textsuffix.IsEmpty() ? DIM_UNITS_FORMAT::NO_SUFFIX
1722 : DIM_UNITS_FORMAT::BARE_SUFFIX );
1726 case ALTIUM_UNIT::INCH: dimension->SetUnits( EDA_UNITS::INCH );
break;
1727 case ALTIUM_UNIT::MILS: dimension->SetUnits( EDA_UNITS::MILS );
break;
1728 case ALTIUM_UNIT::MM: dimension->SetUnits( EDA_UNITS::MM );
break;
1729 case ALTIUM_UNIT::CM: dimension->SetUnits( EDA_UNITS::MM );
break;
1737 m_reporter->
Report( wxT(
"No text position present for leader dimension object" ),
1744 dimension->SetTextPos( aElem.
textPoint.at( 0 ) );
1750 dimension->SetBold( aElem.
textbold );
1753 dimension->SetTextThickness( dimension->GetTextThickness() *
BOLD_FACTOR );
1761 int yAdjust = dimension->GetTextBox(
nullptr ).GetCenter().y - dimension->GetTextPos().y;
1762 dimension->SetTextPos( dimension->GetTextPos() +
VECTOR2I( 0, yAdjust + aElem.
textgap ) );
1766 m_board->
Add( dimension.release(), ADD_MODE::APPEND );
1779 msg.Printf(
_(
"Dimension found on an Altium layer (%d) with no KiCad equivalent. "
1780 "It has been moved to KiCad layer Eco1_User." ), aElem.
layer );
1795 std::unique_ptr<PCB_SHAPE> shape = std::make_unique<PCB_SHAPE>(
m_board, SHAPE_T::SEGMENT );
1797 shape->SetLayer( klayer );
1799 shape->SetStart( last );
1803 m_board->
Add( shape.release(), ADD_MODE::APPEND );
1811 if( dirVec.
x != 0 || dirVec.
y != 0 )
1818 std::unique_ptr<PCB_SHAPE> shape1 = std::make_unique<PCB_SHAPE>(
m_board, SHAPE_T::SEGMENT );
1820 shape1->SetLayer( klayer );
1822 shape1->SetStart( referencePoint0 );
1823 shape1->SetEnd( referencePoint0 + arrVec );
1825 m_board->
Add( shape1.release(), ADD_MODE::APPEND );
1831 std::unique_ptr<PCB_SHAPE> shape2 = std::make_unique<PCB_SHAPE>(
m_board, SHAPE_T::SEGMENT );
1833 shape2->SetLayer( klayer );
1835 shape2->SetStart( referencePoint0 );
1836 shape2->SetEnd( referencePoint0 + arrVec );
1838 m_board->
Add( shape2.release(), ADD_MODE::APPEND );
1848 m_reporter->
Report( wxT(
"No text position present for leader dimension object" ),
1855 std::unique_ptr<PCB_TEXT>
text = std::make_unique<PCB_TEXT>(
m_board );
1859 text->SetLayer( klayer );
1878 msg.Printf(
_(
"Dimension found on an Altium layer (%d) with no KiCad equivalent. "
1879 "It has been moved to KiCad layer Eco1_User." ), aElem.
layer );
1888 std::unique_ptr<PCB_SHAPE> shape = std::make_unique<PCB_SHAPE>(
m_board, SHAPE_T::SEGMENT );
1890 shape->SetLayer( klayer );
1895 m_board->
Add( shape.release(), ADD_MODE::APPEND );
1909 msg.Printf(
_(
"Dimension found on an Altium layer (%d) with no KiCad equivalent. "
1910 "It has been moved to KiCad layer Eco1_User." ), aElem.
layer );
1920 std::unique_ptr<PCB_DIM_CENTER> dimension = std::make_unique<PCB_DIM_CENTER>(
m_board );
1922 dimension->SetLayer( klayer );
1923 dimension->SetLineThickness( aElem.
linewidth );
1924 dimension->SetStart( aElem.
xy1 );
1925 dimension->SetEnd( aElem.
xy1 + vec );
1927 m_board->
Add( dimension.release(), ADD_MODE::APPEND );
1932 const CFB::COMPOUND_FILE_ENTRY* aEntry )
1946 case ALTIUM_DIMENSION_KIND::LINEAR:
1949 case ALTIUM_DIMENSION_KIND::ANGULAR:
1952 m_reporter->
Report( wxString::Format(
_(
"Ignored Angular dimension (not yet supported)." ) ),
1956 case ALTIUM_DIMENSION_KIND::RADIAL:
1959 case ALTIUM_DIMENSION_KIND::LEADER:
1962 case ALTIUM_DIMENSION_KIND::DATUM:
1965 m_reporter->
Report( wxString::Format(
_(
"Ignored Datum dimension (not yet supported)." ) ),
1970 case ALTIUM_DIMENSION_KIND::BASELINE:
1973 m_reporter->
Report( wxString::Format(
_(
"Ignored Baseline dimension (not yet supported)." ) ),
1977 case ALTIUM_DIMENSION_KIND::CENTER:
1980 case ALTIUM_DIMENSION_KIND::LINEAR_DIAMETER:
1983 m_reporter->
Report( wxString::Format(
_(
"Ignored Linear dimension (not yet supported)." ) ),
1987 case ALTIUM_DIMENSION_KIND::RADIAL_DIAMETER:
1990 m_reporter->
Report( wxString::Format(
_(
"Ignored Radial dimension (not yet supported)." ) ),
1998 msg.Printf(
_(
"Ignored dimension of kind %d (not yet supported)." ), elem.
kind );
2006 THROW_IO_ERROR( wxT(
"Dimensions6 stream is not fully parsed" ) );
2011 const CFB::COMPOUND_FILE_ENTRY* aEntry,
2012 const std::vector<std::string>& aRootDir )
2023 wxString invalidChars = wxFileName::GetForbiddenChars();
2030 std::vector<std::string> stepPath = aRootDir;
2031 stepPath.emplace_back( std::to_string( idx ) );
2033 bool validName = !elem.
name.IsEmpty() && elem.
name.IsAscii()
2034 && wxString::npos == elem.
name.find_first_of( invalidChars );
2035 wxString storageName = validName ? elem.
name : wxString::Format( wxT(
"model_%d" ), idx );
2039 const CFB::COMPOUND_FILE_ENTRY* stepEntry = aAltiumPcbFile.
FindStream( stepPath );
2041 if( stepEntry ==
nullptr )
2046 msg.Printf(
_(
"File not found: '%s'. 3D-model not imported." ),
FormatPath( stepPath ) );
2053 size_t stepSize =
static_cast<size_t>( stepEntry->size );
2054 std::vector<char> stepContent( stepSize );
2062 std::move( stepContent ) ) ) );
2066 std::map<wxString, std::vector<wxString>> nameIdMap;
2069 nameIdMap[data.m_modelname].push_back(
id );
2071 for(
auto& [
name, ids] : nameIdMap )
2073 for(
size_t i = 1; i < ids.size(); i++ )
2075 const wxString&
id = ids[i];
2082 wxString modelName = modelTuple->second.m_modelname;
2084 if( modelName.Contains(
"." ) )
2087 wxString baseName = modelName.BeforeLast(
'.', &ext );
2089 modelTuple->second.m_modelname = baseName +
'_' + std::to_string( i ) +
'.' + ext;
2093 modelTuple->second.m_modelname = modelName +
'_' + std::to_string( i );
2104 const CFB::COMPOUND_FILE_ENTRY* aEntry )
2116 ANET6 elem( reader );
2130 const CFB::COMPOUND_FILE_ENTRY* aEntry )
2163 if( elem.
hatchstyle != ALTIUM_POLYGON_HATCHSTYLE::SOLID )
2173 msg.Printf(
_(
"Polygon outline count is %d, expected 1." ), outline.
OutlineCount() );
2181 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>(
m_board);
2187 zone->SetPosition( elem.
vertices.at( 0 ).position );
2188 zone->SetLocked( elem.
locked );
2190 zone->Outline()->AddOutline( outline.
Outline( 0 ) );
2196 const ARULE6* zoneClearanceRule =
GetRule( ALTIUM_RULE_KIND::CLEARANCE, wxT(
"PolygonClearance" ) );
2197 int planeLayers = 0;
2198 int signalLayers = 0;
2212 if( planeLayers > 0 && planeClearanceRule )
2215 if( signalLayers > 0 && zoneClearanceRule )
2223 if( polygonConnectRule !=
nullptr )
2227 case ALTIUM_CONNECT_STYLE::DIRECT:
2228 zone->SetPadConnection( ZONE_CONNECTION::FULL );
2231 case ALTIUM_CONNECT_STYLE::NONE:
2232 zone->SetPadConnection( ZONE_CONNECTION::NONE );
2236 case ALTIUM_CONNECT_STYLE::RELIEF:
2237 zone->SetPadConnection( ZONE_CONNECTION::THERMAL );
2242 zone->SetThermalReliefSpokeWidth(
2253 zone->SetAssignedPriority( 1 );
2258 || zone->GetBoundingBox().Contains( outer_plane->second->GetBoundingBox() ) )
2264 if( elem.
hatchstyle != ALTIUM_POLYGON_HATCHSTYLE::SOLID
2265 && elem.
hatchstyle != ALTIUM_POLYGON_HATCHSTYLE::UNKNOWN )
2267 zone->SetFillMode( ZONE_FILL_MODE::HATCH_PATTERN );
2270 if( elem.
hatchstyle == ALTIUM_POLYGON_HATCHSTYLE::NONE )
2273 const BOX2I& bbox = zone->GetBoundingBox();
2281 if( elem.
hatchstyle == ALTIUM_POLYGON_HATCHSTYLE::DEGREE_45 )
2282 zone->SetHatchOrientation(
ANGLE_45 );
2285 zone->SetBorderDisplayStyle( ZONE_BORDER_DISPLAY_STYLE::DIAGONAL_EDGE,
2289 m_board->
Add( zone.release(), ADD_MODE::APPEND );
2297 const CFB::COMPOUND_FILE_ENTRY* aEntry )
2315 std::sort( val.second.begin(), val.second.end(),
2318 return lhs.priority < rhs.priority;
2331 if( trackWidthRule )
2337 if( routingViasRule )
2348 if( holeToHoleRule )
2354 if( soldermaskRule )
2365 const CFB::COMPOUND_FILE_ENTRY* aEntry )
2381 THROW_IO_ERROR( wxT(
"BoardRegions stream is not fully parsed" ) );
2385 const CFB::COMPOUND_FILE_ENTRY* aEntry )
2393 for(
int primitiveIndex = 0; reader.
GetRemainingBytes() >= 4; primitiveIndex++ )
2399 || elem.
kind == ALTIUM_REGION_KIND::BOARD_CUTOUT )
2412 THROW_IO_ERROR(
"ShapeBasedRegions6 stream is not fully parsed" );
2418 if( aElem.
kind == ALTIUM_REGION_KIND::BOARD_CUTOUT )
2422 else if( aElem.
kind == ALTIUM_REGION_KIND::POLYGON_CUTOUT || aElem.
is_keepout )
2436 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>(
m_board );
2438 zone->SetIsRuleArea(
true );
2444 else if( aElem.
kind == ALTIUM_REGION_KIND::POLYGON_CUTOUT )
2446 zone->SetDoNotAllowZoneFills(
true );
2447 zone->SetDoNotAllowVias(
false );
2448 zone->SetDoNotAllowTracks(
false );
2449 zone->SetDoNotAllowPads(
false );
2450 zone->SetDoNotAllowFootprints(
false );
2453 zone->SetPosition( aElem.
outline.at( 0 ).position );
2454 zone->Outline()->AddOutline( linechain );
2458 zone->SetBorderDisplayStyle( ZONE_BORDER_DISPLAY_STYLE::DIAGONAL_EDGE,
2461 m_board->
Add( zone.release(), ADD_MODE::APPEND );
2463 else if( aElem.
kind == ALTIUM_REGION_KIND::DASHED_OUTLINE )
2472 msg.Printf(
_(
"Dashed outline found on an Altium layer (%d) with no KiCad equivalent. "
2473 "It has been moved to KiCad layer Eco1_User." ), aElem.
layer );
2492 std::unique_ptr<PCB_SHAPE> shape = std::make_unique<PCB_SHAPE>(
m_board, SHAPE_T::POLY );
2494 shape->SetPolyShape( linechain );
2495 shape->SetFilled(
false );
2496 shape->SetLayer( klayer );
2499 m_board->
Add( shape.release(), ADD_MODE::APPEND );
2501 else if( aElem.
kind == ALTIUM_REGION_KIND::COPPER )
2509 else if( aElem.
kind == ALTIUM_REGION_KIND::BOARD_CUTOUT )
2518 msg.Printf(
_(
"Ignored polygon shape of kind %d (not yet supported)." ), aElem.
kind );
2527 const int aPrimitiveIndex )
2529 if( aElem.
kind == ALTIUM_REGION_KIND::POLYGON_CUTOUT || aElem.
is_keepout )
2543 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>( aFootprint );
2545 zone->SetIsRuleArea(
true );
2551 else if( aElem.
kind == ALTIUM_REGION_KIND::POLYGON_CUTOUT )
2553 zone->SetDoNotAllowZoneFills(
true );
2554 zone->SetDoNotAllowVias(
false );
2555 zone->SetDoNotAllowTracks(
false );
2556 zone->SetDoNotAllowPads(
false );
2557 zone->SetDoNotAllowFootprints(
false );
2560 zone->SetPosition( aElem.
outline.at( 0 ).position );
2561 zone->Outline()->AddOutline( linechain );
2565 zone->SetBorderDisplayStyle( ZONE_BORDER_DISPLAY_STYLE::DIAGONAL_EDGE,
2568 aFootprint->
Add( zone.release(), ADD_MODE::APPEND );
2570 else if( aElem.
kind == ALTIUM_REGION_KIND::COPPER )
2581 else if( aElem.
kind == ALTIUM_REGION_KIND::DASHED_OUTLINE
2582 || aElem.
kind == ALTIUM_REGION_KIND::BOARD_CUTOUT )
2595 msg.Printf(
_(
"Loading library '%s':\n"
2596 "Footprint %s contains a dashed outline on Altium layer (%d) with "
2597 "no KiCad equivalent. It has been moved to KiCad layer Eco1_User." ),
2609 msg.Printf(
_(
"Footprint %s contains a dashed outline on Altium layer (%d) with "
2610 "no KiCad equivalent. It has been moved to KiCad layer Eco1_User." ),
2632 std::unique_ptr<PCB_SHAPE> shape = std::make_unique<PCB_SHAPE>( aFootprint, SHAPE_T::POLY );
2634 shape->SetPolyShape( linechain );
2635 shape->SetFilled(
false );
2636 shape->SetLayer( klayer );
2638 if( aElem.
kind == ALTIUM_REGION_KIND::DASHED_OUTLINE )
2643 aFootprint->
Add( shape.release(), ADD_MODE::APPEND );
2652 msg.Printf(
_(
"Error loading library '%s':\n"
2653 "Footprint %s contains polygon shape of kind %d (not yet supported)." ),
2665 msg.Printf(
_(
"Footprint %s contains polygon shape of kind %d (not yet supported)." ),
2693 for(
const std::vector<ALTIUM_VERTICE>& hole : aElem.
holes )
2701 polySet.
AddHole( hole_linechain );
2704 std::unique_ptr<PCB_SHAPE> shape = std::make_unique<PCB_SHAPE>(
m_board, SHAPE_T::POLY );
2706 shape->SetPolyShape( polySet );
2707 shape->SetFilled(
true );
2708 shape->SetLayer( aLayer );
2716 m_board->
Add( shape.release(), ADD_MODE::APPEND );
2723 const int aPrimitiveIndex )
2740 for(
const std::vector<ALTIUM_VERTICE>& hole : aElem.
holes )
2748 polySet.
AddHole( hole_linechain );
2751 if( aLayer ==
F_Cu || aLayer ==
B_Cu )
2754 std::unique_ptr<PAD>
pad = std::make_unique<PAD>( aFootprint );
2757 padLayers.
set( aLayer );
2759 pad->SetAttribute( PAD_ATTRIB::SMD );
2768 pad->SetPosition( anchorPos );
2771 shapePolys.
Move( -anchorPos );
2775 auto it = map.find( aPrimitiveIndex );
2777 if( it != map.end() )
2781 if(
info.pastemaskexpansionmode == ALTIUM_MODE::MANUAL )
2783 pad->SetLocalSolderPasteMargin(
info.pastemaskexpansionmanual );
2786 if(
info.soldermaskexpansionmode == ALTIUM_MODE::MANUAL )
2788 pad->SetLocalSolderMaskMargin(
info.soldermaskexpansionmanual );
2791 if(
info.pastemaskexpansionmode != ALTIUM_MODE::NONE )
2794 if(
info.soldermaskexpansionmode != ALTIUM_MODE::NONE )
2798 pad->SetLayerSet( padLayers );
2800 aFootprint->
Add(
pad.release(), ADD_MODE::APPEND );
2804 std::unique_ptr<PCB_SHAPE> shape = std::make_unique<PCB_SHAPE>( aFootprint, SHAPE_T::POLY );
2806 shape->SetPolyShape( polySet );
2807 shape->SetFilled(
true );
2808 shape->SetLayer( aLayer );
2811 aFootprint->
Add( shape.release(), ADD_MODE::APPEND );
2817 const CFB::COMPOUND_FILE_ENTRY* aEntry )
2833 THROW_IO_ERROR( wxString::Format(
"Region stream tries to access polygon id %d "
2834 "of %d existing polygons.",
2841 if( zone ==
nullptr )
2863 for(
const std::vector<ALTIUM_VERTICE>& hole : elem.
holes )
2870 hole_linechain.
Append( hole.at( 0 ).position );
2872 fill.
AddHole( hole_linechain );
2892 const CFB::COMPOUND_FILE_ENTRY* aEntry )
2899 for(
int primitiveIndex = 0; reader.
GetRemainingBytes() >= 4; primitiveIndex++ )
2902 AARC6 elem( reader );
2924 aShape->
SetShape( SHAPE_T::CIRCLE );
2953 THROW_IO_ERROR( wxString::Format(
"Tracks stream tries to access polygon id %u "
2954 "of %zu existing polygons.",
2960 if( zone ==
nullptr )
3008 for(
const auto& layerExpansionMask :
3011 int width = aElem.
width + ( layerExpansionMask.second * 2 );
3015 std::unique_ptr<PCB_SHAPE> arc = std::make_unique<PCB_SHAPE>(
m_board );
3018 arc->SetStroke(
STROKE_PARAMS( width, LINE_STYLE::SOLID ) );
3019 arc->SetLayer( layerExpansionMask.first );
3021 m_board->
Add( arc.release(), ADD_MODE::APPEND );
3028 const int aPrimitiveIndex,
const bool aIsBoardImport )
3032 wxFAIL_MSG( wxString::Format(
"Altium: Unexpected footprint Arc with polygon id %d",
3065 for(
const auto& layerExpansionMask :
3068 int width = aElem.
width + ( layerExpansionMask.second * 2 );
3072 std::unique_ptr<PCB_SHAPE> arc = std::make_unique<PCB_SHAPE>( aFootprint );
3075 arc->SetStroke(
STROKE_PARAMS( width, LINE_STYLE::SOLID ) );
3076 arc->SetLayer( layerExpansionMask.first );
3078 aFootprint->
Add( arc.release(), ADD_MODE::APPEND );
3099 PCB_SHAPE shape(
nullptr, SHAPE_T::ARC );
3108 std::unique_ptr<PCB_ARC> arc = std::make_unique<PCB_ARC>(
m_board, &shapeArc );
3110 arc->SetWidth( aElem.
width );
3111 arc->SetLayer( aLayer );
3114 m_board->
Add( arc.release(), ADD_MODE::APPEND );
3119 std::unique_ptr<PCB_SHAPE> arc = std::make_unique<PCB_SHAPE>(
m_board);
3123 arc->SetLayer( aLayer );
3125 m_board->
Add( arc.release(), ADD_MODE::APPEND );
3133 std::unique_ptr<PCB_SHAPE> arc = std::make_unique<PCB_SHAPE>( aFootprint );
3137 arc->SetLayer( aLayer );
3139 aFootprint->
Add( arc.release(), ADD_MODE::APPEND );
3144 const CFB::COMPOUND_FILE_ENTRY* aEntry )
3154 APAD6 elem( reader );
3176 && aElem.
layer != ALTIUM_LAYER::MULTI_LAYER )
3183 std::unique_ptr<FOOTPRINT> footprint = std::make_unique<FOOTPRINT>(
m_board );
3184 footprint->SetPosition( aElem.
position );
3188 m_board->
Add( footprint.release(), ADD_MODE::APPEND );
3195 std::unique_ptr<PAD>
pad = std::make_unique<PAD>( aFootprint );
3197 pad->SetNumber(
"" );
3203 pad->SetDrillShape( PAD_DRILL_SHAPE::CIRCLE );
3205 pad->SetAttribute( PAD_ATTRIB::PTH );
3208 pad->SetLayerSet(
LSET().AllCuMask() );
3210 if( aElem.
viamode == ALTIUM_PAD_MODE::SIMPLE )
3214 else if( aElem.
viamode == ALTIUM_PAD_MODE::TOP_MIDDLE_BOTTOM )
3235 pad->Padstack().FrontOuterLayers().has_solder_mask =
true;
3239 pad->Padstack().FrontOuterLayers().has_solder_mask =
false;
3245 pad->Padstack().BackOuterLayers().has_solder_mask =
true;
3249 pad->Padstack().BackOuterLayers().has_solder_mask =
false;
3254 pad->SetLocked(
true );
3263 aFootprint->
Add(
pad.release(), ADD_MODE::APPEND );
3271 && aElem.
layer != ALTIUM_LAYER::MULTI_LAYER )
3284 std::unique_ptr<PAD>
pad = std::make_unique<PAD>( aFootprint );
3295 pad->SetAttribute( PAD_ATTRIB::SMD );
3299 if( aElem.
layer != ALTIUM_LAYER::MULTI_LAYER )
3307 msg.Printf(
_(
"Error loading library '%s':\n"
3308 "Footprint %s pad %s is not marked as multilayer, but is a TH pad." ),
3320 msg.Printf(
_(
"Footprint %s pad %s is not marked as multilayer, but is a TH pad." ),
3328 pad->SetAttribute( aElem.
plated ? PAD_ATTRIB::PTH : PAD_ATTRIB::NPTH );
3332 pad->SetDrillShape( PAD_DRILL_SHAPE::CIRCLE );
3339 case ALTIUM_PAD_HOLE_SHAPE::ROUND:
3340 wxFAIL_MSG( wxT(
"Round holes are handled before the switch" ) );
3343 case ALTIUM_PAD_HOLE_SHAPE::SQUARE:
3349 msg.Printf(
_(
"Loading library '%s':\n"
3350 "Footprint %s pad %s has a square hole (not yet supported)." ),
3362 msg.Printf(
_(
"Footprint %s pad %s has a square hole (not yet supported)." ),
3369 pad->SetDrillShape( PAD_DRILL_SHAPE::CIRCLE );
3375 case ALTIUM_PAD_HOLE_SHAPE::SLOT:
3377 pad->SetDrillShape( PAD_DRILL_SHAPE::OBLONG );
3397 msg.Printf(
_(
"Loading library '%s':\n"
3398 "Footprint %s pad %s has a hole-rotation of %d degrees. "
3399 "KiCad only supports 90 degree rotations." ),
3412 msg.Printf(
_(
"Footprint %s pad %s has a hole-rotation of %d degrees. "
3413 "KiCad only supports 90 degree rotations." ),
3426 case ALTIUM_PAD_HOLE_SHAPE::UNKNOWN:
3432 msg.Printf(
_(
"Error loading library '%s':\n"
3433 "Footprint %s pad %s uses a hole of unknown kind %d." ),
3446 msg.Printf(
_(
"Footprint %s pad %s uses a hole of unknown kind %d." ),
3454 pad->SetDrillShape( PAD_DRILL_SHAPE::CIRCLE );
3466 auto setCopperGeometry =
3475 case ALTIUM_PAD_SHAPE::RECT:
3476 ps.
SetShape( PAD_SHAPE::RECTANGLE, aLayer );
3479 case ALTIUM_PAD_SHAPE::CIRCLE:
3481 && aElem.
sizeAndShape->alt_shape[altLayer] == ALTIUM_PAD_SHAPE_ALT::ROUNDRECT )
3483 ps.
SetShape( PAD_SHAPE::ROUNDRECT, aLayer );
3484 double ratio = aElem.
sizeAndShape->cornerradius[altLayer] / 200.;
3489 ps.
SetShape( PAD_SHAPE::CIRCLE, aLayer );
3493 ps.
SetShape( PAD_SHAPE::OVAL, aLayer );
3498 case ALTIUM_PAD_SHAPE::OCTAGONAL:
3499 ps.
SetShape( PAD_SHAPE::CHAMFERED_RECT, aLayer );
3504 case ALTIUM_PAD_SHAPE::UNKNOWN:
3511 msg.Printf(
_(
"Error loading library '%s':\n"
3512 "Footprint %s pad %s uses an unknown pad shape." ),
3524 msg.Printf(
_(
"Footprint %s pad %s uses an unknown pad shape." ),
3536 case ALTIUM_PAD_MODE::SIMPLE:
3541 case ALTIUM_PAD_MODE::TOP_MIDDLE_BOTTOM:
3548 case ALTIUM_PAD_MODE::FULL_STACK:
3565 setCopperGeometry( layer, aElem.
sizeAndShape->inner_shape[i],
3575 switch( aElem.
layer )
3577 case ALTIUM_LAYER::TOP_LAYER:
3582 case ALTIUM_LAYER::BOTTOM_LAYER:
3587 case ALTIUM_LAYER::MULTI_LAYER:
3593 pad->SetLayer( klayer );
3594 pad->SetLayerSet(
LSET( { klayer } ) );
3605 pad->SetLayerSet(
pad->GetLayerSet().reset(
F_Mask ) );
3608 pad->SetLayerSet(
pad->GetLayerSet().reset(
B_Mask ) );
3610 aFootprint->
Add(
pad.release(), ADD_MODE::APPEND );
3623 msg.Printf(
_(
"Non-copper pad %s found on an Altium layer (%d) with no KiCad "
3624 "equivalent. It has been moved to KiCad layer Eco1_User." ),
3632 std::unique_ptr<PCB_SHAPE>
pad = std::make_unique<PCB_SHAPE>(
m_board );
3651 msg.Printf(
_(
"Loading library '%s':\n"
3652 "Footprint %s non-copper pad %s found on an Altium layer (%d) with no "
3653 "KiCad equivalent. It has been moved to KiCad layer Eco1_User." ),
3666 msg.Printf(
_(
"Footprint %s non-copper pad %s found on an Altium layer (%d) with no "
3667 "KiCad equivalent. It has been moved to KiCad layer Eco1_User." ),
3678 std::unique_ptr<PCB_SHAPE>
pad = std::make_unique<PCB_SHAPE>( aFootprint );
3682 aFootprint->
Add(
pad.release(), ADD_MODE::APPEND );
3694 msg.Printf(
_(
"Non-copper pad %s is connected to a net, which is not supported." ),
3705 msg.Printf(
_(
"Non-copper pad %s has a hole, which is not supported." ), aElem.
name );
3710 if( aElem.
padmode != ALTIUM_PAD_MODE::SIMPLE )
3715 msg.Printf(
_(
"Non-copper pad %s has a complex pad stack (not yet supported)." ),
3723 case ALTIUM_PAD_SHAPE::RECT:
3742 case ALTIUM_PAD_SHAPE::CIRCLE:
3744 && aElem.
sizeAndShape->alt_shape[0] == ALTIUM_PAD_SHAPE_ALT::ROUNDRECT )
3747 int cornerradius = aElem.
sizeAndShape->cornerradius[0];
3748 int offset = ( std::min( aElem.
topsize.
x, aElem.
topsize.
y ) * cornerradius ) / 200;
3753 if( cornerradius < 100 )
3755 int offsetX = aElem.
topsize.
x / 2 - offset;
3756 int offsetY = aElem.
topsize.
y / 2 - offset;
3770 aShape->
SetShape( SHAPE_T::CIRCLE );
3779 aShape->
SetShape( SHAPE_T::SEGMENT );
3787 aShape->
SetShape( SHAPE_T::SEGMENT );
3799 aShape->
SetShape( SHAPE_T::CIRCLE );
3809 aShape->
SetShape( SHAPE_T::SEGMENT );
3812 LINE_STYLE::SOLID ) );
3832 case ALTIUM_PAD_SHAPE::OCTAGONAL:
3849 aShape->
SetPolyPoints( { p11 - chamferX, p11 - chamferY, p12 + chamferY, p12 - chamferX,
3850 p22 + chamferX, p22 + chamferY, p21 - chamferY, p21 + chamferX } );
3857 case ALTIUM_PAD_SHAPE::UNKNOWN:
3862 msg.Printf(
_(
"Non-copper pad %s uses an unknown pad shape." ), aElem.
name );
3872 const CFB::COMPOUND_FILE_ENTRY* aEntry )
3882 AVIA6 elem( reader );
3884 std::unique_ptr<PCB_VIA>
via = std::make_unique<PCB_VIA>(
m_board );
3891 bool start_layer_outside = elem.
layer_start == ALTIUM_LAYER::TOP_LAYER
3892 || elem.
layer_start == ALTIUM_LAYER::BOTTOM_LAYER;
3893 bool end_layer_outside = elem.
layer_end == ALTIUM_LAYER::TOP_LAYER
3894 || elem.
layer_end == ALTIUM_LAYER::BOTTOM_LAYER;
3896 if( start_layer_outside && end_layer_outside )
3898 via->SetViaType( VIATYPE::THROUGH );
3900 else if( ( !start_layer_outside ) || ( !end_layer_outside ) )
3902 via->SetViaType( VIATYPE::BLIND_BURIED );
3908 via->SetViaType( VIATYPE::MICROVIA );
3919 msg.Printf(
_(
"Via from layer %d to %d uses a non-copper layer, which is not "
3930 via->SetLayerPair( start_klayer, end_klayer );
3935 case ALTIUM_PAD_MODE::SIMPLE:
3939 case ALTIUM_PAD_MODE::TOP_MIDDLE_BOTTOM:
3946 case ALTIUM_PAD_MODE::FULL_STACK:
3953 wxCHECK2_MSG( altiumLayer < 32,
break,
3954 "Altium importer expects 32 or fewer copper layers" );
3965 via->SetFrontTentingMode( elem.
is_tent_top ? TENTING_MODE::TENTED
3966 : TENTING_MODE::NOT_TENTED );
3968 : TENTING_MODE::NOT_TENTED );
3979 const CFB::COMPOUND_FILE_ENTRY* aEntry )
3986 for(
int primitiveIndex = 0; reader.
GetRemainingBytes() >= 4; primitiveIndex++ )
4017 msg.Printf( wxT(
"ATRACK6 stream tries to access polygon id %u "
4018 "of %u existing polygons; skipping it" ),
4019 static_cast<unsigned>( aElem.
polygon ),
4020 static_cast<unsigned>(
m_polygons.size() ) );
4029 if( zone ==
nullptr )
4045 PCB_SHAPE shape(
nullptr, SHAPE_T::SEGMENT );
4063 PCB_SHAPE shape(
nullptr, SHAPE_T::SEGMENT );
4077 ALTIUM_RECORD::TRACK, aPrimitiveIndex, aElem.
layer ) )
4079 int width = aElem.
width + ( layerExpansionMask.second * 2 );
4082 std::unique_ptr<PCB_SHAPE> seg = std::make_unique<PCB_SHAPE>(
m_board, SHAPE_T::SEGMENT );
4084 seg->SetStart( aElem.
start );
4085 seg->SetEnd( aElem.
end );
4086 seg->SetStroke(
STROKE_PARAMS( width, LINE_STYLE::SOLID ) );
4087 seg->SetLayer( layerExpansionMask.first );
4089 m_board->
Add( seg.release(), ADD_MODE::APPEND );
4096 const int aPrimitiveIndex,
4097 const bool aIsBoardImport )
4101 wxFAIL_MSG( wxString::Format(
"Altium: Unexpected footprint Track with polygon id %u",
4110 PCB_SHAPE shape(
nullptr, SHAPE_T::SEGMENT );
4135 ALTIUM_RECORD::TRACK, aPrimitiveIndex, aElem.
layer ) )
4137 int width = aElem.
width + ( layerExpansionMask.second * 2 );
4140 std::unique_ptr<PCB_SHAPE> seg = std::make_unique<PCB_SHAPE>( aFootprint, SHAPE_T::SEGMENT );
4142 seg->SetStart( aElem.
start );
4143 seg->SetEnd( aElem.
end );
4144 seg->SetStroke(
STROKE_PARAMS( width, LINE_STYLE::SOLID ) );
4145 seg->SetLayer( layerExpansionMask.first );
4147 aFootprint->
Add( seg.release(), ADD_MODE::APPEND );
4157 std::unique_ptr<PCB_TRACK> track = std::make_unique<PCB_TRACK>(
m_board );
4159 track->SetStart( aElem.
start );
4160 track->SetEnd( aElem.
end );
4161 track->SetWidth( aElem.
width );
4162 track->SetLayer( aLayer );
4165 m_board->
Add( track.release(), ADD_MODE::APPEND );
4169 std::unique_ptr<PCB_SHAPE> seg = std::make_unique<PCB_SHAPE>(
m_board, SHAPE_T::SEGMENT );
4171 seg->SetStart( aElem.
start );
4172 seg->SetEnd( aElem.
end );
4174 seg->SetLayer( aLayer );
4176 m_board->
Add( seg.release(), ADD_MODE::APPEND );
4184 std::unique_ptr<PCB_SHAPE> seg = std::make_unique<PCB_SHAPE>( aFootprint, SHAPE_T::SEGMENT );
4186 seg->SetStart( aElem.
start );
4187 seg->SetEnd( aElem.
end );
4189 seg->SetLayer( aLayer );
4191 aFootprint->
Add( seg.release(), ADD_MODE::APPEND );
4196 const CFB::COMPOUND_FILE_ENTRY* aEntry )
4206 THROW_IO_ERROR( wxT(
"WideStrings6 stream is not fully parsed" ) );
4210 const CFB::COMPOUND_FILE_ENTRY* aEntry )
4240 if( aElem.
fonttype == ALTIUM_TEXT_TYPE::BARCODE )
4245 msg.Printf(
_(
"Ignored barcode on Altium layer %d (not yet supported)." ),
4260 if( aElem.
fonttype == ALTIUM_TEXT_TYPE::BARCODE )
4267 msg.Printf(
_(
"Error loading library '%s':\n"
4268 "Footprint %s contains barcode on Altium layer %d (not yet supported)." ),
4280 msg.Printf(
_(
"Footprint %s contains barcode on Altium layer %d (not yet supported)." ),
4297 std::unique_ptr<PCB_TEXTBOX> pcbTextbox = std::make_unique<PCB_TEXTBOX>(
m_board );
4298 std::unique_ptr<PCB_TEXT> pcbText = std::make_unique<PCB_TEXT>(
m_board );
4302 static const std::map<wxString, wxString> variableMap = {
4303 {
"LAYER_NAME",
"LAYER" },
4304 {
"PRINT_DATE",
"CURRENT_DATE"},
4314 item = pcbTextbox.get();
4315 text = pcbTextbox.get();
4326 text->SetText( kicadText );
4331 m_board->
Add( pcbTextbox.release(), ADD_MODE::APPEND );
4333 m_board->
Add( pcbText.release(), ADD_MODE::APPEND );
4340 std::unique_ptr<PCB_TEXTBOX> fpTextbox = std::make_unique<PCB_TEXTBOX>( aFootprint );
4341 std::unique_ptr<PCB_TEXT> fpText = std::make_unique<PCB_TEXT>( aFootprint );
4358 item = &aFootprint->
Value();
4360 field = &aFootprint->
Value();
4364 item = fpText.get();
4365 text = fpText.get();
4369 static const std::map<wxString, wxString> variableMap = {
4370 {
"DESIGNATOR",
"REFERENCE" },
4371 {
"COMMENT",
"VALUE" },
4372 {
"VALUE",
"ALTIUM_VALUE" },
4373 {
"LAYER_NAME",
"LAYER" },
4374 {
"PRINT_DATE",
"CURRENT_DATE"},
4379 item = fpTextbox.get();
4380 text = fpTextbox.get();
4393 text->SetText( kicadText );
4394 text->SetKeepUpright(
false );
4401 aFootprint->
Add( fpTextbox.release(), ADD_MODE::APPEND );
4403 aFootprint->
Add( fpText.release(), ADD_MODE::APPEND );
4431 kicadMargin =
VECTOR2I( charWidth * 0.933, charHeight * 0.67 );
4433 kicadMargin =
VECTOR2I( charWidth * 0.808, charHeight * 0.844 );
4436 + kicadMargin * 2 - margin * 2 );
4438 kposition = kposition - kicadMargin + margin;
4454 : ALTIUM_TEXT_POSITION::LEFT_BOTTOM;
4456 switch( justification )
4458 case ALTIUM_TEXT_POSITION::LEFT_TOP:
4459 case ALTIUM_TEXT_POSITION::LEFT_CENTER:
4460 case ALTIUM_TEXT_POSITION::LEFT_BOTTOM:
4464 case ALTIUM_TEXT_POSITION::CENTER_TOP:
4465 case ALTIUM_TEXT_POSITION::CENTER_CENTER:
4466 case ALTIUM_TEXT_POSITION::CENTER_BOTTOM:
4470 case ALTIUM_TEXT_POSITION::RIGHT_TOP:
4471 case ALTIUM_TEXT_POSITION::RIGHT_CENTER:
4472 case ALTIUM_TEXT_POSITION::RIGHT_BOTTOM:
4480 msg.Printf(
_(
"Unknown textbox justification %d, aText %s" ), justification,
4500 int rectHeight = aElem.
height;
4503 rectWidth = -rectWidth;
4507 : ALTIUM_TEXT_POSITION::LEFT_BOTTOM;
4509 switch( justification )
4511 case ALTIUM_TEXT_POSITION::LEFT_TOP:
4515 kposition.
y -= rectHeight;
4517 case ALTIUM_TEXT_POSITION::LEFT_CENTER:
4521 kposition.
y -= rectHeight / 2;
4523 case ALTIUM_TEXT_POSITION::LEFT_BOTTOM:
4527 case ALTIUM_TEXT_POSITION::CENTER_TOP:
4531 kposition.
x += rectWidth / 2;
4532 kposition.
y -= rectHeight;
4534 case ALTIUM_TEXT_POSITION::CENTER_CENTER:
4538 kposition.
x += rectWidth / 2;
4539 kposition.
y -= rectHeight / 2;
4541 case ALTIUM_TEXT_POSITION::CENTER_BOTTOM:
4545 kposition.
x += rectWidth / 2;
4547 case ALTIUM_TEXT_POSITION::RIGHT_TOP:
4551 kposition.
x += rectWidth;
4552 kposition.
y -= rectHeight;
4554 case ALTIUM_TEXT_POSITION::RIGHT_CENTER:
4558 kposition.
x += rectWidth;
4559 kposition.
y -= rectHeight / 2;
4561 case ALTIUM_TEXT_POSITION::RIGHT_BOTTOM:
4565 kposition.
x += rectWidth;
4610 if( aElem.
fonttype == ALTIUM_TEXT_TYPE::TRUETYPE )
4618 if( font->
GetName().Contains( wxS(
"Arial" ) ) )
4633 const CFB::COMPOUND_FILE_ENTRY* aEntry )
4666 PCB_SHAPE shape(
nullptr, SHAPE_T::RECTANGLE );
4691 const bool aIsBoardImport )
4694 || aElem.
layer == ALTIUM_LAYER::KEEP_OUT_LAYER )
4697 PCB_SHAPE shape(
nullptr, SHAPE_T::RECTANGLE );
4731 std::unique_ptr<PCB_SHAPE> fill = std::make_unique<PCB_SHAPE>(
m_board, SHAPE_T::RECTANGLE );
4733 fill->SetFilled(
true );
4734 fill->SetLayer( aLayer );
4737 fill->SetStart( aElem.
pos1 );
4738 fill->SetEnd( aElem.
pos2 );
4753 m_board->
Add( fill.release(), ADD_MODE::APPEND );
4760 if( aLayer ==
F_Cu || aLayer ==
B_Cu )
4762 std::unique_ptr<PAD>
pad = std::make_unique<PAD>( aFootprint );
4765 padLayers.
set( aLayer );
4767 pad->SetAttribute( PAD_ATTRIB::SMD );
4780 std::swap( width, height );
4783 pad->SetPosition( aElem.
pos1 / 2 + aElem.
pos2 / 2 );
4795 pad->SetPosition( anchorPos );
4806 aElem.
pos1.
y / 2 + aElem.
pos2.
y / 2 - anchorPos.
y );
4808 pad->AddPrimitivePoly(
F_Cu, shapePolys, 0,
true );
4812 pad->SetLayerSet( padLayers );
4814 aFootprint->
Add(
pad.release(), ADD_MODE::APPEND );
4818 std::unique_ptr<PCB_SHAPE> fill =
4819 std::make_unique<PCB_SHAPE>( aFootprint, SHAPE_T::RECTANGLE );
4821 fill->SetFilled(
true );
4822 fill->SetLayer( aLayer );
4825 fill->SetStart( aElem.
pos1 );
4826 fill->SetEnd( aElem.
pos2 );
4835 aFootprint->
Add( fill.release(), ADD_MODE::APPEND );
4845 layerSet.
set( klayer );
4853 bool keepoutRestrictionVia = ( aKeepoutRestrictions & 0x01 ) != 0;
4854 bool keepoutRestrictionTrack = ( aKeepoutRestrictions & 0x02 ) != 0;
4855 bool keepoutRestrictionCopper = ( aKeepoutRestrictions & 0x04 ) != 0;
4856 bool keepoutRestrictionSMDPad = ( aKeepoutRestrictions & 0x08 ) != 0;
4857 bool keepoutRestrictionTHPad = ( aKeepoutRestrictions & 0x10 ) != 0;
4869 const uint8_t aKeepoutRestrictions )
4871 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>(
m_board );
4873 zone->SetIsRuleArea(
true );
4880 zone->SetBorderDisplayStyle( ZONE_BORDER_DISPLAY_STYLE::DIAGONAL_EDGE,
4883 m_board->
Add( zone.release(), ADD_MODE::APPEND );
4890 const uint8_t aKeepoutRestrictions )
4892 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>( aFootprint );
4894 zone->SetIsRuleArea(
true );
4901 zone->SetBorderDisplayStyle( ZONE_BORDER_DISPLAY_STYLE::DIAGONAL_EDGE,
4905 aFootprint->
Add( zone.release(), ADD_MODE::APPEND );
4918 if( elems.first == elems.second )
4921 std::vector<std::pair<PCB_LAYER_ID, int>> layerExpansionPairs;
4923 for(
auto it = elems.first; it != elems.second; ++it )
4927 if( pInf.
type == AEXTENDED_PRIMITIVE_INFORMATION_TYPE::MASK )
4933 if( aAltiumLayer == ALTIUM_LAYER::TOP_LAYER
4934 || aAltiumLayer == ALTIUM_LAYER::MULTI_LAYER )
4939 if( aAltiumLayer == ALTIUM_LAYER::BOTTOM_LAYER
4940 || aAltiumLayer == ALTIUM_LAYER::MULTI_LAYER )
4948 if( aAltiumLayer == ALTIUM_LAYER::TOP_LAYER
4949 || aAltiumLayer == ALTIUM_LAYER::MULTI_LAYER )
4954 if( aAltiumLayer == ALTIUM_LAYER::BOTTOM_LAYER
4955 || aAltiumLayer == ALTIUM_LAYER::MULTI_LAYER )
4963 return layerExpansionPairs;
std::string FormatPath(const std::vector< std::string > &aVectorPath)
Helper for debug logging (vector -> string)
const uint16_t ALTIUM_NET_UNCONNECTED
const uint16_t ALTIUM_POLYGON_NONE
const uint16_t ALTIUM_POLYGON_BOARD
const int ALTIUM_COMPONENT_NONE
LIB_ID AltiumToKiCadLibID(const wxString &aLibName, const wxString &aLibReference)
wxString AltiumPcbSpecialStringsToKiCadStrings(const wxString &aString, const std::map< wxString, wxString > &aOverrides)
void HelperShapeLineChainFromAltiumVertices(SHAPE_LINE_CHAIN &aLine, const std::vector< ALTIUM_VERTICE > &aVertices)
double normalizeAngleDegrees(double Angle, double aMin, double aMax)
Normalize angle to be aMin < angle <= aMax angle is in degrees.
constexpr double BOLD_FACTOR
bool IsAltiumLayerCopper(ALTIUM_LAYER aLayer)
bool IsAltiumLayerAPlane(ALTIUM_LAYER aLayer)
std::function< void(const ALTIUM_PCB_COMPOUND_FILE &, const CFB::COMPOUND_FILE_ENTRY *)> PARSE_FUNCTION_POINTER_fp
constexpr int ARC_HIGH_DEF
constexpr EDA_IU_SCALE pcbIUScale
LAYER_T
The allowed types of layers, same as Specctra DSN spec.
@ BS_ITEM_TYPE_DIELECTRIC
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
size_t GetRemainingBytes() const
std::map< uint32_t, wxString > ReadWideStringTable()
size_t ReadAndSetSubrecordLength()
std::map< wxString, wxString > ReadProperties(std::function< std::map< wxString, wxString >(const std::string &)> handleBinaryData=[](const std::string &) { return std::map< wxString, wxString >();})
const CFB::CompoundFileReader & GetCompoundFileReader() const
const CFB::COMPOUND_FILE_ENTRY * FindStream(const std::vector< std::string > &aStreamPath) const
const std::pair< AMODEL, std::vector< char > > * GetLibModel(const wxString &aModelID) const
std::tuple< wxString, const CFB::COMPOUND_FILE_ENTRY * > FindLibFootprintDirName(const wxString &aFpUnicodeName)
PROGRESS_REPORTER * m_progressReporter
optional; may be nullptr
void ParseClasses6Data(const ALTIUM_PCB_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry)
std::vector< PCB_DIM_RADIAL * > m_radialDimensions
void ConvertArcs6ToFootprintItemOnLayer(FOOTPRINT *aFootprint, const AARC6 &aElem, PCB_LAYER_ID aLayer)
void ConvertTracks6ToBoardItem(const ATRACK6 &aElem, const int aPrimitiveIndex)
void ConvertTracks6ToFootprintItem(FOOTPRINT *aFootprint, const ATRACK6 &aElem, const int aPrimitiveIndex, const bool aIsBoardImport)
int m_highest_pour_index
Altium stores pour order across all layers.
void ConvertTexts6ToFootprintItemOnLayer(FOOTPRINT *aFootprint, const ATEXT6 &aElem, PCB_LAYER_ID aLayer)
std::map< ALTIUM_LAYER, PCB_LAYER_ID > m_layermap
void ConvertShapeBasedRegions6ToBoardItemOnLayer(const AREGION6 &aElem, PCB_LAYER_ID aLayer)
void ParseVias6Data(const ALTIUM_PCB_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry)
void HelperParseDimensions6Leader(const ADIMENSION6 &aElem)
wxString m_footprintName
for footprint library loading error reporting
std::vector< FOOTPRINT * > m_components
void ParseShapeBasedRegions6Data(const ALTIUM_PCB_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry)
const ARULE6 * GetRuleDefault(ALTIUM_RULE_KIND aKind) const
void HelperParsePad6NonCopper(const APAD6 &aElem, PCB_LAYER_ID aLayer, PCB_SHAPE *aShape)
void ParseRegions6Data(const ALTIUM_PCB_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry)
std::vector< PCB_LAYER_ID > GetKicadLayersToIterate(ALTIUM_LAYER aAltiumLayer) const
void ConvertShapeBasedRegions6ToFootprintItem(FOOTPRINT *aFootprint, const AREGION6 &aElem, const int aPrimitiveIndex)
void HelperPcpShapeAsFootprintKeepoutRegion(FOOTPRINT *aFootprint, const PCB_SHAPE &aShape, const ALTIUM_LAYER aAltiumLayer, const uint8_t aKeepoutRestrictions)
void ConvertArcs6ToBoardItem(const AARC6 &aElem, const int aPrimitiveIndex)
void ConvertShapeBasedRegions6ToFootprintItemOnLayer(FOOTPRINT *aFootprint, const AREGION6 &aElem, PCB_LAYER_ID aLayer, const int aPrimitiveIndex)
std::map< ALTIUM_LAYER, ZONE * > m_outer_plane
std::vector< int > m_altiumToKicadNetcodes
unsigned m_totalCount
for progress reporting
void ParseComponents6Data(const ALTIUM_PCB_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry)
void HelperPcpShapeAsBoardKeepoutRegion(const PCB_SHAPE &aShape, const ALTIUM_LAYER aAltiumLayer, const uint8_t aKeepoutRestrictions)
std::map< wxString, ALTIUM_EMBEDDED_MODEL_DATA > m_EmbeddedModels
void ConvertFills6ToBoardItemOnLayer(const AFILL6 &aElem, PCB_LAYER_ID aLayer)
std::vector< std::pair< PCB_LAYER_ID, int > > HelperGetSolderAndPasteMaskExpansions(const ALTIUM_RECORD aType, const int aPrimitiveIndex, const ALTIUM_LAYER aAltiumLayer)
void ConvertComponentBody6ToFootprintItem(const ALTIUM_PCB_COMPOUND_FILE &aAltiumPcbFile, FOOTPRINT *aFootprint, const ACOMPONENTBODY6 &aElem)
void HelperSetTextAlignmentAndPos(const ATEXT6 &aElem, EDA_TEXT *aEdaText)
void ParseBoard6Data(const ALTIUM_PCB_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry)
void ConvertFills6ToFootprintItem(FOOTPRINT *aFootprint, const AFILL6 &aElem, const bool aIsBoardImport)
void ParseExtendedPrimitiveInformationData(const ALTIUM_PCB_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry)
void ParseFileHeader(const ALTIUM_PCB_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry)
void ConvertShapeBasedRegions6ToBoardItem(const AREGION6 &aElem)
void HelperCreateBoardOutline(const std::vector< ALTIUM_VERTICE > &aVertices)
std::map< ALTIUM_RULE_KIND, std::vector< ARULE6 > > m_rules
void ConvertVias6ToFootprintItem(FOOTPRINT *aFootprint, const AVIA6 &aElem)
void ParseRules6Data(const ALTIUM_PCB_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry)
void HelperSetZoneKeepoutRestrictions(ZONE &aZone, const uint8_t aKeepoutRestrictions)
void HelperParseDimensions6Linear(const ADIMENSION6 &aElem)
void ParseTracks6Data(const ALTIUM_PCB_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry)
std::map< uint32_t, wxString > m_unicodeStrings
void ConvertTexts6ToBoardItem(const ATEXT6 &aElem)
void HelperParseDimensions6Center(const ADIMENSION6 &aElem)
void HelperParseDimensions6Radial(const ADIMENSION6 &aElem)
void ParseBoardRegionsData(const ALTIUM_PCB_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry)
void ParseArcs6Data(const ALTIUM_PCB_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry)
void ConvertTexts6ToBoardItemOnLayer(const ATEXT6 &aElem, PCB_LAYER_ID aLayer)
void ConvertPads6ToFootprintItemOnCopper(FOOTPRINT *aFootprint, const APAD6 &aElem)
FOOTPRINT * ParseFootprint(ALTIUM_PCB_COMPOUND_FILE &altiumLibFile, const wxString &aFootprintName)
REPORTER * m_reporter
optional; may be nullptr
int GetNetCode(uint16_t aId) const
void ConvertTexts6ToEdaTextSettings(const ATEXT6 &aElem, EDA_TEXT &aEdaText)
wxString m_library
for footprint library loading error reporting
void ConvertPads6ToFootprintItemOnNonCopper(FOOTPRINT *aFootprint, const APAD6 &aElem)
void ConvertTexts6ToFootprintItem(FOOTPRINT *aFootprint, const ATEXT6 &aElem)
unsigned m_lastProgressCount
void ParseFills6Data(const ALTIUM_PCB_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry)
void ConvertArcs6ToFootprintItem(FOOTPRINT *aFootprint, const AARC6 &aElem, const int aPrimitiveIndex, const bool aIsBoardImport)
void HelperParseDimensions6Datum(const ADIMENSION6 &aElem)
void ConvertPads6ToBoardItem(const APAD6 &aElem)
void ConvertFills6ToFootprintItemOnLayer(FOOTPRINT *aFootprint, const AFILL6 &aElem, PCB_LAYER_ID aLayer)
void ParseWideStrings6Data(const ALTIUM_PCB_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry)
void remapUnsureLayers(std::vector< ABOARD6_LAYER_STACKUP > &aStackup)
std::vector< ZONE * > m_polygons
void ParsePads6Data(const ALTIUM_PCB_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry)
void ConvertArcs6ToPcbShape(const AARC6 &aElem, PCB_SHAPE *aShape)
void ConvertTracks6ToBoardItemOnLayer(const ATRACK6 &aElem, PCB_LAYER_ID aLayer)
void ConvertFills6ToBoardItem(const AFILL6 &aElem)
FOOTPRINT * HelperGetFootprint(uint16_t aComponent) const
LAYER_MAPPING_HANDLER m_layerMappingHandler
void ParsePolygons6Data(const ALTIUM_PCB_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry)
PCB_LAYER_ID GetKicadLayer(ALTIUM_LAYER aAltiumLayer) const
void ParseComponentsBodies6Data(const ALTIUM_PCB_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry)
void ConvertTracks6ToFootprintItemOnLayer(FOOTPRINT *aFootprint, const ATRACK6 &aElem, PCB_LAYER_ID aLayer)
void Parse(const ALTIUM_PCB_COMPOUND_FILE &aAltiumPcbFile, const std::map< ALTIUM_PCB_DIR, std::string > &aFileMapping)
ALTIUM_PCB(BOARD *aBoard, PROGRESS_REPORTER *aProgressReporter, LAYER_MAPPING_HANDLER &aLayerMappingHandler, REPORTER *aReporter=nullptr, const wxString &aLibrary=wxEmptyString, const wxString &aFootprintName=wxEmptyString)
void ConvertArcs6ToBoardItemOnLayer(const AARC6 &aElem, PCB_LAYER_ID aLayer)
void ParseTexts6Data(const ALTIUM_PCB_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry)
std::map< ALTIUM_RECORD, std::multimap< int, const AEXTENDED_PRIMITIVE_INFORMATION > > m_extendedPrimitiveInformationMaps
void ParseModelsData(const ALTIUM_PCB_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry, const std::vector< std::string > &aRootDir)
std::map< ALTIUM_LAYER, wxString > m_layerNames
void ConvertPads6ToBoardItemOnNonCopper(const APAD6 &aElem)
void HelperSetTextboxAlignmentAndPos(const ATEXT6 &aElem, PCB_TEXTBOX *aPcbTextbox)
void ParseNets6Data(const ALTIUM_PCB_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry)
void ConvertPads6ToFootprintItem(FOOTPRINT *aFootprint, const APAD6 &aElem)
const ARULE6 * GetRule(ALTIUM_RULE_KIND aKind, const wxString &aName) const
void ParseDimensions6Data(const ALTIUM_PCB_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry)
void HelperSetZoneLayers(ZONE &aZone, const ALTIUM_LAYER aAltiumLayer)
static wxString ReadString(const std::map< wxString, wxString > &aProps, const wxString &aKey, const wxString &aDefault)
BASE_SET & set(size_t pos)
Container for design settings for a BOARD object.
std::shared_ptr< NET_SETTINGS > m_NetSettings
void SetGridOrigin(const VECTOR2I &aOrigin)
const VECTOR2I & GetGridOrigin() const
int GetBoardThickness() const
The full thickness of the board including copper and masks.
void SetAuxOrigin(const VECTOR2I &aOrigin)
const VECTOR2I & GetAuxOrigin() const
int m_SolderMaskExpansion
BOARD_STACKUP & GetStackupDescriptor()
void SetBoardThickness(int aThickness)
int GetLineThickness(PCB_LAYER_ID aLayer) const
Return the default graphic segment thickness from the layer class for the given layer.
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.
void SetVisibleLayers(const LSET &aLayerMask)
A proxy function that calls the correspondent function in m_BoardSettings changes the bit-mask of vis...
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
const BOX2I GetBoardEdgesBoundingBox() const
Return the board bounding box calculated using exclusively the board edges (graphics on Edge....
const PAGE_INFO & GetPageSettings() const
bool IsLayerEnabled(PCB_LAYER_ID aLayer) const
A proxy function that calls the correspondent function in m_BoardSettings tests whether a given layer...
LAYER_T GetLayerType(PCB_LAYER_ID aLayer) const
Return the type of the copper layer given by aLayer.
bool SetLayerName(PCB_LAYER_ID aLayer, const wxString &aLayerName)
Changes the name of the layer given by aLayer.
void Move(const VECTOR2I &aMoveVector) override
Move this object.
int GetCopperLayerCount() const
const TRACKS & Tracks() const
bool m_LegacyNetclassesLoaded
True if netclasses were loaded from the file.
void SetCopperLayerCount(int aCount)
bool SetLayerType(PCB_LAYER_ID aLayer, LAYER_T aLayerType)
Change the type of the layer given by aLayer.
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
const LSET & GetEnabledLayers() const
A proxy function that calls the corresponding function in m_BoardSettings.
void SetEnabledLayers(const LSET &aLayerMask)
A proxy function that calls the correspondent function in m_BoardSettings.
const DRAWINGS & Drawings() const
constexpr coord_type GetY() const
constexpr size_type GetWidth() const
constexpr coord_type GetX() const
constexpr size_type GetHeight() const
bool IsHorizontal() const
bool IsCardinal90() const
EDA_ANGLE GetArcAngle() const
void SetCenter(const VECTOR2I &aCenter)
virtual void SetFilled(bool aFlag)
void SetStart(const VECTOR2I &aStart)
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
void SetShape(SHAPE_T aShape)
void SetEnd(const VECTOR2I &aEnd)
void SetArcAngleAndEnd(const EDA_ANGLE &aAngle, bool aCheckNegativeAngle=false)
Set the end point from the angle center and start.
void SetPolyPoints(const std::vector< VECTOR2I > &aPoints)
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
int GetTextHeight() const
void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true)
void SetTextPos(const VECTOR2I &aPoint)
KIFONT::FONT * GetFont() const
void SetMirrored(bool isMirrored)
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
void SetBoldFlag(bool aBold)
Set only the bold flag, without changing the font.
void SetTextThickness(int aWidth)
The TextThickness is that set by the user.
GR_TEXT_V_ALIGN_T GetVertJustify() const
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
void SetItalic(bool aItalic)
Set the text to be italic - this will also update the font if needed.
void SetFont(KIFONT::FONT *aFont)
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
wxString GetEmbeddedFileLink(const EMBEDDED_FILE &aFile) const
Return the link for an embedded file.
EMBEDDED_FILE * AddFile(const wxFileName &aName, bool aOverwrite)
Load a file from disk and adds it to the collection.
static RETURN_CODE CompressAndEncode(EMBEDDED_FILE &aFile)
Take data from the #decompressedData buffer and compresses it using ZSTD into the #compressedEncodedD...
VECTOR3D m_Offset
3D model offset (mm)
VECTOR3D m_Rotation
3D model rotation (degrees)
wxString m_Filename
The 3D shape filename in 3D library.
FONT is an abstract base class for both outline and stroke fonts.
static FONT * GetFont(const wxString &aFontName=wxEmptyString, bool aBold=false, bool aItalic=false, const std::vector< wxString > *aEmbeddedFiles=nullptr, bool aForDrawingSheet=false)
virtual bool IsStroke() const
const wxString & GetName() const
virtual bool IsOutline() const
LAYER_RANGE_ITERATOR begin() const
A logical library item identifier and consists of various portions much like a URI.
LSET is a set of PCB_LAYER_IDs.
static const LSET & AllBoardTechMask()
Return a mask holding board technical layers (no CU layer) on both side.
static const LSET & UserMask()
static LSET UserDefinedLayersMask(int aUserDefinedLayerCount=MAX_USER_DEFINED_LAYERS)
Return a mask with the requested number of user defined layers.
static const LSET & InternalCuMask()
Return a complete set of internal copper layers which is all Cu layers except F_Cu and B_Cu.
Handle the data for a net.
static const int UNCONNECTED
Constant that holds the "unconnected net" number (typically 0) all items "connected" to this net are ...
A PADSTACK defines the characteristics of a single or multi-layer pad, in the IPC sense of the word.
void SetRoundRectRadiusRatio(double aRatio, PCB_LAYER_ID aLayer)
void SetChamferRatio(double aRatio, PCB_LAYER_ID aLayer)
void SetShape(PAD_SHAPE aShape, PCB_LAYER_ID aLayer)
void SetChamferPositions(int aPositions, PCB_LAYER_ID aLayer)
@ NORMAL
Shape is the same on all layers.
@ CUSTOM
Shapes can be defined on arbitrary layers.
@ FRONT_INNER_BACK
Up to three shapes can be defined (F_Cu, inner copper layers, B_Cu)
void SetSize(const VECTOR2I &aSize, PCB_LAYER_ID aLayer)
static constexpr PCB_LAYER_ID ALL_LAYERS
! Temporary layer identifier to identify code that is not padstack-aware
static constexpr PCB_LAYER_ID INNER_LAYERS
! The layer identifier to use for "inner layers" on top/inner/bottom padstacks
static LSET PTHMask()
layer set for a through hole pad
static LSET UnplatedHoleMask()
layer set for a mechanical unplated through hole pad
static LSET SMDMask()
layer set for a SMD pad on Front layer
int GetHeightIU(double aIUScale) const
Gets the page height in IU.
int GetWidthIU(double aIUScale) const
Gets the page width in IU.
virtual VECTOR2I GetCenter() const override
This defaults to the center of the bounding box if not overridden.
A radial dimension indicates either the radius or diameter of an arc or circle.
VECTOR2I GetCenter() const override
This defaults to the center of the bounding box if not overridden.
void Rotate(const VECTOR2I &aRotCentre, const EDA_ANGLE &aAngle) override
Rotate this object.
void SetPosition(const VECTOR2I &aPos) override
void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
void SetStroke(const STROKE_PARAMS &aStroke) override
VECTOR2I GetPosition() const override
void SetBorderEnabled(bool enabled)
void SetMarginTop(int aTop)
void SetMarginLeft(int aLeft)
void SetMarginBottom(int aBottom)
void SetTextAngle(const EDA_ANGLE &aAngle) override
void SetMarginRight(int aRight)
A progress reporter interface for use in multi-threaded environments.
virtual bool KeepRefreshing(bool aWait=false)=0
Update the UI (if any).
virtual void Report(const wxString &aMessage)=0
Display aMessage in the progress bar dialog.
virtual void SetCurrentProgress(double aProgress)=0
Set the progress value to aProgress (0..1).
A pure virtual class used to derive REPORTER objects from.
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
Report a string with a given severity.
OPT_VECTOR2I Intersect(const SEG &aSeg, bool aIgnoreEndpoints=false, bool aLines=false) const
Compute intersection point of segment (this) with segment aSeg.
const VECTOR2I & GetArcMid() const
const VECTOR2I & GetP1() const
const VECTOR2I & GetP0() const
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
const SHAPE_ARC & Arc(size_t aArc) const
void SetClosed(bool aClosed)
Mark the line chain as closed (i.e.
int PointCount() const
Return the number of points (vertices) in this line chain.
ssize_t ArcIndex(size_t aSegment) const
Return the arc index for the given segment index.
SEG Segment(int aIndex) const
Return a copy of the aIndex-th segment in the line chain.
int NextShape(int aPointIndex) const
Return the vertex index of the next shape in the chain, or -1 if aPointIndex is the last shape.
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
bool IsArcStart(size_t aIndex) const
Represent a set of closed polygons.
void Rotate(const EDA_ANGLE &aAngle, const VECTOR2I &aCenter={ 0, 0 }) override
Rotate all vertices by a given angle.
void BooleanAdd(const SHAPE_POLY_SET &b)
Perform boolean polyset union.
int AddOutline(const SHAPE_LINE_CHAIN &aOutline)
Adds a new outline to the set and returns its index.
void Fracture()
Convert a set of polygons with holes to a single outline with "slits"/"fractures" connecting the oute...
void Inflate(int aAmount, CORNER_STRATEGY aCornerStrategy, int aMaxError, bool aSimplify=false)
Perform outline inflation/deflation.
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Appends a vertex at the end of the given outline/hole (default: the last outline)
int AddHole(const SHAPE_LINE_CHAIN &aHole, int aOutline=-1)
Adds a new hole to the given outline (default: last) and returns its index.
SHAPE_LINE_CHAIN & Outline(int aIndex)
Return the reference to aIndex-th outline in the set.
int NewOutline()
Creates a new empty polygon in the set and returns its index.
int OutlineCount() const
Return the number of outlines in the set.
void Move(const VECTOR2I &aVector) override
Simple container to manage line stroke parameters.
constexpr extended_type Cross(const VECTOR2< T > &aVector) const
Compute cross product of self with aVector.
double Distance(const VECTOR2< extended_type > &aVector) const
Compute the distance between two vectors.
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
constexpr VECTOR2< T > Perpendicular() const
Compute the perpendicular vector.
VECTOR2< T > Resize(T aNewLength) const
Return a vector of the same direction, but length specified in aNewLength.
Handle a list of polygons defining a copper zone.
void SetNeedRefill(bool aNeedRefill)
void SetDoNotAllowPads(bool aEnable)
SHAPE_POLY_SET * GetFill(PCB_LAYER_ID aLayer)
void SetDoNotAllowTracks(bool aEnable)
void SetFilledPolysList(PCB_LAYER_ID aLayer, const SHAPE_POLY_SET &aPolysList)
Set the list of filled polygons.
void SetIsFilled(bool isFilled)
bool HasFilledPolysForLayer(PCB_LAYER_ID aLayer) const
void SetLayerSet(const LSET &aLayerSet) override
void SetDoNotAllowVias(bool aEnable)
void SetDoNotAllowFootprints(bool aEnable)
void SetDoNotAllowZoneFills(bool aEnable)
static int GetDefaultHatchPitch()
static constexpr EDA_ANGLE ANGLE_90
static constexpr EDA_ANGLE ANGLE_45
#define THROW_IO_ERROR(msg)
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)
std::function< std::map< wxString, PCB_LAYER_ID >(const std::vector< INPUT_LAYER_DESC > &)> LAYER_MAPPING_HANDLER
Pointer to a function that takes a map of source and KiCad layers and returns a re-mapped version.
std::optional< VECTOR2I > OPT_VECTOR2I
wxString NotSpecifiedPrm()
uint8_t keepoutrestrictions
wxString dielectricmaterial
std::vector< ABOARD6_LAYER_STACKUP > stackup
std::vector< ALTIUM_VERTICE > board_vertices
std::vector< wxString > names
wxString sourceHierachicalPath
wxString sourcefootprintlibrary
wxString sourcedesignator
std::vector< VECTOR2I > textPoint
ALTIUM_DIMENSION_KIND kind
std::vector< VECTOR2I > referencePoint
uint8_t keepoutrestrictions
std::vector< char > m_data
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
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_TEXT_TYPE fonttype
uint8_t keepoutrestrictions
int32_t soldermask_expansion_front
bool soldermask_expansion_manual
int32_t soldermask_expansion_back
uint32_t diameter_by_layer[32]
constexpr double IUTomm(int iu) const
constexpr int mmToIU(double mm) const
std::vector< char > decompressedData
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.
double DEG2RAD(double deg)
@ PCB_SHAPE_T
class PCB_SHAPE, a segment not on copper layers
@ PCB_DIM_ALIGNED_T
class PCB_DIM_ALIGNED, a linear dimension (graphic item)
@ PCB_ARC_T
class PCB_ARC, an arc track segment on a copper layer
VECTOR2< int32_t > VECTOR2I