45#include <compoundfilereader.h>
50#include <wx/docview.h>
52#include <wx/mstream.h>
53#include <wx/wfstream.h>
54#include <wx/zstream.h>
78 "of %d existing components" ),
98 "id %d of %d existing components" ),
160 const std::vector<ALTIUM_VERTICE>& aVertices )
169 double startradiant =
DEG2RAD( vertex.startangle );
170 double endradiant =
DEG2RAD( vertex.endangle );
172 -
KiROUND( std::sin( startradiant ) * vertex.radius ) );
175 -
KiROUND( std::sin( endradiant ) * vertex.radius ) );
177 VECTOR2I arcStart = vertex.center + arcStartOffset;
178 VECTOR2I arcEnd = vertex.center + arcEndOffset;
192 aLine.
Append( vertex.position );
202 auto override =
m_layermap.find( aAltiumLayer );
206 return override->second;
209 switch( aAltiumLayer )
308 static std::set<ALTIUM_LAYER> altiumLayersWithWarning;
312 std::vector<PCB_LAYER_ID> layers;
315 layer =
static_cast<PCB_LAYER_ID>(
static_cast<int>( layer ) + 1 ) )
317 layers.emplace_back( layer );
327 wxLogWarning(
_(
"Altium layer (%d) has no KiCad equivalent. It has been moved to KiCad "
328 "layer Eco1_User." ),
353 const unsigned PROGRESS_DELTA = 250;
371 const std::map<ALTIUM_PCB_DIR, std::string>& aFileMapping )
374 const std::vector<std::tuple<bool, ALTIUM_PCB_DIR, PARSE_FUNCTION_POINTER_fp>> parserOrder = {
486 for(
const std::tuple<bool, ALTIUM_PCB_DIR, PARSE_FUNCTION_POINTER_fp>& cur : parserOrder )
491 std::tie( isRequired,
directory, fp ) = cur;
496 const auto& mappedDirectory = aFileMapping.find(
directory );
498 if( mappedDirectory == aFileMapping.end() )
501 const std::vector<std::string> mappedFile{ mappedDirectory->second,
"Header" };
502 const CFB::COMPOUND_FILE_ENTRY* file = altiumPcbFile.
FindStream( mappedFile );
504 if( file ==
nullptr )
508 uint32_t numOfRecords = reader.
Read<uint32_t>();
512 wxLogError(
_(
"'%s' was not parsed correctly." ),
FormatPath( mappedFile ) );
520 wxLogError(
_(
"'%s' was not fully parsed." ),
FormatPath( mappedFile ) );
527 for(
const std::tuple<bool, ALTIUM_PCB_DIR, PARSE_FUNCTION_POINTER_fp>& cur : parserOrder )
532 std::tie( isRequired,
directory, fp ) = cur;
534 const auto& mappedDirectory = aFileMapping.find(
directory );
536 if( mappedDirectory == aFileMapping.end() )
538 wxASSERT_MSG( !isRequired,
wxString::Format( wxT(
"Altium Directory of kind %d was "
539 "expected, but no mapping is "
540 "present in the code" ),
545 std::vector<std::string> mappedFile{ mappedDirectory->second };
548 mappedFile.emplace_back(
"Data" );
550 const CFB::COMPOUND_FILE_ENTRY* file = altiumPcbFile.
FindStream( mappedFile );
552 if( file !=
nullptr )
553 fp( altiumPcbFile, file );
554 else if( isRequired )
555 wxLogError(
_(
"File not found: '%s'." ),
FormatPath( mappedFile ) );
565 if( zone->GetAssignedPriority() == 1000 )
576 zone->SetAssignedPriority( priority >= 0 ? priority : 0 );
580 for( std::pair<const ALTIUM_LAYER, ZONE*>& zone :
m_outer_plane )
581 zone.second->SetAssignedPriority( 0 );
617 if( arc->
GetCenter() == dim->GetPosition() )
626 VECTOR2I radialLine = dim->GetEnd() - dim->GetStart();
631 radialLine = radialLine.
Resize( std::max( radius, 2 ) );
632 dim->SetEnd( dim->GetStart() + (
VECTOR2I) radialLine );
633 dim->SetLeaderLength( totalLength - radius );
643 int desired_x = ( w - bbbox.
GetWidth() ) / 2;
644 int desired_y = ( h - bbbox.
GetHeight() ) / 2;
646 VECTOR2I movementVector( desired_x - bbbox.
GetX(), desired_y - bbbox.
GetY() );
658 const wxString& aFootprintName )
660 std::unique_ptr<FOOTPRINT> footprint = std::make_unique<FOOTPRINT>(
m_board );
677 const std::vector<std::string> streamName{ aFootprintName.ToStdString(),
"Data" };
678 const CFB::COMPOUND_FILE_ENTRY* footprintData = altiumLibFile.
FindStream( streamName );
680 if( footprintData ==
nullptr )
693 footprint->SetFPID( fpID );
695 const std::vector<std::string> parametersStreamName{ aFootprintName.ToStdString(),
697 const CFB::COMPOUND_FILE_ENTRY* parametersData =
698 altiumLibFile.
FindStream( parametersStreamName );
700 if( parametersData !=
nullptr )
702 ALTIUM_PARSER parametersReader( altiumLibFile, parametersData );
703 std::map<wxString, wxString> parameterProperties = parametersReader.
ReadProperties();
705 wxT(
"DESCRIPTION" ),
707 footprint->SetDescription( description );
711 wxLogError(
_(
"File not found: '%s'." ),
FormatPath( parametersStreamName ) );
712 footprint->SetDescription( wxT(
"" ) );
715 const std::vector<std::string> extendedPrimitiveInformationStreamName{
716 aFootprintName.ToStdString(),
"ExtendedPrimitiveInformation",
"Data"
718 const CFB::COMPOUND_FILE_ENTRY* extendedPrimitiveInformationData =
719 altiumLibFile.
FindStream( extendedPrimitiveInformationStreamName );
721 if( extendedPrimitiveInformationData !=
nullptr )
724 footprint->SetReference( wxT(
"REF**" ) );
725 footprint->SetValue( footprintName );
726 footprint->Reference().SetVisible(
true );
727 footprint->Value().SetVisible(
true );
800 return footprint.release();
823 const auto rules =
m_rules.find( aKind );
828 for(
const ARULE6& rule : rules->second )
830 if( rule.
name == aName )
839 const auto rules =
m_rules.find( aKind );
844 for(
const ARULE6& rule : rules->second )
854 const CFB::COMPOUND_FILE_ENTRY* aEntry )
871 const CFB::COMPOUND_FILE_ENTRY* aEntry )
888 THROW_IO_ERROR( wxT(
"ExtendedPrimitiveInformation stream is not fully parsed" ) );
892 const CFB::COMPOUND_FILE_ENTRY* aEntry )
909 size_t layercount = 0;
912 while( layerid < elem.
stackup.size() && layerid != 0 )
914 layerid = elem.
stackup[ layerid - 1 ].nextId;
918 size_t kicadLayercount = ( layercount % 2 == 0 ) ? layercount : layercount + 1;
928 auto it = stackup.
GetList().begin();
934 auto curLayer =
static_cast<int>(
F_Cu );
937 altiumLayerId < elem.
stackup.size() && altiumLayerId != 0;
938 altiumLayerId = elem.
stackup[altiumLayerId - 1].nextId )
944 if( layer.
nextId == 0 && layercount != kicadLayercount )
949 THROW_IO_ERROR( wxT(
"Board6 stream, unexpected item while parsing stackup" ) );
951 ( *it )->SetThickness( 0 );
956 THROW_IO_ERROR( wxT(
"Board6 stream, unexpected item while parsing stackup" ) );
958 ( *it )->SetThickness( 0, 0 );
959 ( *it )->SetThicknessLocked(
true, 0 );
967 THROW_IO_ERROR( wxT(
"Board6 stream, unexpected item while parsing stackup" ) );
984 THROW_IO_ERROR( wxT(
"Board6 stream, unexpected id while parsing last stackup layer" ) );
994 THROW_IO_ERROR( wxT(
"Board6 stream, unexpected item while parsing stackup" ) );
1046 int nextShape = lineChain.
NextShape( i );
1047 bool isLastShape = nextShape < 0;
1072 const CFB::COMPOUND_FILE_ENTRY* aEntry )
1086 std::shared_ptr<NETCLASS> nc = std::make_shared<NETCLASS>( elem.
name );
1088 for(
const wxString&
name : elem.
names )
1117 const CFB::COMPOUND_FILE_ENTRY* aEntry )
1124 uint16_t componentId = 0;
1146 if( reference.find_first_not_of(
"0123456789" ) == wxString::npos )
1147 reference.Prepend( wxT(
"UNK" ) );
1160 THROW_IO_ERROR( wxT(
"Components6 stream is not fully parsed" ) );
1167 while( Angle < aMin )
1170 while( Angle >= aMax )
1178 const CFB::COMPOUND_FILE_ENTRY* aEntry )
1196 "component id %d of %d existing components" ),
1208 wxLogError( wxT(
"ComponentsBodies6 stream tries to access model id %s which does not "
1219 modelSettings.
m_Filename = modelTuple->second;
1230 orientation = -orientation;
1243 footprint->
Models().push_back( modelSettings );
1247 THROW_IO_ERROR( wxT(
"ComponentsBodies6 stream is not fully parsed" ) );
1254 THROW_IO_ERROR( wxT(
"Incorrect number of reference points for linear dimension object" ) );
1260 wxLogWarning(
_(
"Dimension found on an Altium layer (%d) with no KiCad equivalent. "
1261 "It has been moved to KiCad layer Eco1_User." ),
1274 dimension->
SetStart( referencePoint0 );
1276 if( referencePoint0 != aElem.
xy1 )
1289 SEG segm1( referencePoint0, referencePoint0 + directionNormalVector );
1290 SEG segm2( referencePoint1, referencePoint1 + direction );
1294 THROW_IO_ERROR( wxT(
"Invalid dimension. This should never happen." ) );
1296 dimension->
SetEnd( *intersection );
1298 int height =
static_cast<int>(
EuclideanNorm( direction ) );
1300 if( direction.
x <= 0 && direction.
y <= 0 )
1307 dimension->
SetEnd( referencePoint1 );
1350 THROW_IO_ERROR( wxT(
"Not enough reference points for radial dimension object" ) );
1356 wxLogWarning(
_(
"Dimension found on an Altium layer (%d) with no KiCad equivalent. "
1357 "It has been moved to KiCad layer Eco1_User." ),
1371 dimension->
SetStart( referencePoint0 );
1400 wxLogError( wxT(
"No text position present for leader dimension object" ) );
1433 wxLogWarning(
_(
"Dimension found on an Altium layer (%d) with no KiCad equivalent. "
1434 "It has been moved to KiCad layer Eco1_User." ),
1461 if( dirVec.
x != 0 || dirVec.
y != 0 )
1472 shape1->
SetStart( referencePoint0 );
1473 shape1->
SetEnd( referencePoint0 + arrVec );
1481 shape2->
SetStart( referencePoint0 );
1482 shape2->
SetEnd( referencePoint0 + arrVec );
1489 wxLogError( wxT(
"No text position present for leader dimension object" ) );
1497 text->SetLayer( klayer );
1511 wxLogWarning(
_(
"Dimension found on an Altium layer (%d) with no KiCad equivalent. "
1512 "It has been moved to KiCad layer Eco1_User." ),
1535 wxLogWarning(
_(
"Dimension found on an Altium layer (%d) with no KiCad equivalent. "
1536 "It has been moved to KiCad layer Eco1_User." ),
1554 const CFB::COMPOUND_FILE_ENTRY* aEntry )
1578 wxLogError(
_(
"Ignored dimension of kind %d (not yet supported)." ), elem.
kind );
1585 wxLogError(
_(
"Ignored dimension of kind %d (not yet supported)." ), elem.
kind );
1591 THROW_IO_ERROR( wxT(
"Dimensions6 stream is not fully parsed" ) );
1596 const CFB::COMPOUND_FILE_ENTRY* aEntry,
1597 const std::vector<std::string>& aRootDir )
1612 const wxString altiumModelDir = wxT(
"ALTIUM_EMBEDDED_MODELS" );
1614 wxFileName altiumModelsPath = wxFileName::DirName( projectPath );
1615 wxString kicadModelPrefix = wxT(
"${KIPRJMOD}/" ) + altiumModelDir + wxT(
"/" );
1617 if( !altiumModelsPath.AppendDir( altiumModelDir ) )
1618 THROW_IO_ERROR( wxT(
"Cannot construct directory path for step models" ) );
1621 if( !altiumModelsPath.DirExists() )
1623 if( !altiumModelsPath.Mkdir() )
1625 wxLogError(
_(
"Failed to create folder '%s'." ) + wxS(
" " )
1626 +
_(
"No 3D-models will be imported." ),
1627 altiumModelsPath.GetFullPath() );
1633 wxString invalidChars = wxFileName::GetForbiddenChars();
1640 std::vector<std::string> stepPath = aRootDir;
1641 stepPath.emplace_back( std::to_string( idx ) );
1643 bool validName = !elem.
name.IsEmpty() && elem.
name.IsAscii() &&
1644 wxString::npos == elem.
name.find_first_of( invalidChars );
1645 wxString storageName = !validName ?
wxString::Format( wxT(
"model_%d" ), idx )
1647 wxFileName storagePath( altiumModelsPath.GetPath(), storageName );
1651 const CFB::COMPOUND_FILE_ENTRY* stepEntry = aAltiumPcbFile.
FindStream( stepPath );
1653 if( stepEntry ==
nullptr )
1655 wxLogError(
_(
"File not found: '%s'. 3D-model not imported." ),
1660 size_t stepSize =
static_cast<size_t>( stepEntry->size );
1661 std::vector<char> stepContent( stepSize );
1667 if( !storagePath.IsDirWritable() )
1669 wxLogError(
_(
"Insufficient permissions to save file '%s'." ),
1670 storagePath.GetFullPath() );
1674 wxMemoryInputStream stepStream( stepContent.data(), stepSize );
1675 wxZlibInputStream zlibInputStream( stepStream );
1677 wxFFileOutputStream outputStream( storagePath.GetFullPath() );
1678 outputStream.Write( zlibInputStream );
1679 outputStream.Close();
1681 m_models.insert( { elem.
id, kicadModelPrefix + storageName } );
1690 const CFB::COMPOUND_FILE_ENTRY* aEntry )
1701 ANET6 elem( reader );
1714 const CFB::COMPOUND_FILE_ENTRY* aEntry )
1762 if( clearanceRule !=
nullptr )
1767 if( polygonConnectRule !=
nullptr )
1838 const CFB::COMPOUND_FILE_ENTRY* aEntry )
1856 std::sort( val.second.begin(), val.second.end(),
1859 return lhs.priority < rhs.priority;
1868 const CFB::COMPOUND_FILE_ENTRY* aEntry )
1884 THROW_IO_ERROR( wxT(
"BoardRegions stream is not fully parsed" ) );
1888 const CFB::COMPOUND_FILE_ENTRY* aEntry )
1914 THROW_IO_ERROR(
"ShapeBasedRegions6 stream is not fully parsed" );
1964 wxLogError(
_(
"Ignored polygon shape of kind %d (not yet supported)." ), aElem.
kind );
2010 wxLogError(
_(
"Ignored polygon shape of kind %d (not yet supported)." ), aElem.
kind );
2068 const CFB::COMPOUND_FILE_ENTRY* aEntry )
2091 "of %d existing polygons.",
2098 if( zone ==
nullptr )
2120 for(
const std::vector<ALTIUM_VERTICE>& hole : elem.
holes )
2127 hole_linechain.
Append( hole.at( 0 ).position );
2129 fill.
AddHole( hole_linechain );
2149 const CFB::COMPOUND_FILE_ENTRY* aEntry )
2156 for(
int primitiveIndex = 0; reader.
GetRemainingBytes() >= 4; primitiveIndex++ )
2159 AARC6 elem( reader );
2226 for(
const auto layerExpansionMask :
2229 int width = aElem.
width + ( layerExpansionMask.second * 2 );
2237 arc->
SetLayer( layerExpansionMask.first );
2246 const int aPrimitiveIndex,
const bool aIsBoardImport )
2279 for(
const auto layerExpansionMask :
2282 int width = aElem.
width + ( layerExpansionMask.second * 2 );
2290 arc->
SetLayer( layerExpansionMask.first );
2354 const CFB::COMPOUND_FILE_ENTRY* aEntry )
2364 APAD6 elem( reader );
2422 pad->SetKeepTopBottom(
false );
2429 pad->SetLocalCoord();
2442 wxLogError(
_(
"Footprint %s pad %s is not marked as multilayer, but is a TH pad." ),
2459 wxFAIL_MSG( wxT(
"Round holes are handled before the switch" ) );
2463 wxLogWarning(
_(
"Footprint %s pad %s has a square hole (not yet supported)." ),
2490 wxLogWarning(
_(
"Footprint %s pad %s has a hole-rotation of %f degrees. "
2491 "KiCad only supports 90 degree rotations." ),
2502 wxLogError(
_(
"Footprint %s pad %s uses a hole of unknown kind %d." ),
2519 wxLogError(
_(
"Footprint %s pad %s uses a complex pad stack (not yet supported.)" ),
2534 double ratio = aElem.
sizeAndShape->cornerradius[0] / 200.;
2535 pad->SetRoundRectRadiusRatio( ratio );
2551 pad->SetChamferRectRatio( 0.25 );
2556 wxLogError(
_(
"Footprint %s pad %s uses an unknown pad-shape." ),
2566 pad->SetSize(
pad->GetDrillSize() );
2569 switch( aElem.
layer )
2587 pad->SetLayer( klayer );
2588 pad->SetLayerSet(
LSET( 1, klayer ) );
2599 pad->SetLayerSet(
pad->GetLayerSet().reset(
F_Mask ) );
2602 pad->SetLayerSet(
pad->GetLayerSet().reset(
B_Mask ) );
2614 wxLogWarning(
_(
"Non-copper pad %s found on an Altium layer (%d) with no KiCad "
2615 "equivalent. It has been moved to KiCad layer Eco1_User." ),
2635 _(
"Non-copper pad %s found on an Altium layer (%d) with no KiCad equivalent. "
2636 "It has been moved to KiCad layer Eco1_User." ),
2655 wxLogError(
_(
"Non-copper pad %s is connected to a net, which is not supported." ),
2661 wxLogError(
_(
"Non-copper pad %s has a hole, which is not supported." ), aElem.
name );
2666 wxLogWarning(
_(
"Non-copper pad %s has a complex pad stack (not yet supported)." ),
2696 int cornerradius = aElem.
sizeAndShape->cornerradius[0];
2697 int offset = ( std::min( aElem.
topsize.
x, aElem.
topsize.
y ) * cornerradius ) / 200;
2702 if( cornerradius < 100 )
2704 int offsetX = aElem.
topsize.
x / 2 - offset;
2705 int offsetY = aElem.
topsize.
y / 2 - offset;
2798 aShape->
SetPolyPoints( { p11 - chamferX, p11 - chamferY, p12 + chamferY, p12 - chamferX,
2799 p22 + chamferX, p22 + chamferY, p21 - chamferY, p21 + chamferX } );
2808 wxLogError(
_(
"Non-copper pad %s uses an unknown pad-shape." ), aElem.
name );
2815 const CFB::COMPOUND_FILE_ENTRY* aEntry )
2825 AVIA6 elem( reader );
2841 if( start_layer_outside && end_layer_outside )
2845 else if( ( !start_layer_outside ) && ( !end_layer_outside ) )
2859 wxLogError(
_(
"Via from layer %d to %d uses a non-copper layer, which is not "
2867 via->SetLayerPair( start_klayer, end_klayer );
2875 const CFB::COMPOUND_FILE_ENTRY* aEntry )
2882 for(
int primitiveIndex = 0; reader.
GetRemainingBytes() >= 4; primitiveIndex++ )
2930 int width = aElem.
width + ( layerExpansionMask.second * 2 );
2938 seg->
SetLayer( layerExpansionMask.first );
2947 const int aPrimitiveIndex,
2948 const bool aIsBoardImport )
2984 int width = aElem.
width + ( layerExpansionMask.second * 2 );
2992 seg->
SetLayer( layerExpansionMask.first );
3045 const CFB::COMPOUND_FILE_ENTRY* aEntry )
3055 THROW_IO_ERROR( wxT(
"WideStrings6 stream is not fully parsed" ) );
3059 const CFB::COMPOUND_FILE_ENTRY* aEntry )
3091 wxLogError(
_(
"Ignored barcode on Altium layer %d (not yet supported)." ), aElem.
layer );
3104 wxLogError(
_(
"Ignored barcode on Altium layer %d (not yet supported)." ), aElem.
layer );
3118 wxString trimmedText = aElem.
text;
3121 if( trimmedText.CmpNoCase( wxT(
".Layer_Name" ) ) == 0 )
3122 pcbText->
SetText( wxT(
"${LAYER}" ) );
3146 fpText = &aFootprint->
Value();
3150 fpText =
new FP_TEXT( aFootprint );
3155 wxString trimmedText = aElem.
text;
3158 if( !aElem.
isDesignator && trimmedText.CmpNoCase( wxT(
".Designator" ) ) == 0 )
3159 fpText->
SetText( wxT(
"${REFERENCE}" ) );
3160 else if( !aElem.
isComment && trimmedText.CmpNoCase( wxT(
".Comment" ) ) == 0 )
3161 fpText->
SetText( wxT(
"${VALUE}" ) );
3162 else if( trimmedText.CmpNoCase( wxT(
".Layer_Name" ) ) == 0 )
3163 fpText->
SetText( wxT(
"${LAYER}" ) );
3220 wxLogError( wxT(
"Unexpected horizontal Text Position. This should never happen." ) );
3242 wxLogError( wxT(
"Unexpected vertical text position. This should never happen." ) );
3250 const CFB::COMPOUND_FILE_ENTRY* aEntry )
3294 const bool aIsBoardImport )
3348 const int outlineIdx = -1;
3430 layerSet.set( klayer );
3439 bool keepoutRestrictionVia = ( aKeepoutRestrictions & 0x01 ) != 0;
3440 bool keepoutRestrictionTrack = ( aKeepoutRestrictions & 0x02 ) != 0;
3441 bool keepoutRestrictionCopper = ( aKeepoutRestrictions & 0x04 ) != 0;
3442 bool keepoutRestrictionSMDPad = ( aKeepoutRestrictions & 0x08 ) != 0;
3443 bool keepoutRestrictionTHPad = ( aKeepoutRestrictions & 0x10 ) != 0;
3448 aZone->
SetDoNotAllowPads( keepoutRestrictionSMDPad && keepoutRestrictionTHPad );
3455 const uint8_t aKeepoutRestrictions )
3476 const uint8_t aKeepoutRestrictions )
3504 if( elems.first == elems.second )
3507 std::vector<std::pair<PCB_LAYER_ID, int>> layerExpansionPairs;
3509 for(
auto it = elems.first; it != elems.second; ++it )
3549 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 int ALTIUM_COMPONENT_NONE
LIB_ID AltiumToKiCadLibID(const wxString &aLibName, const wxString &aLibReference)
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_COMPOUND_FILE &, const CFB::COMPOUND_FILE_ENTRY *)> PARSE_FUNCTION_POINTER_fp
@ EXTENDPRIMITIVEINFORMATION
constexpr int ARC_HIGH_DEF
constexpr EDA_IU_SCALE pcbIUScale
@ BS_ITEM_TYPE_DIELECTRIC
const CFB::CompoundFileReader & GetCompoundFileReader() const
const CFB::COMPOUND_FILE_ENTRY * FindStream(const std::vector< std::string > &aStreamPath) const
size_t GetRemainingBytes() const
std::map< wxString, wxString > ReadProperties()
static wxString ReadString(const std::map< wxString, wxString > &aProps, const wxString &aKey, const wxString &aDefault)
std::map< uint32_t, wxString > ReadWideStringTable()
size_t ReadAndSetSubrecordLength()
void ParseFileHeader(const ALTIUM_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry)
PROGRESS_REPORTER * m_progressReporter
optional; may be nullptr
void HelperSetZoneLayers(ZONE *aZone, const ALTIUM_LAYER aAltiumLayer)
void ParseShapeBasedRegions6Data(const ALTIUM_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 HelperParseDimensions6Leader(const ADIMENSION6 &aElem)
std::vector< FOOTPRINT * > m_components
const ARULE6 * GetRuleDefault(ALTIUM_RULE_KIND aKind) const
void HelperParsePad6NonCopper(const APAD6 &aElem, PCB_LAYER_ID aLayer, PCB_SHAPE *aShape)
std::vector< PCB_LAYER_ID > GetKicadLayersToIterate(ALTIUM_LAYER aAltiumLayer) const
void ParseRegions6Data(const ALTIUM_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry)
void ParseBoard6Data(const ALTIUM_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry)
void ParseComponentsBodies6Data(const ALTIUM_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry)
void HelperPcpShapeAsFootprintKeepoutRegion(FOOTPRINT *aFootprint, const PCB_SHAPE &aShape, const ALTIUM_LAYER aAltiumLayer, const uint8_t aKeepoutRestrictions)
void ParseFills6Data(const ALTIUM_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry)
void Parse(const ALTIUM_COMPOUND_FILE &aAltiumPcbFile, const std::map< ALTIUM_PCB_DIR, std::string > &aFileMapping)
void ParseBoardRegionsData(const ALTIUM_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry)
void ConvertArcs6ToBoardItem(const AARC6 &aElem, const int aPrimitiveIndex)
std::map< ALTIUM_LAYER, ZONE * > m_outer_plane
std::vector< int > m_altiumToKicadNetcodes
ALTIUM_PCB(BOARD *aBoard, PROGRESS_REPORTER *aProgressReporter)
unsigned m_totalCount
for progress reporting
void HelperPcpShapeAsBoardKeepoutRegion(const PCB_SHAPE &aShape, const ALTIUM_LAYER aAltiumLayer, const uint8_t aKeepoutRestrictions)
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 ConvertFills6ToFootprintItem(FOOTPRINT *aFootprint, const AFILL6 &aElem, const bool aIsBoardImport)
void ConvertShapeBasedRegions6ToFootprintItemOnLayer(FOOTPRINT *aFootprint, const AREGION6 &aElem, PCB_LAYER_ID aLayer)
void ConvertShapeBasedRegions6ToBoardItem(const AREGION6 &aElem)
void HelperCreateBoardOutline(const std::vector< ALTIUM_VERTICE > &aVertices)
FOOTPRINT * ParseFootprint(const ALTIUM_COMPOUND_FILE &altiumLibFile, const wxString &aFootprintName)
void ParseVias6Data(const ALTIUM_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry)
std::map< ALTIUM_RULE_KIND, std::vector< ARULE6 > > m_rules
void ParseClasses6Data(const ALTIUM_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry)
void HelperParseDimensions6Linear(const ADIMENSION6 &aElem)
std::map< uint32_t, wxString > m_unicodeStrings
void ConvertTexts6ToBoardItem(const ATEXT6 &aElem)
void ParseArcs6Data(const ALTIUM_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry)
void HelperParseDimensions6Center(const ADIMENSION6 &aElem)
void HelperParseDimensions6Radial(const ADIMENSION6 &aElem)
void HelperSetZoneKeepoutRestrictions(ZONE *aZone, const uint8_t aKeepoutRestrictions)
PCB_SHAPE * HelperCreateAndAddShape(uint16_t aComponent)
void ParsePads6Data(const ALTIUM_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry)
void ParseWideStrings6Data(const ALTIUM_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)
void ParseComponents6Data(const ALTIUM_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry)
int GetNetCode(uint16_t aId) const
void ConvertPads6ToFootprintItemOnNonCopper(FOOTPRINT *aFootprint, const APAD6 &aElem)
void ConvertTexts6ToFootprintItem(FOOTPRINT *aFootprint, const ATEXT6 &aElem)
unsigned m_lastProgressCount
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 HelperShapeSetLocalCoord(PCB_SHAPE *aShape, uint16_t aComponent)
std::vector< ZONE * > m_polygons
std::map< wxString, wxString > m_models
void ConvertArcs6ToPcbShape(const AARC6 &aElem, PCB_SHAPE *aShape)
void ConvertTracks6ToBoardItemOnLayer(const ATRACK6 &aElem, PCB_LAYER_ID aLayer)
void ConvertFills6ToBoardItem(const AFILL6 &aElem)
void ParseModelsData(const ALTIUM_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry, const std::vector< std::string > &aRootDir)
void ParseRules6Data(const ALTIUM_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry)
FOOTPRINT * HelperGetFootprint(uint16_t aComponent) const
PCB_LAYER_ID GetKicadLayer(ALTIUM_LAYER aAltiumLayer) const
void ConvertFills6ToBoardItemWithNet(const AFILL6 &aElem)
void ConvertTracks6ToFootprintItemOnLayer(FOOTPRINT *aFootprint, const ATRACK6 &aElem, PCB_LAYER_ID aLayer)
void ParseTexts6Data(const ALTIUM_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry)
void ParsePolygons6Data(const ALTIUM_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry)
void ConvertArcs6ToBoardItemOnLayer(const AARC6 &aElem, PCB_LAYER_ID aLayer)
std::map< ALTIUM_RECORD, std::multimap< int, const AEXTENDED_PRIMITIVE_INFORMATION > > m_extendedPrimitiveInformationMaps
void ConvertTexts6ToEdaTextSettings(const ATEXT6 &aElem, EDA_TEXT *aEdaText)
void ParseTracks6Data(const ALTIUM_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry)
void ConvertPads6ToBoardItemOnNonCopper(const APAD6 &aElem)
void ConvertShapeBasedRegions6ToFootprintItem(FOOTPRINT *aFootprint, const AREGION6 &aElem)
void ParseNets6Data(const ALTIUM_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry)
void ParseExtendedPrimitiveInformationData(const ALTIUM_COMPOUND_FILE &aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY *aEntry)
void ParseDimensions6Data(const ALTIUM_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
bool SetNetCode(int aNetCode, bool aNoAssert)
Set net using a net code.
Container for design settings for a BOARD object.
std::shared_ptr< NET_SETTINGS > m_NetSettings
void SetGridOrigin(const VECTOR2I &aOrigin)
const VECTOR2I & GetGridOrigin()
const VECTOR2I & GetAuxOrigin()
void SetAuxOrigin(const VECTOR2I &aOrigin)
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 SetLocked(bool aLocked)
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
BOARD_ITEM_CONTAINER * GetParent() const
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.
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 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.
bool m_LegacyNetclassesLoaded
True if netclasses were loaded from the file.
void SetCopperLayerCount(int aCount)
const wxString & GetFileName() const
bool SetLayerType(PCB_LAYER_ID aLayer, LAYER_T aLayerType)
Change the type of the layer given by aLayer.
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
const Vec GetCenter() const
coord_type GetHeight() const
coord_type GetWidth() const
bool Contains(const Vec &aPoint) const
bool IsHorizontal() const
EDA_ANGLE GetArcAngle() const
void SetCenter(const VECTOR2I &aCenter)
SHAPE_POLY_SET & GetPolyShape()
void SetFilled(bool aFlag)
void SetPolyShape(const SHAPE_POLY_SET &aShape)
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 SetArcGeometry(const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd)
Set the three controlling points for an arc.
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,...
BOX2I GetTextBox(int aLine=-1, bool aInvertY=false) const
Useful in multiline texts to calculate the full text or a line area (for zones filling,...
const VECTOR2I & GetTextPos() const
void SetTextPos(const VECTOR2I &aPoint)
void SetMirrored(bool isMirrored)
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
virtual void SetVisible(bool aVisible)
void SetTextThickness(int aWidth)
The TextThickness is that set by the user.
void SetKeepUpright(bool aKeepUpright)
void SetTextSize(const VECTOR2I &aNewSize)
virtual void SetText(const wxString &aText)
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
int GetTextThickness() const
void SetItalic(bool aItalic)
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
VECTOR3D m_Offset
3D model offset (mm)
VECTOR3D m_Rotation
3D model rotation (degrees)
wxString m_Filename
The 3D shape filename in 3D library.
virtual void SetLocalCoord()
Set relative coordinates from draw coordinates.
void Rotate(const VECTOR2I &aRotCentre, const EDA_ANGLE &aAngle) override
Rotate this object.
virtual void SetPosition(const VECTOR2I &aPos) override
A specialization of ZONE for use in footprints.
A logical library item identifier and consists of various portions much like a URI.
LSET is a set of PCB_LAYER_IDs.
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Handle the data for a net.
static const int UNCONNECTED
Constant that forces initialization of a netinfo item to the NETINFO_ITEM ORPHANED (typically -1) whe...
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.
void SetUnitsFormat(const DIM_UNITS_FORMAT aFormat)
void SetUnits(EDA_UNITS aUnits)
void SetPrefix(const wxString &aPrefix)
void SetLineThickness(int aWidth)
virtual void SetEnd(const VECTOR2I &aPoint)
void SetPrecision(DIM_PRECISION aPrecision)
virtual void SetStart(const VECTOR2I &aPoint)
void SetKeepTextAligned(bool aKeepAligned)
For better understanding of the points that make a dimension:
void SetHeight(int aHeight)
Set the distance from the feature points to the crossbar line.
Mark the center of a circle or arc with a cross shape.
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.
virtual void Rotate(const VECTOR2I &aRotCentre, const EDA_ANGLE &aAngle) override
Rotate this object.
void SetStroke(const STROKE_PARAMS &aStroke) override
VECTOR2I GetPosition() const override
virtual void SetPosition(const VECTOR2I &aPos) override
void SetWidth(int aWidth)
void SetEnd(const VECTOR2I &aEnd)
void SetStart(const VECTOR2I &aStart)
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).
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
int NextShape(int aPointIndex, bool aForwards=true) const
Return the vertex index of the next shape in the chain, or -1 if aPointIndex is the last shape.
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.
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
bool IsArcStart(size_t aIndex) const
SEG Segment(int aIndex)
Return a copy of the aIndex-th segment in the line chain.
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 Fracture(POLYGON_MODE aFastMode)
Convert a single outline slitted ("fractured") polygon into a set ouf outlines with holes.
int AddOutline(const SHAPE_LINE_CHAIN &aOutline)
Adds a new hole to the given outline (default: last) and returns its index.
void BooleanAdd(const SHAPE_POLY_SET &b, POLYGON_MODE aFastMode)
Perform boolean polyset difference For aFastMode meaning, see function booleanOp.
int AddHole(const SHAPE_LINE_CHAIN &aHole, int aOutline=-1)
Return the area of this poly set.
void Move(const VECTOR2I &aVector) override
Simple container to manage line stroke parameters.
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 SetHatchThickness(int aThickness)
void SetNeedRefill(bool aNeedRefill)
void SetDoNotAllowPads(bool aEnable)
void SetPosition(const VECTOR2I &aPos) override
void SetBorderDisplayStyle(ZONE_BORDER_DISPLAY_STYLE aBorderHatchStyle, int aBorderHatchPitch, bool aRebuilBorderdHatch)
Set all hatch parameters for the zone.
const BOX2I GetBoundingBox() const override
void SetMinThickness(int aMinThickness)
void SetHatchOrientation(const EDA_ANGLE &aStep)
void SetDoNotAllowCopperPour(bool aEnable)
void SetThermalReliefSpokeWidth(int aThermalReliefSpokeWidth)
SHAPE_POLY_SET * Outline()
SHAPE_POLY_SET * GetFill(PCB_LAYER_ID aLayer)
void SetIsRuleArea(bool aEnable)
void SetDoNotAllowTracks(bool aEnable)
void SetFilledPolysList(PCB_LAYER_ID aLayer, const SHAPE_POLY_SET &aPolysList)
Set the list of filled polygons.
int GetMinThickness() const
void Rotate(const VECTOR2I &aCentre, const EDA_ANGLE &aAngle) override
Rotate the outlines.
void SetIsFilled(bool isFilled)
void SetFillMode(ZONE_FILL_MODE aFillMode)
bool HasFilledPolysForLayer(PCB_LAYER_ID aLayer) const
void SetDoNotAllowVias(bool aEnable)
void SetLocalClearance(int aClearance)
void SetThermalReliefGap(int aThermalReliefGap)
void SetLayerSet(LSET aLayerSet) override
void SetDoNotAllowFootprints(bool aEnable)
bool AppendCorner(VECTOR2I aPosition, int aHoleIdx, bool aAllowDuplication=false)
Add a new corner to the zone outline (to the main outline or a hole)
void SetAssignedPriority(unsigned aPriority)
void SetPadConnection(ZONE_CONNECTION aPadConnection)
void SetHatchGap(int aStep)
static int GetDefaultHatchPitch()
static constexpr EDA_ANGLE & ANGLE_45
#define THROW_IO_ERROR(msg)
bool IsCopperLayer(int aLayerId)
Tests whether a layer is a copper layer.
PCB_LAYER_ID
A quick note on layer IDs:
LSET FlipLayerMask(LSET aMask, int aCopperLayersCount)
Calculate the mask layer when flipping a footprint.
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
@ NPTH
like PAD_PTH, but not plated
@ SMD
Smd pad, appears on the solder paste layer (default)
@ PTH
Plated through hole pad.
#define PROJECT_VAR_NAME
A variable name whose value holds the current project directory.
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
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 sourcefootprintlibrary
wxString sourcedesignator
std::vector< VECTOR2I > textPoint
ALTIUM_DIMENSION_KIND kind
std::vector< VECTOR2I > referencePoint
uint8_t keepoutrestrictions
int32_t soldermaskexpansionmanual
std::unique_ptr< APAD6_SIZE_AND_SHAPE > sizeAndShape
ALTIUM_PAD_SHAPE topshape
ALTIUM_MODE pastemaskexpansionmode
ALTIUM_MODE soldermaskexpansionmode
int32_t pastemaskexpansionmanual
std::vector< ALTIUM_VERTICE > vertices
ALTIUM_POLYGON_HATCHSTYLE hatchstyle