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 "
301 const wxString& aLibrary,
const wxString& aFootprintName )
321 const unsigned PROGRESS_DELTA = 250;
339 const std::map<ALTIUM_PCB_DIR, std::string>& aFileMapping )
342 const std::vector<std::tuple<bool, ALTIUM_PCB_DIR, PARSE_FUNCTION_POINTER_fp>> parserOrder = {
343 {
true, ALTIUM_PCB_DIR::FILE_HEADER,
348 {
true, ALTIUM_PCB_DIR::BOARD6,
353 {
false, ALTIUM_PCB_DIR::EXTENDPRIMITIVEINFORMATION,
358 {
true, ALTIUM_PCB_DIR::COMPONENTS6,
363 {
false, ALTIUM_PCB_DIR::MODELS,
366 std::vector<std::string> dir{ aFileMapping.at( ALTIUM_PCB_DIR::MODELS ) };
369 {
true, ALTIUM_PCB_DIR::COMPONENTBODIES6,
374 {
true, ALTIUM_PCB_DIR::NETS6,
379 {
true, ALTIUM_PCB_DIR::CLASSES6,
384 {
true, ALTIUM_PCB_DIR::RULES6,
389 {
true, ALTIUM_PCB_DIR::DIMENSIONS6,
394 {
true, ALTIUM_PCB_DIR::POLYGONS6,
399 {
true, ALTIUM_PCB_DIR::ARCS6,
404 {
true, ALTIUM_PCB_DIR::PADS6,
409 {
true, ALTIUM_PCB_DIR::VIAS6,
414 {
true, ALTIUM_PCB_DIR::TRACKS6,
419 {
false, ALTIUM_PCB_DIR::WIDESTRINGS6,
424 {
true, ALTIUM_PCB_DIR::TEXTS6,
429 {
true, ALTIUM_PCB_DIR::FILLS6,
434 {
false, ALTIUM_PCB_DIR::BOARDREGIONS,
439 {
true, ALTIUM_PCB_DIR::SHAPEBASEDREGIONS6,
444 {
true, ALTIUM_PCB_DIR::REGIONS6,
454 for(
const std::tuple<bool, ALTIUM_PCB_DIR, PARSE_FUNCTION_POINTER_fp>& cur : parserOrder )
459 std::tie( isRequired,
directory, fp ) = cur;
461 if(
directory == ALTIUM_PCB_DIR::FILE_HEADER )
464 const auto& mappedDirectory = aFileMapping.find(
directory );
466 if( mappedDirectory == aFileMapping.end() )
469 const std::vector<std::string> mappedFile{ mappedDirectory->second,
"Header" };
470 const CFB::COMPOUND_FILE_ENTRY* file = altiumPcbFile.
FindStream( mappedFile );
472 if( file ==
nullptr )
476 uint32_t numOfRecords = reader.
Read<uint32_t>();
506 const auto& boardDirectory = aFileMapping.find( ALTIUM_PCB_DIR::BOARD6 );
508 if( boardDirectory != aFileMapping.end() )
510 std::vector<std::string> mappedFile{ boardDirectory->second,
"Data" };
512 const CFB::COMPOUND_FILE_ENTRY* file = altiumPcbFile.
FindStream( mappedFile );
517 "This file does not appear to be in a valid PCB Binary Version 6.0 format. In "
519 "make sure to save as \"PCB Binary Files (*.PcbDoc)\"." ) );
524 for(
const std::tuple<bool, ALTIUM_PCB_DIR, PARSE_FUNCTION_POINTER_fp>& cur : parserOrder )
529 std::tie( isRequired,
directory, fp ) = cur;
531 const auto& mappedDirectory = aFileMapping.find(
directory );
533 if( mappedDirectory == aFileMapping.end() )
535 wxASSERT_MSG( !isRequired, wxString::Format( wxT(
"Altium Directory of kind %d was "
536 "expected, but no mapping is "
537 "present in the code" ),
542 std::vector<std::string> mappedFile{ mappedDirectory->second };
544 if(
directory != ALTIUM_PCB_DIR::FILE_HEADER )
545 mappedFile.emplace_back(
"Data" );
547 const CFB::COMPOUND_FILE_ENTRY* file = altiumPcbFile.
FindStream( mappedFile );
549 if( file !=
nullptr )
551 fp( altiumPcbFile, file );
553 else if( isRequired )
557 m_reporter->
Report( wxString::Format(
_(
"File not found: '%s' for directory '%s'." ),
572 if( zone->GetAssignedPriority() == 1000 )
583 zone->SetAssignedPriority( priority >= 0 ? priority : 0 );
587 for( std::pair<const ALTIUM_LAYER, ZONE*>& zone :
m_outer_plane )
588 zone.second->SetAssignedPriority( 0 );
598 if( !zone->HasFilledPolysForLayer( layer ) )
601 zone->GetFilledPolysList( layer )->Fracture();
620 if( shape->
GetShape() != SHAPE_T::ARC && shape->
GetShape() != SHAPE_T::CIRCLE )
639 if( arc->
GetCenter() == dim->GetPosition() )
648 VECTOR2I radialLine = dim->GetEnd() - dim->GetStart();
653 radialLine = radialLine.
Resize( std::max(
radius, 2 ) );
654 dim->SetEnd( dim->GetStart() + (
VECTOR2I) radialLine );
655 dim->SetLeaderLength( totalLength -
radius );
665 int desired_x = ( w - bbbox.
GetWidth() ) / 2;
666 int desired_y = ( h - bbbox.
GetHeight() ) / 2;
668 VECTOR2I movementVector( desired_x - bbbox.
GetX(), desired_y - bbbox.
GetY() );
680 const wxString& aFootprintName )
682 std::unique_ptr<FOOTPRINT> footprint = std::make_unique<FOOTPRINT>(
m_board );
700 std::tuple<wxString, const CFB::COMPOUND_FILE_ENTRY*> ret =
703 wxString fpDirName = std::get<0>( ret );
704 const CFB::COMPOUND_FILE_ENTRY* footprintStream = std::get<1>( ret );
706 if( fpDirName.IsEmpty() )
709 wxString::Format(
_(
"Footprint directory not found: '%s'." ), aFootprintName ) );
712 const std::vector<std::string> streamName{ fpDirName.ToStdString(),
"Data" };
713 const CFB::COMPOUND_FILE_ENTRY* footprintData = altiumLibFile.
FindStream( footprintStream, {
"Data" } );
715 if( footprintData ==
nullptr )
728 footprint->SetFPID( fpID );
730 const std::vector<std::string> parametersStreamName{ fpDirName.ToStdString(),
732 const CFB::COMPOUND_FILE_ENTRY* parametersData =
733 altiumLibFile.
FindStream( footprintStream, {
"Parameters" } );
735 if( parametersData !=
nullptr )
738 std::map<wxString, wxString> parameterProperties = parametersReader.
ReadProperties();
740 wxT(
"DESCRIPTION" ), wxT(
"" ) );
741 footprint->SetLibDescription( description );
752 footprint->SetLibDescription( wxT(
"" ) );
755 const std::vector<std::string> extendedPrimitiveInformationStreamName{
756 "ExtendedPrimitiveInformation",
"Data"
758 const CFB::COMPOUND_FILE_ENTRY* extendedPrimitiveInformationData =
759 altiumLibFile.
FindStream( footprintStream, extendedPrimitiveInformationStreamName );
761 if( extendedPrimitiveInformationData !=
nullptr )
764 footprint->SetReference( wxT(
"REF**" ) );
765 footprint->SetValue( aFootprintName );
766 footprint->Reference().SetVisible(
true );
767 footprint->Value().SetVisible(
true );
772 for(
PCB_FIELD* field : footprint->GetFields() )
774 field->SetTextSize( defaultTextSize );
775 field->SetTextThickness( defaultTextThickness );
784 case ALTIUM_RECORD::ARC:
790 case ALTIUM_RECORD::PAD:
796 case ALTIUM_RECORD::VIA:
802 case ALTIUM_RECORD::TRACK:
808 case ALTIUM_RECORD::TEXT:
814 case ALTIUM_RECORD::FILL:
820 case ALTIUM_RECORD::REGION:
826 case ALTIUM_RECORD::MODEL:
833 THROW_IO_ERROR( wxString::Format(
_(
"Record of unknown type: '%d'." ), recordtype ) );
839 for(
bool changes =
true; changes; )
844 [&changes](
PAD* aPad1,
PAD* aPad2 )
846 if( !( aPad1->GetNumber().IsEmpty() ^ aPad2->GetNumber().IsEmpty() ) )
849 for( PCB_LAYER_ID layer : aPad1->GetLayerSet().Seq() )
851 std::shared_ptr<SHAPE> shape1 = aPad1->GetEffectiveShape( layer );
852 std::shared_ptr<SHAPE> shape2 = aPad2->GetEffectiveShape( layer );
854 if( shape1->Collide( shape2.get() ) )
856 if( aPad1->GetNumber().IsEmpty() )
857 aPad1->SetNumber( aPad2->GetNumber() );
859 aPad2->SetNumber( aPad1->GetNumber() );
868 footprint->AutoPositionFields();
870 if( parser.HasParsingError() )
872 THROW_IO_ERROR( wxString::Format( wxT(
"%s stream was not parsed correctly" ),
876 if( parser.GetRemainingBytes() != 0 )
878 THROW_IO_ERROR( wxString::Format( wxT(
"%s stream is not fully parsed" ),
882 return footprint.release();
893 THROW_IO_ERROR( wxString::Format( wxT(
"Netcode with id %d does not exist. Only %d nets "
905 const auto rules =
m_rules.find( aKind );
910 for(
const ARULE6& rule : rules->second )
912 if( rule.
name == aName )
921 const auto rules =
m_rules.find( aKind );
926 for(
const ARULE6& rule : rules->second )
936 const CFB::COMPOUND_FILE_ENTRY* aEntry )
954 const CFB::COMPOUND_FILE_ENTRY* aEntry )
971 THROW_IO_ERROR( wxT(
"ExtendedPrimitiveInformation stream is not fully parsed" ) );
976 const CFB::COMPOUND_FILE_ENTRY* aEntry )
993 size_t layercount = 0;
994 size_t layerid =
static_cast<size_t>( ALTIUM_LAYER::TOP_LAYER );
996 while( layerid < elem.
stackup.size() && layerid != 0 )
998 layerid = elem.
stackup[ layerid - 1 ].nextId;
1002 size_t kicadLayercount = ( layercount % 2 == 0 ) ? layercount : layercount + 1;
1012 auto it = stackup.
GetList().begin();
1020 for(
size_t altiumLayerId =
static_cast<size_t>( ALTIUM_LAYER::TOP_LAYER );
1021 altiumLayerId < elem.
stackup.size() && altiumLayerId != 0;
1022 altiumLayerId = elem.
stackup[altiumLayerId - 1].nextId )
1028 if( layer.
nextId == 0 && layercount != kicadLayercount )
1033 THROW_IO_ERROR( wxT(
"Board6 stream, unexpected item while parsing stackup" ) );
1035 ( *it )->SetThickness( 0 );
1040 THROW_IO_ERROR( wxT(
"Board6 stream, unexpected item while parsing stackup" ) );
1042 ( *it )->SetThickness( 0, 0 );
1043 ( *it )->SetThicknessLocked(
true, 0 );
1051 THROW_IO_ERROR( wxT(
"Board6 stream, unexpected item while parsing stackup" ) );
1065 if( klayer ==
B_Cu )
1068 THROW_IO_ERROR( wxT(
"Board6 stream, unexpected id while parsing last stackup layer" ) );
1078 THROW_IO_ERROR( wxT(
"Board6 stream, unexpected item while parsing stackup" ) );
1092 for(
size_t altiumLayerId =
static_cast<size_t>( ALTIUM_LAYER::TOP_OVERLAY );
1093 altiumLayerId <= static_cast<size_t>( ALTIUM_LAYER::BOTTOM_SOLDER ); altiumLayerId++ )
1104 for(
size_t altiumLayerId =
static_cast<size_t>( ALTIUM_LAYER::MECHANICAL_1 );
1105 altiumLayerId <= static_cast<size_t>( ALTIUM_LAYER::MECHANICAL_16 ); altiumLayerId++ )
1126 if( aStackup.size() == 0 )
1129 std::vector<INPUT_LAYER_DESC> inputLayers;
1130 std::map<wxString, ALTIUM_LAYER> altiumLayerNameMap;
1137 [&](
size_t ii ) ->
size_t
1142 if( layer_num < ALTIUM_LAYER::BOTTOM_LAYER )
1143 return curLayer.
nextId - 1;
1148 for(
size_t ii = 0; ii < aStackup.size(); ii =
next( ii ) )
1150 curLayer = aStackup[ii];
1154 && !( layer_num >= ALTIUM_LAYER::TOP_OVERLAY
1155 && layer_num <= ALTIUM_LAYER::BOTTOM_SOLDER )
1156 && !( layer_num >= ALTIUM_LAYER::MECHANICAL_1
1157 && layer_num <= ALTIUM_LAYER::MECHANICAL_16 ) )
1159 if( layer_num < ALTIUM_LAYER::BOTTOM_LAYER )
1173 inputLayers.push_back( iLdesc );
1174 altiumLayerNameMap.insert( { curLayer.
name, layer_num } );
1178 if( inputLayers.size() == 0 )
1185 for( std::pair<wxString, PCB_LAYER_ID> layerPair : reMappedLayers )
1187 if( layerPair.second == PCB_LAYER_ID::UNDEFINED_LAYER )
1189 wxFAIL_MSG( wxT(
"Unexpected Layer ID" ) );
1193 ALTIUM_LAYER altiumID = altiumLayerNameMap.at( layerPair.first );
1194 m_layermap.insert_or_assign( altiumID, layerPair.second );
1195 enabledLayers |=
LSET( { layerPair.second } );
1209 LINE_STYLE::SOLID );
1216 int nextShape = lineChain.
NextShape( i );
1217 bool isLastShape = nextShape < 0;
1219 std::unique_ptr<PCB_SHAPE> shape = std::make_unique<PCB_SHAPE>(
m_board, SHAPE_T::ARC );
1221 shape->SetStroke( stroke );
1225 m_board->
Add( shape.release(), ADD_MODE::APPEND );
1231 std::unique_ptr<PCB_SHAPE> shape = std::make_unique<PCB_SHAPE>(
m_board, SHAPE_T::SEGMENT );
1233 shape->SetStroke( stroke );
1235 shape->SetStart( seg.
A );
1236 shape->SetEnd( seg.
B );
1238 m_board->
Add( shape.release(), ADD_MODE::APPEND );
1245 const CFB::COMPOUND_FILE_ENTRY* aEntry )
1257 if( elem.
kind == ALTIUM_CLASS_KIND::NET_CLASS )
1259 std::shared_ptr<NETCLASS> nc = std::make_shared<NETCLASS>( elem.
name );
1261 for(
const wxString&
name : elem.
names )
1264 name, nc->GetName() );
1274 msg.Printf(
_(
"More than one Altium netclass with name '%s' found. "
1275 "Only the first one will be imported." ), elem.
name );
1294 const CFB::COMPOUND_FILE_ENTRY* aEntry )
1301 uint16_t componentId = 0;
1308 std::unique_ptr<FOOTPRINT> footprint = std::make_unique<FOOTPRINT>(
m_board );
1318 footprint->SetFPID( fpID );
1320 footprint->SetPosition( elem.
position );
1321 footprint->SetOrientationDegrees( elem.
rotation );
1327 if( reference.find_first_not_of(
"0123456789" ) == wxString::npos )
1328 reference.Prepend( wxT(
"UNK" ) );
1330 footprint->SetReference( reference );
1335 path.push_back( pathid );
1336 path.push_back(
id );
1338 footprint->SetPath(
path );
1342 footprint->SetLocked( elem.
locked );
1343 footprint->Reference().SetVisible( elem.
nameon );
1344 footprint->Value().SetVisible( elem.
commenton );
1345 footprint->SetLayer( elem.
layer == ALTIUM_LAYER::TOP_LAYER ?
F_Cu :
B_Cu );
1348 m_board->
Add( footprint.release(), ADD_MODE::APPEND );
1354 THROW_IO_ERROR( wxT(
"Components6 stream is not fully parsed" ) );
1361 while( Angle < aMin )
1364 while( Angle >= aMax )
1387 m_reporter->
Report( wxString::Format( wxT(
"Model %s not found for footprint %s" ),
1400 if( file->
name.IsEmpty() )
1401 file->
name = model->first.name;
1404 std::vector<char> decompressedData;
1405 wxMemoryInputStream compressedStream( model->second.data(), model->second.size() );
1406 wxZlibInputStream zlibStream( compressedStream );
1410 decompressedData.resize( model->second.size() * 6 );
1413 while( !zlibStream.Eof() )
1415 zlibStream.Read( decompressedData.data() + offset, decompressedData.size() - offset );
1416 size_t bytesRead = zlibStream.LastRead();
1421 offset += bytesRead;
1423 if( offset >= decompressedData.size() )
1424 decompressedData.resize( 2 * decompressedData.size() );
1427 decompressedData.resize( offset );
1448 orientation = -orientation;
1460 aFootprint->
Models().push_back( modelSettings );
1465 const CFB::COMPOUND_FILE_ENTRY* aEntry )
1482 THROW_IO_ERROR( wxString::Format( wxT(
"ComponentsBodies6 stream tries to access "
1483 "component id %d of %zu existing components" ),
1498 msg.Printf( wxT(
"ComponentsBodies6 stream tries to access model id %s which does "
1499 "not exist" ), elem.
modelId );
1512 wxMemoryInputStream compressedStream( modelData.
m_data.data(), modelData.
m_data.size() );
1513 wxZlibInputStream zlibStream( compressedStream );
1514 wxMemoryOutputStream decompressedStream;
1516 zlibStream.Read( decompressedStream );
1539 orientation = -orientation;
1552 footprint->
Models().push_back( modelSettings );
1556 THROW_IO_ERROR( wxT(
"ComponentsBodies6 stream is not fully parsed" ) );
1563 THROW_IO_ERROR( wxT(
"Incorrect number of reference points for linear dimension object" ) );
1572 _(
"Dimension found on an Altium layer (%d) with no KiCad equivalent. "
1573 "It has been moved to KiCad layer Eco1_User." ), aElem.
layer ),
1586 dimension->SetLayer( klayer );
1587 dimension->SetStart( referencePoint0 );
1589 if( referencePoint0 != aElem.
xy1 )
1602 SEG segm1( referencePoint0, referencePoint0 + directionNormalVector );
1603 SEG segm2( referencePoint1, referencePoint1 + direction );
1607 THROW_IO_ERROR( wxT(
"Invalid dimension. This should never happen." ) );
1609 dimension->SetEnd( *intersection );
1613 if( ( direction.
x > 0 || direction.
y < 0 ) != ( aElem.
angle >= 180.0 ) )
1616 dimension->SetHeight( height );
1620 dimension->SetEnd( referencePoint1 );
1623 dimension->SetLineThickness( aElem.
linewidth );
1625 dimension->SetUnitsFormat( DIM_UNITS_FORMAT::NO_SUFFIX );
1629 wxRegEx units( wxS(
"(mm)|(in)|(mils)|(thou)|(')|(\")" ), wxRE_ADVANCED );
1632 dimension->SetUnitsFormat( DIM_UNITS_FORMAT::BARE_SUFFIX );
1641 dimension->Text().SetBold( aElem.
textbold );
1644 dimension->SetTextThickness( dimension->GetTextThickness() *
BOLD_FACTOR );
1649 case ALTIUM_UNIT::INCH: dimension->SetUnits( EDA_UNITS::INCH );
break;
1650 case ALTIUM_UNIT::MILS: dimension->SetUnits( EDA_UNITS::MILS );
break;
1651 case ALTIUM_UNIT::MM: dimension->SetUnits( EDA_UNITS::MM );
break;
1652 case ALTIUM_UNIT::CM: dimension->SetUnits( EDA_UNITS::MM );
break;
1656 m_board->
Add( dimension.release(), ADD_MODE::APPEND );
1663 THROW_IO_ERROR( wxT(
"Not enough reference points for radial dimension object" ) );
1672 _(
"Dimension found on an Altium layer (%d) with no KiCad equivalent. "
1673 "It has been moved to KiCad layer Eco1_User." ),
1683 std::unique_ptr<PCB_DIM_RADIAL> dimension = std::make_unique<PCB_DIM_RADIAL>(
m_board );
1686 dimension->SetLayer( klayer );
1687 dimension->SetStart( referencePoint0 );
1688 dimension->SetEnd( aElem.
xy1 );
1689 dimension->SetLineThickness( aElem.
linewidth );
1690 dimension->SetKeepTextAligned(
false );
1695 dimension->SetUnitsFormat( aElem.
textsuffix.IsEmpty() ? DIM_UNITS_FORMAT::NO_SUFFIX
1696 : DIM_UNITS_FORMAT::BARE_SUFFIX );
1700 case ALTIUM_UNIT::INCH: dimension->SetUnits( EDA_UNITS::INCH );
break;
1701 case ALTIUM_UNIT::MILS: dimension->SetUnits( EDA_UNITS::MILS );
break;
1702 case ALTIUM_UNIT::MM: dimension->SetUnits( EDA_UNITS::MM );
break;
1703 case ALTIUM_UNIT::CM: dimension->SetUnits( EDA_UNITS::MM );
break;
1711 m_reporter->
Report( wxT(
"No text position present for leader dimension object" ),
1718 dimension->SetTextPos( aElem.
textPoint.at( 0 ) );
1724 dimension->SetBold( aElem.
textbold );
1727 dimension->SetTextThickness( dimension->GetTextThickness() *
BOLD_FACTOR );
1735 int yAdjust = dimension->GetTextBox().GetCenter().y - dimension->GetTextPos().y;
1736 dimension->SetTextPos( dimension->GetTextPos() +
VECTOR2I( 0, yAdjust + aElem.
textgap ) );
1740 m_board->
Add( dimension.release(), ADD_MODE::APPEND );
1753 msg.Printf(
_(
"Dimension found on an Altium layer (%d) with no KiCad equivalent. "
1754 "It has been moved to KiCad layer Eco1_User." ), aElem.
layer );
1769 std::unique_ptr<PCB_SHAPE> shape = std::make_unique<PCB_SHAPE>(
m_board, SHAPE_T::SEGMENT );
1771 shape->SetLayer( klayer );
1773 shape->SetStart( last );
1777 m_board->
Add( shape.release(), ADD_MODE::APPEND );
1785 if( dirVec.
x != 0 || dirVec.
y != 0 )
1793 std::unique_ptr<PCB_SHAPE> shape1 =
1794 std::make_unique<PCB_SHAPE>(
m_board, SHAPE_T::SEGMENT );
1796 shape1->SetLayer( klayer );
1798 shape1->SetStart( referencePoint0 );
1799 shape1->SetEnd( referencePoint0 + arrVec );
1801 m_board->
Add( shape1.release(), ADD_MODE::APPEND );
1807 std::unique_ptr<PCB_SHAPE> shape2 =
1808 std::make_unique<PCB_SHAPE>(
m_board, SHAPE_T::SEGMENT );
1810 shape2->SetLayer( klayer );
1812 shape2->SetStart( referencePoint0 );
1813 shape2->SetEnd( referencePoint0 + arrVec );
1815 m_board->
Add( shape2.release(), ADD_MODE::APPEND );
1825 m_reporter->
Report( wxT(
"No text position present for leader dimension object" ),
1832 std::unique_ptr<PCB_TEXT>
text = std::make_unique<PCB_TEXT>(
m_board );
1836 text->SetLayer( klayer );
1855 msg.Printf(
_(
"Dimension found on an Altium layer (%d) with no KiCad equivalent. "
1856 "It has been moved to KiCad layer Eco1_User." ), aElem.
layer );
1865 std::unique_ptr<PCB_SHAPE> shape = std::make_unique<PCB_SHAPE>(
m_board, SHAPE_T::SEGMENT );
1867 shape->SetLayer( klayer );
1872 m_board->
Add( shape.release(), ADD_MODE::APPEND );
1886 msg.Printf(
_(
"Dimension found on an Altium layer (%d) with no KiCad equivalent. "
1887 "It has been moved to KiCad layer Eco1_User." ), aElem.
layer );
1897 std::unique_ptr<PCB_DIM_CENTER> dimension = std::make_unique<PCB_DIM_CENTER>(
m_board );
1899 dimension->SetLayer( klayer );
1900 dimension->SetLineThickness( aElem.
linewidth );
1901 dimension->SetStart( aElem.
xy1 );
1902 dimension->SetEnd( aElem.
xy1 + vec );
1904 m_board->
Add( dimension.release(), ADD_MODE::APPEND );
1909 const CFB::COMPOUND_FILE_ENTRY* aEntry )
1923 case ALTIUM_DIMENSION_KIND::LINEAR:
1926 case ALTIUM_DIMENSION_KIND::ANGULAR:
1930 wxString::Format(
_(
"Ignored Angular dimension (not yet supported)." ) ),
1934 case ALTIUM_DIMENSION_KIND::RADIAL:
1937 case ALTIUM_DIMENSION_KIND::LEADER:
1940 case ALTIUM_DIMENSION_KIND::DATUM:
1944 wxString::Format(
_(
"Ignored Datum dimension (not yet supported)." ) ),
1949 case ALTIUM_DIMENSION_KIND::BASELINE:
1953 wxString::Format(
_(
"Ignored Baseline dimension (not yet supported)." ) ),
1957 case ALTIUM_DIMENSION_KIND::CENTER:
1960 case ALTIUM_DIMENSION_KIND::LINEAR_DIAMETER:
1964 wxString::Format(
_(
"Ignored Linear dimension (not yet supported)." ) ),
1968 case ALTIUM_DIMENSION_KIND::RADIAL_DIAMETER:
1972 wxString::Format(
_(
"Ignored Radial dimension (not yet supported)." ) ),
1980 msg.Printf(
_(
"Ignored dimension of kind %d (not yet supported)." ), elem.
kind );
1988 THROW_IO_ERROR( wxT(
"Dimensions6 stream is not fully parsed" ) );
1993 const CFB::COMPOUND_FILE_ENTRY* aEntry,
1994 const std::vector<std::string>& aRootDir )
2005 wxString invalidChars = wxFileName::GetForbiddenChars();
2012 std::vector<std::string> stepPath = aRootDir;
2013 stepPath.emplace_back( std::to_string( idx ) );
2015 bool validName = !elem.
name.IsEmpty() && elem.
name.IsAscii() &&
2016 wxString::npos == elem.
name.find_first_of( invalidChars );
2017 wxString storageName = !validName ? wxString::Format( wxT(
"model_%d" ), idx )
2022 const CFB::COMPOUND_FILE_ENTRY* stepEntry = aAltiumPcbFile.
FindStream( stepPath );
2024 if( stepEntry ==
nullptr )
2029 msg.Printf(
_(
"File not found: '%s'. 3D-model not imported." ),
2037 size_t stepSize =
static_cast<size_t>( stepEntry->size );
2038 std::vector<char> stepContent( stepSize );
2046 std::move( stepContent ) ) ) );
2055 const CFB::COMPOUND_FILE_ENTRY* aEntry )
2067 ANET6 elem( reader );
2081 const CFB::COMPOUND_FILE_ENTRY* aEntry )
2114 if( elem.
hatchstyle != ALTIUM_POLYGON_HATCHSTYLE::SOLID )
2124 msg.Printf(
_(
"Polygon outline count is %d, expected 1." ), outline.
OutlineCount() );
2132 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>(
m_board);
2138 zone->SetPosition( elem.
vertices.at( 0 ).position );
2139 zone->SetLocked( elem.
locked );
2141 zone->Outline()->AddOutline( outline.
Outline( 0 ) );
2147 const ARULE6* zoneClearanceRule =
GetRule( ALTIUM_RULE_KIND::CLEARANCE,
2148 wxT(
"PolygonClearance" ) );
2149 int planeLayers = 0;
2150 int signalLayers = 0;
2164 if( planeLayers > 0 && planeClearanceRule )
2167 if( signalLayers > 0 && zoneClearanceRule )
2175 if( polygonConnectRule !=
nullptr )
2179 case ALTIUM_CONNECT_STYLE::DIRECT:
2180 zone->SetPadConnection( ZONE_CONNECTION::FULL );
2183 case ALTIUM_CONNECT_STYLE::NONE:
2184 zone->SetPadConnection( ZONE_CONNECTION::NONE );
2188 case ALTIUM_CONNECT_STYLE::RELIEF:
2189 zone->SetPadConnection( ZONE_CONNECTION::THERMAL );
2194 zone->SetThermalReliefSpokeWidth(
2205 zone->SetAssignedPriority( 1 );
2210 || zone->GetBoundingBox().Contains( outer_plane->second->GetBoundingBox() ) )
2216 if( elem.
hatchstyle != ALTIUM_POLYGON_HATCHSTYLE::SOLID
2217 && elem.
hatchstyle != ALTIUM_POLYGON_HATCHSTYLE::UNKNOWN )
2219 zone->SetFillMode( ZONE_FILL_MODE::HATCH_PATTERN );
2222 if( elem.
hatchstyle == ALTIUM_POLYGON_HATCHSTYLE::NONE )
2225 const BOX2I& bbox = zone->GetBoundingBox();
2233 if( elem.
hatchstyle == ALTIUM_POLYGON_HATCHSTYLE::DEGREE_45 )
2234 zone->SetHatchOrientation(
ANGLE_45 );
2237 zone->SetBorderDisplayStyle( ZONE_BORDER_DISPLAY_STYLE::DIAGONAL_EDGE,
2241 m_board->
Add( zone.release(), ADD_MODE::APPEND );
2249 const CFB::COMPOUND_FILE_ENTRY* aEntry )
2267 std::sort( val.second.begin(), val.second.end(),
2270 return lhs.priority < rhs.priority;
2283 if( trackWidthRule )
2289 if( routingViasRule )
2300 if( holeToHoleRule )
2306 if( soldermaskRule )
2317 const CFB::COMPOUND_FILE_ENTRY* aEntry )
2333 THROW_IO_ERROR( wxT(
"BoardRegions stream is not fully parsed" ) );
2337 const CFB::COMPOUND_FILE_ENTRY* aEntry )
2345 for(
int primitiveIndex = 0; reader.
GetRemainingBytes() >= 4; primitiveIndex++ )
2351 || elem.
kind == ALTIUM_REGION_KIND::BOARD_CUTOUT )
2364 THROW_IO_ERROR(
"ShapeBasedRegions6 stream is not fully parsed" );
2370 if( aElem.
kind == ALTIUM_REGION_KIND::BOARD_CUTOUT )
2374 else if( aElem.
kind == ALTIUM_REGION_KIND::POLYGON_CUTOUT || aElem.
is_keepout )
2388 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>(
m_board );
2390 zone->SetIsRuleArea(
true );
2396 else if( aElem.
kind == ALTIUM_REGION_KIND::POLYGON_CUTOUT )
2398 zone->SetDoNotAllowZoneFills(
true );
2399 zone->SetDoNotAllowVias(
false );
2400 zone->SetDoNotAllowTracks(
false );
2401 zone->SetDoNotAllowPads(
false );
2402 zone->SetDoNotAllowFootprints(
false );
2405 zone->SetPosition( aElem.
outline.at( 0 ).position );
2406 zone->Outline()->AddOutline( linechain );
2410 zone->SetBorderDisplayStyle( ZONE_BORDER_DISPLAY_STYLE::DIAGONAL_EDGE,
2413 m_board->
Add( zone.release(), ADD_MODE::APPEND );
2415 else if( aElem.
kind == ALTIUM_REGION_KIND::DASHED_OUTLINE )
2424 msg.Printf(
_(
"Dashed outline found on an Altium layer (%d) with no KiCad equivalent. "
2425 "It has been moved to KiCad layer Eco1_User." ), aElem.
layer );
2444 std::unique_ptr<PCB_SHAPE> shape = std::make_unique<PCB_SHAPE>(
m_board, SHAPE_T::POLY );
2446 shape->SetPolyShape( linechain );
2447 shape->SetFilled(
false );
2448 shape->SetLayer( klayer );
2451 m_board->
Add( shape.release(), ADD_MODE::APPEND );
2453 else if( aElem.
kind == ALTIUM_REGION_KIND::COPPER )
2461 else if( aElem.
kind == ALTIUM_REGION_KIND::BOARD_CUTOUT )
2470 msg.Printf(
_(
"Ignored polygon shape of kind %d (not yet supported)." ), aElem.
kind );
2479 const int aPrimitiveIndex )
2481 if( aElem.
kind == ALTIUM_REGION_KIND::POLYGON_CUTOUT || aElem.
is_keepout )
2495 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>( aFootprint );
2497 zone->SetIsRuleArea(
true );
2503 else if( aElem.
kind == ALTIUM_REGION_KIND::POLYGON_CUTOUT )
2505 zone->SetDoNotAllowZoneFills(
true );
2506 zone->SetDoNotAllowVias(
false );
2507 zone->SetDoNotAllowTracks(
false );
2508 zone->SetDoNotAllowPads(
false );
2509 zone->SetDoNotAllowFootprints(
false );
2512 zone->SetPosition( aElem.
outline.at( 0 ).position );
2513 zone->Outline()->AddOutline( linechain );
2517 zone->SetBorderDisplayStyle( ZONE_BORDER_DISPLAY_STYLE::DIAGONAL_EDGE,
2520 aFootprint->
Add( zone.release(), ADD_MODE::APPEND );
2522 else if( aElem.
kind == ALTIUM_REGION_KIND::COPPER )
2533 else if( aElem.
kind == ALTIUM_REGION_KIND::DASHED_OUTLINE
2534 || aElem.
kind == ALTIUM_REGION_KIND::BOARD_CUTOUT )
2547 msg.Printf(
_(
"Loading library '%s':\n"
2548 "Footprint %s contains a dashed outline on Altium layer (%d) with "
2549 "no KiCad equivalent. It has been moved to KiCad layer Eco1_User." ),
2561 msg.Printf(
_(
"Footprint %s contains a dashed outline on Altium layer (%d) with "
2562 "no KiCad equivalent. It has been moved to KiCad layer Eco1_User." ),
2584 std::unique_ptr<PCB_SHAPE> shape = std::make_unique<PCB_SHAPE>( aFootprint, SHAPE_T::POLY );
2586 shape->SetPolyShape( linechain );
2587 shape->SetFilled(
false );
2588 shape->SetLayer( klayer );
2590 if( aElem.
kind == ALTIUM_REGION_KIND::DASHED_OUTLINE )
2595 aFootprint->
Add( shape.release(), ADD_MODE::APPEND );
2604 msg.Printf(
_(
"Error loading library '%s':\n"
2605 "Footprint %s contains polygon shape of kind %d (not yet supported)." ),
2617 msg.Printf(
_(
"Footprint %s contains polygon shape of kind %d (not yet supported)." ),
2645 for(
const std::vector<ALTIUM_VERTICE>& hole : aElem.
holes )
2653 polySet.
AddHole( hole_linechain );
2656 std::unique_ptr<PCB_SHAPE> shape = std::make_unique<PCB_SHAPE>(
m_board, SHAPE_T::POLY );
2658 shape->SetPolyShape( polySet );
2659 shape->SetFilled(
true );
2660 shape->SetLayer( aLayer );
2668 m_board->
Add( shape.release(), ADD_MODE::APPEND );
2675 const int aPrimitiveIndex )
2692 for(
const std::vector<ALTIUM_VERTICE>& hole : aElem.
holes )
2700 polySet.
AddHole( hole_linechain );
2703 if( aLayer ==
F_Cu || aLayer ==
B_Cu )
2706 std::unique_ptr<PAD>
pad = std::make_unique<PAD>( aFootprint );
2709 padLayers.
set( aLayer );
2711 pad->SetAttribute( PAD_ATTRIB::SMD );
2720 pad->SetPosition( anchorPos );
2723 shapePolys.
Move( -anchorPos );
2727 auto it = map.find( aPrimitiveIndex );
2729 if( it != map.end() )
2733 if(
info.pastemaskexpansionmode == ALTIUM_MODE::MANUAL )
2735 pad->SetLocalSolderPasteMargin(
2736 info.pastemaskexpansionmanual ?
info.pastemaskexpansionmanual : 1 );
2739 if(
info.soldermaskexpansionmode == ALTIUM_MODE::MANUAL )
2741 pad->SetLocalSolderMaskMargin(
2742 info.soldermaskexpansionmanual ?
info.soldermaskexpansionmanual : 1 );
2745 if(
info.pastemaskexpansionmode != ALTIUM_MODE::NONE )
2748 if(
info.soldermaskexpansionmode != ALTIUM_MODE::NONE )
2752 pad->SetLayerSet( padLayers );
2754 aFootprint->
Add(
pad.release(), ADD_MODE::APPEND );
2758 std::unique_ptr<PCB_SHAPE> shape = std::make_unique<PCB_SHAPE>( aFootprint, SHAPE_T::POLY );
2760 shape->SetPolyShape( polySet );
2761 shape->SetFilled(
true );
2762 shape->SetLayer( aLayer );
2765 aFootprint->
Add( shape.release(), ADD_MODE::APPEND );
2771 const CFB::COMPOUND_FILE_ENTRY* aEntry )
2787 THROW_IO_ERROR( wxString::Format(
"Region stream tries to access polygon id %d "
2788 "of %d existing polygons.",
2795 if( zone ==
nullptr )
2817 for(
const std::vector<ALTIUM_VERTICE>& hole : elem.
holes )
2824 hole_linechain.
Append( hole.at( 0 ).position );
2826 fill.
AddHole( hole_linechain );
2846 const CFB::COMPOUND_FILE_ENTRY* aEntry )
2853 for(
int primitiveIndex = 0; reader.
GetRemainingBytes() >= 4; primitiveIndex++ )
2856 AARC6 elem( reader );
2878 aShape->
SetShape( SHAPE_T::CIRCLE );
2907 THROW_IO_ERROR( wxString::Format(
"Tracks stream tries to access polygon id %u "
2908 "of %zu existing polygons.",
2914 if( zone ==
nullptr )
2962 for(
const auto& layerExpansionMask :
2965 int width = aElem.
width + ( layerExpansionMask.second * 2 );
2969 std::unique_ptr<PCB_SHAPE> arc = std::make_unique<PCB_SHAPE>(
m_board );
2972 arc->SetStroke(
STROKE_PARAMS( width, LINE_STYLE::SOLID ) );
2973 arc->SetLayer( layerExpansionMask.first );
2975 m_board->
Add( arc.release(), ADD_MODE::APPEND );
2982 const int aPrimitiveIndex,
const bool aIsBoardImport )
2986 wxFAIL_MSG( wxString::Format(
"Altium: Unexpected footprint Arc with polygon id %d",
3019 for(
const auto& layerExpansionMask :
3022 int width = aElem.
width + ( layerExpansionMask.second * 2 );
3026 std::unique_ptr<PCB_SHAPE> arc = std::make_unique<PCB_SHAPE>( aFootprint );
3029 arc->SetStroke(
STROKE_PARAMS( width, LINE_STYLE::SOLID ) );
3030 arc->SetLayer( layerExpansionMask.first );
3032 aFootprint->
Add( arc.release(), ADD_MODE::APPEND );
3053 PCB_SHAPE shape(
nullptr, SHAPE_T::ARC );
3062 std::unique_ptr<PCB_ARC> arc = std::make_unique<PCB_ARC>(
m_board, &shapeArc );
3064 arc->SetWidth( aElem.
width );
3065 arc->SetLayer( aLayer );
3068 m_board->
Add( arc.release(), ADD_MODE::APPEND );
3073 std::unique_ptr<PCB_SHAPE> arc = std::make_unique<PCB_SHAPE>(
m_board);
3077 arc->SetLayer( aLayer );
3079 m_board->
Add( arc.release(), ADD_MODE::APPEND );
3087 std::unique_ptr<PCB_SHAPE> arc = std::make_unique<PCB_SHAPE>( aFootprint );
3091 arc->SetLayer( aLayer );
3093 aFootprint->
Add( arc.release(), ADD_MODE::APPEND );
3098 const CFB::COMPOUND_FILE_ENTRY* aEntry )
3108 APAD6 elem( reader );
3130 && aElem.
layer != ALTIUM_LAYER::MULTI_LAYER )
3137 std::unique_ptr<FOOTPRINT> footprint = std::make_unique<FOOTPRINT>(
m_board );
3138 footprint->SetPosition( aElem.
position );
3142 m_board->
Add( footprint.release(), ADD_MODE::APPEND );
3149 std::unique_ptr<PAD>
pad = std::make_unique<PAD>( aFootprint );
3151 pad->SetNumber(
"" );
3157 pad->SetDrillShape( PAD_DRILL_SHAPE::CIRCLE );
3159 pad->SetAttribute( PAD_ATTRIB::PTH );
3162 pad->SetLayerSet(
LSET().AllCuMask() );
3164 if( aElem.
viamode == ALTIUM_PAD_MODE::SIMPLE )
3168 else if( aElem.
viamode == ALTIUM_PAD_MODE::TOP_MIDDLE_BOTTOM )
3189 pad->Padstack().FrontOuterLayers().has_solder_mask =
true;
3193 pad->Padstack().FrontOuterLayers().has_solder_mask =
false;
3199 pad->Padstack().BackOuterLayers().has_solder_mask =
true;
3203 pad->Padstack().BackOuterLayers().has_solder_mask =
false;
3208 pad->SetLocked(
true );
3217 aFootprint->
Add(
pad.release(), ADD_MODE::APPEND );
3225 && aElem.
layer != ALTIUM_LAYER::MULTI_LAYER )
3238 std::unique_ptr<PAD>
pad = std::make_unique<PAD>( aFootprint );
3249 pad->SetAttribute( PAD_ATTRIB::SMD );
3253 if( aElem.
layer != ALTIUM_LAYER::MULTI_LAYER )
3261 msg.Printf(
_(
"Error loading library '%s':\n"
3262 "Footprint %s pad %s is not marked as multilayer, but is a TH pad." ),
3274 msg.Printf(
_(
"Footprint %s pad %s is not marked as multilayer, but is a TH pad." ),
3282 pad->SetAttribute( aElem.
plated ? PAD_ATTRIB::PTH : PAD_ATTRIB::NPTH );
3286 pad->SetDrillShape( PAD_DRILL_SHAPE::CIRCLE );
3293 case ALTIUM_PAD_HOLE_SHAPE::ROUND:
3294 wxFAIL_MSG( wxT(
"Round holes are handled before the switch" ) );
3297 case ALTIUM_PAD_HOLE_SHAPE::SQUARE:
3303 msg.Printf(
_(
"Loading library '%s':\n"
3304 "Footprint %s pad %s has a square hole (not yet supported)." ),
3316 msg.Printf(
_(
"Footprint %s pad %s has a square hole (not yet supported)." ),
3323 pad->SetDrillShape( PAD_DRILL_SHAPE::CIRCLE );
3329 case ALTIUM_PAD_HOLE_SHAPE::SLOT:
3331 pad->SetDrillShape( PAD_DRILL_SHAPE::OBLONG );
3351 msg.Printf(
_(
"Loading library '%s':\n"
3352 "Footprint %s pad %s has a hole-rotation of %f degrees. "
3353 "KiCad only supports 90 degree rotations." ),
3366 msg.Printf(
_(
"Footprint %s pad %s has a hole-rotation of %f degrees. "
3367 "KiCad only supports 90 degree rotations." ),
3380 case ALTIUM_PAD_HOLE_SHAPE::UNKNOWN:
3386 msg.Printf(
_(
"Error loading library '%s':\n"
3387 "Footprint %s pad %s uses a hole of unknown kind %d." ),
3400 msg.Printf(
_(
"Footprint %s pad %s uses a hole of unknown kind %d." ),
3408 pad->SetDrillShape( PAD_DRILL_SHAPE::CIRCLE );
3420 auto setCopperGeometry =
3429 case ALTIUM_PAD_SHAPE::RECT:
3430 ps.
SetShape( PAD_SHAPE::RECTANGLE, aLayer );
3433 case ALTIUM_PAD_SHAPE::CIRCLE:
3435 && aElem.
sizeAndShape->alt_shape[altLayer] == ALTIUM_PAD_SHAPE_ALT::ROUNDRECT )
3437 ps.
SetShape( PAD_SHAPE::ROUNDRECT, aLayer );
3438 double ratio = aElem.
sizeAndShape->cornerradius[altLayer] / 200.;
3443 ps.
SetShape( PAD_SHAPE::CIRCLE, aLayer );
3447 ps.
SetShape( PAD_SHAPE::OVAL, aLayer );
3452 case ALTIUM_PAD_SHAPE::OCTAGONAL:
3453 ps.
SetShape( PAD_SHAPE::CHAMFERED_RECT, aLayer );
3458 case ALTIUM_PAD_SHAPE::UNKNOWN:
3465 msg.Printf(
_(
"Error loading library '%s':\n"
3466 "Footprint %s pad %s uses an unknown pad-shape." ),
3478 msg.Printf(
_(
"Footprint %s pad %s uses an unknown pad-shape." ),
3490 case ALTIUM_PAD_MODE::SIMPLE:
3495 case ALTIUM_PAD_MODE::TOP_MIDDLE_BOTTOM:
3502 case ALTIUM_PAD_MODE::FULL_STACK:
3515 setCopperGeometry( layer, aElem.
sizeAndShape->inner_shape[i],
3525 if(
pad->GetAttribute() == PAD_ATTRIB::NPTH &&
pad->HasHole() )
3529 : PAD_SHAPE::OVAL );
3533 switch( aElem.
layer )
3535 case ALTIUM_LAYER::TOP_LAYER:
3540 case ALTIUM_LAYER::BOTTOM_LAYER:
3545 case ALTIUM_LAYER::MULTI_LAYER:
3551 pad->SetLayer( klayer );
3552 pad->SetLayerSet(
LSET( { klayer } ) );
3563 pad->SetLayerSet(
pad->GetLayerSet().reset(
F_Mask ) );
3566 pad->SetLayerSet(
pad->GetLayerSet().reset(
B_Mask ) );
3568 aFootprint->
Add(
pad.release(), ADD_MODE::APPEND );
3581 msg.Printf(
_(
"Non-copper pad %s found on an Altium layer (%d) with no KiCad "
3582 "equivalent. It has been moved to KiCad layer Eco1_User." ),
3590 std::unique_ptr<PCB_SHAPE>
pad = std::make_unique<PCB_SHAPE>(
m_board );
3609 msg.Printf(
_(
"Loading library '%s':\n"
3610 "Footprint %s non-copper pad %s found on an Altium layer (%d) with no "
3611 "KiCad equivalent. It has been moved to KiCad layer Eco1_User." ),
3624 msg.Printf(
_(
"Footprint %s non-copper pad %s found on an Altium layer (%d) with no "
3625 "KiCad equivalent. It has been moved to KiCad layer Eco1_User." ),
3636 std::unique_ptr<PCB_SHAPE>
pad = std::make_unique<PCB_SHAPE>( aFootprint );
3640 aFootprint->
Add(
pad.release(), ADD_MODE::APPEND );
3652 msg.Printf(
_(
"Non-copper pad %s is connected to a net, which is not supported." ),
3663 msg.Printf(
_(
"Non-copper pad %s has a hole, which is not supported." ), aElem.
name );
3668 if( aElem.
padmode != ALTIUM_PAD_MODE::SIMPLE )
3673 msg.Printf(
_(
"Non-copper pad %s has a complex pad stack (not yet supported)." ),
3681 case ALTIUM_PAD_SHAPE::RECT:
3700 case ALTIUM_PAD_SHAPE::CIRCLE:
3702 && aElem.
sizeAndShape->alt_shape[0] == ALTIUM_PAD_SHAPE_ALT::ROUNDRECT )
3705 int cornerradius = aElem.
sizeAndShape->cornerradius[0];
3706 int offset = ( std::min( aElem.
topsize.
x, aElem.
topsize.
y ) * cornerradius ) / 200;
3711 if( cornerradius < 100 )
3713 int offsetX = aElem.
topsize.
x / 2 - offset;
3714 int offsetY = aElem.
topsize.
y / 2 - offset;
3728 aShape->
SetShape( SHAPE_T::CIRCLE );
3737 aShape->
SetShape( SHAPE_T::SEGMENT );
3745 aShape->
SetShape( SHAPE_T::SEGMENT );
3757 aShape->
SetShape( SHAPE_T::CIRCLE );
3767 aShape->
SetShape( SHAPE_T::SEGMENT );
3770 LINE_STYLE::SOLID ) );
3790 case ALTIUM_PAD_SHAPE::OCTAGONAL:
3807 aShape->
SetPolyPoints( { p11 - chamferX, p11 - chamferY, p12 + chamferY, p12 - chamferX,
3808 p22 + chamferX, p22 + chamferY, p21 - chamferY, p21 + chamferX } );
3815 case ALTIUM_PAD_SHAPE::UNKNOWN:
3820 msg.Printf(
_(
"Non-copper pad %s uses an unknown pad-shape." ), aElem.
name );
3830 const CFB::COMPOUND_FILE_ENTRY* aEntry )
3840 AVIA6 elem( reader );
3842 std::unique_ptr<PCB_VIA>
via = std::make_unique<PCB_VIA>(
m_board );
3849 bool start_layer_outside = elem.
layer_start == ALTIUM_LAYER::TOP_LAYER
3850 || elem.
layer_start == ALTIUM_LAYER::BOTTOM_LAYER;
3851 bool end_layer_outside = elem.
layer_end == ALTIUM_LAYER::TOP_LAYER
3852 || elem.
layer_end == ALTIUM_LAYER::BOTTOM_LAYER;
3854 if( start_layer_outside && end_layer_outside )
3856 via->SetViaType( VIATYPE::THROUGH );
3858 else if( ( !start_layer_outside ) || ( !end_layer_outside ) )
3860 via->SetViaType( VIATYPE::BLIND_BURIED );
3866 via->SetViaType( VIATYPE::MICROVIA );
3877 msg.Printf(
_(
"Via from layer %d to %d uses a non-copper layer, which is not "
3888 via->SetLayerPair( start_klayer, end_klayer );
3893 case ALTIUM_PAD_MODE::SIMPLE:
3897 case ALTIUM_PAD_MODE::TOP_MIDDLE_BOTTOM:
3904 case ALTIUM_PAD_MODE::FULL_STACK:
3911 wxCHECK2_MSG( altiumLayer < 32,
break,
3912 "Altium importer expects 32 or fewer copper layers" );
3923 via->SetFrontTentingMode( elem.
is_tent_top ? TENTING_MODE::TENTED
3924 : TENTING_MODE::NOT_TENTED );
3926 : TENTING_MODE::NOT_TENTED );
3937 const CFB::COMPOUND_FILE_ENTRY* aEntry )
3944 for(
int primitiveIndex = 0; reader.
GetRemainingBytes() >= 4; primitiveIndex++ )
3975 msg.Printf( wxT(
"ATRACK6 stream tries to access polygon id %u "
3976 "of %u existing polygons; skipping it" ),
3977 static_cast<unsigned>( aElem.
polygon ),
3978 static_cast<unsigned>(
m_polygons.size() ) );
3987 if( zone ==
nullptr )
4003 PCB_SHAPE shape(
nullptr, SHAPE_T::SEGMENT );
4021 PCB_SHAPE shape(
nullptr, SHAPE_T::SEGMENT );
4035 ALTIUM_RECORD::TRACK, aPrimitiveIndex, aElem.
layer ) )
4037 int width = aElem.
width + ( layerExpansionMask.second * 2 );
4040 std::unique_ptr<PCB_SHAPE> seg = std::make_unique<PCB_SHAPE>(
m_board, SHAPE_T::SEGMENT );
4042 seg->SetStart( aElem.
start );
4043 seg->SetEnd( aElem.
end );
4044 seg->SetStroke(
STROKE_PARAMS( width, LINE_STYLE::SOLID ) );
4045 seg->SetLayer( layerExpansionMask.first );
4047 m_board->
Add( seg.release(), ADD_MODE::APPEND );
4054 const int aPrimitiveIndex,
4055 const bool aIsBoardImport )
4059 wxFAIL_MSG( wxString::Format(
"Altium: Unexpected footprint Track with polygon id %u",
4068 PCB_SHAPE shape(
nullptr, SHAPE_T::SEGMENT );
4093 ALTIUM_RECORD::TRACK, aPrimitiveIndex, aElem.
layer ) )
4095 int width = aElem.
width + ( layerExpansionMask.second * 2 );
4098 std::unique_ptr<PCB_SHAPE> seg = std::make_unique<PCB_SHAPE>( aFootprint, SHAPE_T::SEGMENT );
4100 seg->SetStart( aElem.
start );
4101 seg->SetEnd( aElem.
end );
4102 seg->SetStroke(
STROKE_PARAMS( width, LINE_STYLE::SOLID ) );
4103 seg->SetLayer( layerExpansionMask.first );
4105 aFootprint->
Add( seg.release(), ADD_MODE::APPEND );
4115 std::unique_ptr<PCB_TRACK> track = std::make_unique<PCB_TRACK>(
m_board );
4117 track->SetStart( aElem.
start );
4118 track->SetEnd( aElem.
end );
4119 track->SetWidth( aElem.
width );
4120 track->SetLayer( aLayer );
4123 m_board->
Add( track.release(), ADD_MODE::APPEND );
4127 std::unique_ptr<PCB_SHAPE> seg = std::make_unique<PCB_SHAPE>(
m_board, SHAPE_T::SEGMENT );
4129 seg->SetStart( aElem.
start );
4130 seg->SetEnd( aElem.
end );
4132 seg->SetLayer( aLayer );
4134 m_board->
Add( seg.release(), ADD_MODE::APPEND );
4142 std::unique_ptr<PCB_SHAPE> seg = std::make_unique<PCB_SHAPE>( aFootprint, SHAPE_T::SEGMENT );
4144 seg->SetStart( aElem.
start );
4145 seg->SetEnd( aElem.
end );
4147 seg->SetLayer( aLayer );
4149 aFootprint->
Add( seg.release(), ADD_MODE::APPEND );
4154 const CFB::COMPOUND_FILE_ENTRY* aEntry )
4164 THROW_IO_ERROR( wxT(
"WideStrings6 stream is not fully parsed" ) );
4168 const CFB::COMPOUND_FILE_ENTRY* aEntry )
4198 if( aElem.
fonttype == ALTIUM_TEXT_TYPE::BARCODE )
4203 msg.Printf(
_(
"Ignored barcode on Altium layer %d (not yet supported)." ),
4218 if( aElem.
fonttype == ALTIUM_TEXT_TYPE::BARCODE )
4225 msg.Printf(
_(
"Error loading library '%s':\n"
4226 "Footprint %s contains barcode on Altium layer %d (not yet supported)." ),
4238 msg.Printf(
_(
"Footprint %s contains barcode on Altium layer %d (not yet supported)." ),
4255 std::unique_ptr<PCB_TEXTBOX> pcbTextbox = std::make_unique<PCB_TEXTBOX>(
m_board );
4256 std::unique_ptr<PCB_TEXT> pcbText = std::make_unique<PCB_TEXT>(
m_board );
4260 static const std::map<wxString, wxString> variableMap = {
4261 {
"LAYER_NAME",
"LAYER" },
4262 {
"PRINT_DATE",
"CURRENT_DATE"},
4272 item = pcbTextbox.get();
4273 text = pcbTextbox.get();
4284 text->SetText( kicadText );
4289 m_board->
Add( pcbTextbox.release(), ADD_MODE::APPEND );
4291 m_board->
Add( pcbText.release(), ADD_MODE::APPEND );
4298 std::unique_ptr<PCB_TEXTBOX> fpTextbox = std::make_unique<PCB_TEXTBOX>( aFootprint );
4299 std::unique_ptr<PCB_TEXT> fpText = std::make_unique<PCB_TEXT>( aFootprint );
4316 item = &aFootprint->
Value();
4318 field = &aFootprint->
Value();
4322 item = fpText.get();
4323 text = fpText.get();
4327 static const std::map<wxString, wxString> variableMap = {
4328 {
"DESIGNATOR",
"REFERENCE" },
4329 {
"COMMENT",
"VALUE" },
4330 {
"VALUE",
"ALTIUM_VALUE" },
4331 {
"LAYER_NAME",
"LAYER" },
4332 {
"PRINT_DATE",
"CURRENT_DATE"},
4337 item = fpTextbox.get();
4338 text = fpTextbox.get();
4351 text->SetText( kicadText );
4352 text->SetKeepUpright(
false );
4359 aFootprint->
Add( fpTextbox.release(), ADD_MODE::APPEND );
4361 aFootprint->
Add( fpText.release(), ADD_MODE::APPEND );
4389 kicadMargin =
VECTOR2I( charWidth * 0.933, charHeight * 0.67 );
4391 kicadMargin =
VECTOR2I( charWidth * 0.808, charHeight * 0.844 );
4394 + kicadMargin * 2 - margin * 2 );
4396 kposition = kposition - kicadMargin + margin;
4412 : ALTIUM_TEXT_POSITION::LEFT_BOTTOM;
4414 switch( justification )
4416 case ALTIUM_TEXT_POSITION::LEFT_TOP:
4417 case ALTIUM_TEXT_POSITION::LEFT_CENTER:
4418 case ALTIUM_TEXT_POSITION::LEFT_BOTTOM:
4422 case ALTIUM_TEXT_POSITION::CENTER_TOP:
4423 case ALTIUM_TEXT_POSITION::CENTER_CENTER:
4424 case ALTIUM_TEXT_POSITION::CENTER_BOTTOM:
4428 case ALTIUM_TEXT_POSITION::RIGHT_TOP:
4429 case ALTIUM_TEXT_POSITION::RIGHT_CENTER:
4430 case ALTIUM_TEXT_POSITION::RIGHT_BOTTOM:
4438 msg.Printf(
_(
"Unknown textbox justification %d, aText %s" ), justification,
4458 int rectHeight = aElem.
height;
4461 rectWidth = -rectWidth;
4465 : ALTIUM_TEXT_POSITION::LEFT_BOTTOM;
4467 switch( justification )
4469 case ALTIUM_TEXT_POSITION::LEFT_TOP:
4473 kposition.
y -= rectHeight;
4475 case ALTIUM_TEXT_POSITION::LEFT_CENTER:
4479 kposition.
y -= rectHeight / 2;
4481 case ALTIUM_TEXT_POSITION::LEFT_BOTTOM:
4485 case ALTIUM_TEXT_POSITION::CENTER_TOP:
4489 kposition.
x += rectWidth / 2;
4490 kposition.
y -= rectHeight;
4492 case ALTIUM_TEXT_POSITION::CENTER_CENTER:
4496 kposition.
x += rectWidth / 2;
4497 kposition.
y -= rectHeight / 2;
4499 case ALTIUM_TEXT_POSITION::CENTER_BOTTOM:
4503 kposition.
x += rectWidth / 2;
4505 case ALTIUM_TEXT_POSITION::RIGHT_TOP:
4509 kposition.
x += rectWidth;
4510 kposition.
y -= rectHeight;
4512 case ALTIUM_TEXT_POSITION::RIGHT_CENTER:
4516 kposition.
x += rectWidth;
4517 kposition.
y -= rectHeight / 2;
4519 case ALTIUM_TEXT_POSITION::RIGHT_BOTTOM:
4523 kposition.
x += rectWidth;
4568 if( aElem.
fonttype == ALTIUM_TEXT_TYPE::TRUETYPE )
4576 if( font->
GetName().Contains( wxS(
"Arial" ) ) )
4591 const CFB::COMPOUND_FILE_ENTRY* aEntry )
4624 PCB_SHAPE shape(
nullptr, SHAPE_T::RECTANGLE );
4649 const bool aIsBoardImport )
4652 || aElem.
layer == ALTIUM_LAYER::KEEP_OUT_LAYER )
4655 PCB_SHAPE shape(
nullptr, SHAPE_T::RECTANGLE );
4689 std::unique_ptr<PCB_SHAPE> fill = std::make_unique<PCB_SHAPE>(
m_board, SHAPE_T::RECTANGLE );
4691 fill->SetFilled(
true );
4692 fill->SetLayer( aLayer );
4695 fill->SetStart( aElem.
pos1 );
4696 fill->SetEnd( aElem.
pos2 );
4711 m_board->
Add( fill.release(), ADD_MODE::APPEND );
4718 if( aLayer ==
F_Cu || aLayer ==
B_Cu )
4720 std::unique_ptr<PAD>
pad = std::make_unique<PAD>( aFootprint );
4723 padLayers.
set( aLayer );
4725 pad->SetAttribute( PAD_ATTRIB::SMD );
4738 std::swap( width, height );
4741 pad->SetPosition( aElem.
pos1 / 2 + aElem.
pos2 / 2 );
4753 pad->SetPosition( anchorPos );
4764 aElem.
pos1.
y / 2 + aElem.
pos2.
y / 2 - anchorPos.
y );
4766 pad->AddPrimitivePoly(
F_Cu, shapePolys, 0,
true );
4770 pad->SetLayerSet( padLayers );
4772 aFootprint->
Add(
pad.release(), ADD_MODE::APPEND );
4776 std::unique_ptr<PCB_SHAPE> fill =
4777 std::make_unique<PCB_SHAPE>( aFootprint, SHAPE_T::RECTANGLE );
4779 fill->SetFilled(
true );
4780 fill->SetLayer( aLayer );
4783 fill->SetStart( aElem.
pos1 );
4784 fill->SetEnd( aElem.
pos2 );
4793 aFootprint->
Add( fill.release(), ADD_MODE::APPEND );
4803 layerSet.
set( klayer );
4811 bool keepoutRestrictionVia = ( aKeepoutRestrictions & 0x01 ) != 0;
4812 bool keepoutRestrictionTrack = ( aKeepoutRestrictions & 0x02 ) != 0;
4813 bool keepoutRestrictionCopper = ( aKeepoutRestrictions & 0x04 ) != 0;
4814 bool keepoutRestrictionSMDPad = ( aKeepoutRestrictions & 0x08 ) != 0;
4815 bool keepoutRestrictionTHPad = ( aKeepoutRestrictions & 0x10 ) != 0;
4827 const uint8_t aKeepoutRestrictions )
4829 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>(
m_board );
4831 zone->SetIsRuleArea(
true );
4838 zone->SetBorderDisplayStyle( ZONE_BORDER_DISPLAY_STYLE::DIAGONAL_EDGE,
4841 m_board->
Add( zone.release(), ADD_MODE::APPEND );
4848 const uint8_t aKeepoutRestrictions )
4850 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>( aFootprint );
4852 zone->SetIsRuleArea(
true );
4859 zone->SetBorderDisplayStyle( ZONE_BORDER_DISPLAY_STYLE::DIAGONAL_EDGE,
4863 aFootprint->
Add( zone.release(), ADD_MODE::APPEND );
4876 if( elems.first == elems.second )
4879 std::vector<std::pair<PCB_LAYER_ID, int>> layerExpansionPairs;
4881 for(
auto it = elems.first; it != elems.second; ++it )
4885 if( pInf.
type == AEXTENDED_PRIMITIVE_INFORMATION_TYPE::MASK )
4891 if( aAltiumLayer == ALTIUM_LAYER::TOP_LAYER
4892 || aAltiumLayer == ALTIUM_LAYER::MULTI_LAYER )
4897 if( aAltiumLayer == ALTIUM_LAYER::BOTTOM_LAYER
4898 || aAltiumLayer == ALTIUM_LAYER::MULTI_LAYER )
4906 if( aAltiumLayer == ALTIUM_LAYER::TOP_LAYER
4907 || aAltiumLayer == ALTIUM_LAYER::MULTI_LAYER )
4912 if( aAltiumLayer == ALTIUM_LAYER::BOTTOM_LAYER
4913 || aAltiumLayer == ALTIUM_LAYER::MULTI_LAYER )
4921 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
void SetAuxOrigin(const VECTOR2I &aOrigin)
const VECTOR2I & GetAuxOrigin() const
int m_SolderMaskExpansion
BOARD_STACKUP & GetStackupDescriptor()
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.
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
void BuildDefaultStackupList(const BOARD_DESIGN_SETTINGS *aSettings, int aActiveCopperLayersCount=0)
Create a default stackup, according to the current BOARD_DESIGN_SETTINGS settings.
Information pertinent to a Pcbnew printed circuit board.
LSET GetEnabledLayers() const
A proxy function that calls the corresponding function in m_BoardSettings.
void 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
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 LSET AllBoardTechMask()
Return a mask holding board technical layers (no CU layer) on both side.
static LSET UserDefinedLayersMask(int aUserDefinedLayerCount=MAX_USER_DEFINED_LAYERS)
Return a mask with the requested number of user defined layers.
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)=0
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.
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).
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