altium: Parse solder and paste mask settings of tracks and arcs
This commit is contained in:
parent
5efd29d6f4
commit
52a2d52bf0
|
@ -166,12 +166,92 @@ void altium_parse_polygons( std::map<wxString, wxString>& aProps,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static ALTIUM_MODE ReadAltiumModeFromProperties( const std::map<wxString, wxString>& aProps,
|
||||||
|
wxString aKey )
|
||||||
|
{
|
||||||
|
wxString mode = ALTIUM_PARSER::ReadString( aProps, aKey, wxT( "" ) );
|
||||||
|
|
||||||
|
if( mode == wxT( "None" ) )
|
||||||
|
return ALTIUM_MODE::NONE;
|
||||||
|
else if( mode == wxT( "Rule" ) )
|
||||||
|
return ALTIUM_MODE::RULE;
|
||||||
|
else if( mode == wxT( "Manual" ) )
|
||||||
|
return ALTIUM_MODE::MANUAL;
|
||||||
|
|
||||||
|
wxLogError( _( "Unknown Mode string: '%s'." ), mode );
|
||||||
|
return ALTIUM_MODE::UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static ALTIUM_RECORD ReadAltiumRecordFromProperties( const std::map<wxString, wxString>& aProps,
|
||||||
|
wxString aKey )
|
||||||
|
{
|
||||||
|
wxString record = ALTIUM_PARSER::ReadString( aProps, aKey, wxT( "" ) );
|
||||||
|
|
||||||
|
if( record == wxT( "Arc" ) )
|
||||||
|
return ALTIUM_RECORD::ARC;
|
||||||
|
else if( record == wxT( "Pad" ) )
|
||||||
|
return ALTIUM_RECORD::PAD;
|
||||||
|
else if( record == wxT( "Via" ) )
|
||||||
|
return ALTIUM_RECORD::VIA;
|
||||||
|
else if( record == wxT( "Track" ) )
|
||||||
|
return ALTIUM_RECORD::TRACK;
|
||||||
|
else if( record == wxT( "Text" ) )
|
||||||
|
return ALTIUM_RECORD::TEXT;
|
||||||
|
else if( record == wxT( "Fill" ) )
|
||||||
|
return ALTIUM_RECORD::FILL;
|
||||||
|
else if( record == wxT( "Region" ) ) // correct?
|
||||||
|
return ALTIUM_RECORD::REGION;
|
||||||
|
else if( record == wxT( "Model" ) )
|
||||||
|
return ALTIUM_RECORD::MODEL;
|
||||||
|
|
||||||
|
wxLogError( _( "Unknown Record name string: '%s'." ), record );
|
||||||
|
return ALTIUM_RECORD::UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static AEXTENDED_PRIMITIVE_INFORMATION_TYPE
|
||||||
|
ReadAltiumExtendedPrimitiveInformationTypeFromProperties(
|
||||||
|
const std::map<wxString, wxString>& aProps, wxString aKey )
|
||||||
|
{
|
||||||
|
wxString parsedType = ALTIUM_PARSER::ReadString( aProps, aKey, wxT( "" ) );
|
||||||
|
|
||||||
|
if( parsedType == wxT( "Mask" ) )
|
||||||
|
return AEXTENDED_PRIMITIVE_INFORMATION_TYPE::MASK;
|
||||||
|
|
||||||
|
wxLogError( _( "Unknown Extended Primitive Information type: '%s'." ), parsedType );
|
||||||
|
return AEXTENDED_PRIMITIVE_INFORMATION_TYPE::UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
AEXTENDED_PRIMITIVE_INFORMATION::AEXTENDED_PRIMITIVE_INFORMATION( ALTIUM_PARSER& aReader )
|
||||||
|
{
|
||||||
|
const std::map<wxString, wxString> props = aReader.ReadProperties();
|
||||||
|
|
||||||
|
if( props.empty() )
|
||||||
|
THROW_IO_ERROR( wxT( "ExtendedPrimitiveInformation stream has no properties!" ) );
|
||||||
|
|
||||||
|
primitiveIndex = ALTIUM_PARSER::ReadInt( props, wxT( "PRIMITIVEINDEX" ), -1 );
|
||||||
|
primitiveObjectId = ReadAltiumRecordFromProperties( props, wxT( "PRIMITIVEOBJECTID" ) );
|
||||||
|
type = ReadAltiumExtendedPrimitiveInformationTypeFromProperties( props, wxT( "TYPE" ) );
|
||||||
|
|
||||||
|
pastemaskexpansionmode = ReadAltiumModeFromProperties( props, wxT( "PASTEMASKEXPANSIONMODE" ) );
|
||||||
|
pastemaskexpansionmanual = ALTIUM_PARSER::ReadKicadUnit(
|
||||||
|
props, wxT( "PASTEMASKEXPANSION_MANUAL" ), wxT( "0mil" ) );
|
||||||
|
soldermaskexpansionmode =
|
||||||
|
ReadAltiumModeFromProperties( props, wxT( "SOLDERMASKEXPANSIONMODE" ) );
|
||||||
|
soldermaskexpansionmanual = ALTIUM_PARSER::ReadKicadUnit(
|
||||||
|
props, wxT( "SOLDERMASKEXPANSION_MANUAL" ), wxT( "0mil" ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ABOARD6::ABOARD6( ALTIUM_PARSER& aReader )
|
ABOARD6::ABOARD6( ALTIUM_PARSER& aReader )
|
||||||
{
|
{
|
||||||
std::map<wxString, wxString> props = aReader.ReadProperties();
|
std::map<wxString, wxString> props = aReader.ReadProperties();
|
||||||
|
|
||||||
if( props.empty() )
|
if( props.empty() )
|
||||||
THROW_IO_ERROR( wxT( "Board6 stream has no props!" ) );
|
THROW_IO_ERROR( wxT( "Board6 stream has no properties!" ) );
|
||||||
|
|
||||||
sheetpos = VECTOR2I( ALTIUM_PARSER::ReadKicadUnit( props, wxT( "SHEETX" ), wxT( "0mil" ) ),
|
sheetpos = VECTOR2I( ALTIUM_PARSER::ReadKicadUnit( props, wxT( "SHEETX" ), wxT( "0mil" ) ),
|
||||||
-ALTIUM_PARSER::ReadKicadUnit( props, wxT( "SHEETY" ), wxT( "0mil" ) ) );
|
-ALTIUM_PARSER::ReadKicadUnit( props, wxT( "SHEETY" ), wxT( "0mil" ) ) );
|
||||||
|
@ -634,8 +714,8 @@ APAD6::APAD6( ALTIUM_PARSER& aReader )
|
||||||
pastemaskexpansionmanual = aReader.ReadKicadUnit();
|
pastemaskexpansionmanual = aReader.ReadKicadUnit();
|
||||||
soldermaskexpansionmanual = aReader.ReadKicadUnit();
|
soldermaskexpansionmanual = aReader.ReadKicadUnit();
|
||||||
aReader.Skip( 7 );
|
aReader.Skip( 7 );
|
||||||
pastemaskexpansionmode = static_cast<ALTIUM_PAD_RULE>( aReader.Read<uint8_t>() );
|
pastemaskexpansionmode = static_cast<ALTIUM_MODE>( aReader.Read<uint8_t>() );
|
||||||
soldermaskexpansionmode = static_cast<ALTIUM_PAD_RULE>( aReader.Read<uint8_t>() );
|
soldermaskexpansionmode = static_cast<ALTIUM_MODE>( aReader.Read<uint8_t>() );
|
||||||
aReader.Skip( 3 );
|
aReader.Skip( 3 );
|
||||||
holerotation = aReader.Read<double>();
|
holerotation = aReader.Read<double>();
|
||||||
|
|
||||||
|
|
|
@ -119,6 +119,8 @@ enum class ALTIUM_CONNECT_STYLE
|
||||||
|
|
||||||
enum class ALTIUM_RECORD
|
enum class ALTIUM_RECORD
|
||||||
{
|
{
|
||||||
|
UNKNOWN = -1,
|
||||||
|
|
||||||
ARC = 1,
|
ARC = 1,
|
||||||
PAD = 2,
|
PAD = 2,
|
||||||
VIA = 3,
|
VIA = 3,
|
||||||
|
@ -161,9 +163,10 @@ enum class ALTIUM_PAD_MODE
|
||||||
FULL_STACK = 2
|
FULL_STACK = 2
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class ALTIUM_PAD_RULE
|
enum class ALTIUM_MODE
|
||||||
{
|
{
|
||||||
UNKNOWN = 0,
|
UNKNOWN = -1,
|
||||||
|
NONE = 0, // TODO: correct ID?
|
||||||
RULE = 1,
|
RULE = 1,
|
||||||
MANUAL = 2
|
MANUAL = 2
|
||||||
};
|
};
|
||||||
|
@ -329,6 +332,29 @@ enum class ALTIUM_LAYER
|
||||||
|
|
||||||
class ALTIUM_PARSER;
|
class ALTIUM_PARSER;
|
||||||
|
|
||||||
|
enum class AEXTENDED_PRIMITIVE_INFORMATION_TYPE
|
||||||
|
{
|
||||||
|
UNKNOWN = -1,
|
||||||
|
|
||||||
|
MASK
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AEXTENDED_PRIMITIVE_INFORMATION
|
||||||
|
{
|
||||||
|
int primitiveIndex;
|
||||||
|
ALTIUM_RECORD primitiveObjectId;
|
||||||
|
|
||||||
|
AEXTENDED_PRIMITIVE_INFORMATION_TYPE type;
|
||||||
|
|
||||||
|
// Type == Mask
|
||||||
|
ALTIUM_MODE pastemaskexpansionmode;
|
||||||
|
int32_t pastemaskexpansionmanual;
|
||||||
|
ALTIUM_MODE soldermaskexpansionmode;
|
||||||
|
int32_t soldermaskexpansionmanual;
|
||||||
|
|
||||||
|
explicit AEXTENDED_PRIMITIVE_INFORMATION( ALTIUM_PARSER& aReader );
|
||||||
|
};
|
||||||
|
|
||||||
struct ABOARD6_LAYER_STACKUP
|
struct ABOARD6_LAYER_STACKUP
|
||||||
{
|
{
|
||||||
wxString name;
|
wxString name;
|
||||||
|
@ -585,9 +611,9 @@ struct APAD6
|
||||||
|
|
||||||
double direction;
|
double direction;
|
||||||
bool plated;
|
bool plated;
|
||||||
ALTIUM_PAD_RULE pastemaskexpansionmode;
|
ALTIUM_MODE pastemaskexpansionmode;
|
||||||
int32_t pastemaskexpansionmanual;
|
int32_t pastemaskexpansionmanual;
|
||||||
ALTIUM_PAD_RULE soldermaskexpansionmode;
|
ALTIUM_MODE soldermaskexpansionmode;
|
||||||
int32_t soldermaskexpansionmanual;
|
int32_t soldermaskexpansionmanual;
|
||||||
double holerotation;
|
double holerotation;
|
||||||
|
|
||||||
|
|
|
@ -379,6 +379,11 @@ void ALTIUM_PCB::Parse( const ALTIUM_COMPOUND_FILE& altiumPcbFi
|
||||||
{
|
{
|
||||||
this->ParseBoard6Data( aFile, fileHeader );
|
this->ParseBoard6Data( aFile, fileHeader );
|
||||||
} },
|
} },
|
||||||
|
{ false, ALTIUM_PCB_DIR::EXTENDPRIMITIVEINFORMATION,
|
||||||
|
[this]( const ALTIUM_COMPOUND_FILE& aFile, auto fileHeader )
|
||||||
|
{
|
||||||
|
this->ParseExtendedPrimitiveInformationData( aFile, fileHeader );
|
||||||
|
} },
|
||||||
{ true, ALTIUM_PCB_DIR::COMPONENTS6,
|
{ true, ALTIUM_PCB_DIR::COMPONENTS6,
|
||||||
[this]( const ALTIUM_COMPOUND_FILE& aFile, auto fileHeader )
|
[this]( const ALTIUM_COMPOUND_FILE& aFile, auto fileHeader )
|
||||||
{
|
{
|
||||||
|
@ -660,6 +665,7 @@ FOOTPRINT* ALTIUM_PCB::ParseFootprint( const ALTIUM_COMPOUND_FILE& altiumLibFile
|
||||||
m_layermap.emplace( ALTIUM_LAYER::MECHANICAL_16, Eco2_User );
|
m_layermap.emplace( ALTIUM_LAYER::MECHANICAL_16, Eco2_User );
|
||||||
|
|
||||||
m_unicodeStrings.clear();
|
m_unicodeStrings.clear();
|
||||||
|
m_extendedPrimitiveInformationMaps.clear();
|
||||||
// TODO: WideStrings are stored as parameterMap in the case of footprints, not as binary
|
// TODO: WideStrings are stored as parameterMap in the case of footprints, not as binary
|
||||||
// std::string unicodeStringsStreamName = aFootprintName.ToStdString() + "\\WideStrings";
|
// std::string unicodeStringsStreamName = aFootprintName.ToStdString() + "\\WideStrings";
|
||||||
// const CFB::COMPOUND_FILE_ENTRY* unicodeStringsData = altiumLibFile.FindStream( unicodeStringsStreamName );
|
// const CFB::COMPOUND_FILE_ENTRY* unicodeStringsData = altiumLibFile.FindStream( unicodeStringsStreamName );
|
||||||
|
@ -710,7 +716,7 @@ FOOTPRINT* ALTIUM_PCB::ParseFootprint( const ALTIUM_COMPOUND_FILE& altiumLibFile
|
||||||
altiumLibFile.FindStream( extendedPrimitiveInformationStreamName );
|
altiumLibFile.FindStream( extendedPrimitiveInformationStreamName );
|
||||||
if( extendedPrimitiveInformationData != nullptr )
|
if( extendedPrimitiveInformationData != nullptr )
|
||||||
{
|
{
|
||||||
// TODO: implement
|
ParseExtendedPrimitiveInformationData( altiumLibFile, extendedPrimitiveInformationData );
|
||||||
}
|
}
|
||||||
|
|
||||||
footprint->SetReference( wxT( "REF**" ) );
|
footprint->SetReference( wxT( "REF**" ) );
|
||||||
|
@ -718,7 +724,7 @@ FOOTPRINT* ALTIUM_PCB::ParseFootprint( const ALTIUM_COMPOUND_FILE& altiumLibFile
|
||||||
footprint->Reference().SetVisible( true ); // TODO: extract visibility information
|
footprint->Reference().SetVisible( true ); // TODO: extract visibility information
|
||||||
footprint->Value().SetVisible( true );
|
footprint->Value().SetVisible( true );
|
||||||
|
|
||||||
while( parser.GetRemainingBytes() >= 4 /* TODO: use Header section of file */ )
|
for( int primitiveIndex = 0; parser.GetRemainingBytes() >= 4; primitiveIndex++ )
|
||||||
{
|
{
|
||||||
ALTIUM_RECORD recordtype = static_cast<ALTIUM_RECORD>( parser.Peek<uint8_t>() );
|
ALTIUM_RECORD recordtype = static_cast<ALTIUM_RECORD>( parser.Peek<uint8_t>() );
|
||||||
switch( recordtype )
|
switch( recordtype )
|
||||||
|
@ -726,7 +732,7 @@ FOOTPRINT* ALTIUM_PCB::ParseFootprint( const ALTIUM_COMPOUND_FILE& altiumLibFile
|
||||||
case ALTIUM_RECORD::ARC:
|
case ALTIUM_RECORD::ARC:
|
||||||
{
|
{
|
||||||
AARC6 arc( parser );
|
AARC6 arc( parser );
|
||||||
ConvertArcs6ToFootprintItem( footprint.get(), arc, false );
|
ConvertArcs6ToFootprintItem( footprint.get(), arc, primitiveIndex, false );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ALTIUM_RECORD::PAD:
|
case ALTIUM_RECORD::PAD:
|
||||||
|
@ -744,7 +750,7 @@ FOOTPRINT* ALTIUM_PCB::ParseFootprint( const ALTIUM_COMPOUND_FILE& altiumLibFile
|
||||||
case ALTIUM_RECORD::TRACK:
|
case ALTIUM_RECORD::TRACK:
|
||||||
{
|
{
|
||||||
ATRACK6 track( parser );
|
ATRACK6 track( parser );
|
||||||
ConvertTracks6ToFootprintItem( footprint.get(), track, false );
|
ConvertTracks6ToFootprintItem( footprint.get(), track, primitiveIndex, false );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ALTIUM_RECORD::TEXT:
|
case ALTIUM_RECORD::TEXT:
|
||||||
|
@ -860,6 +866,27 @@ void ALTIUM_PCB::ParseFileHeader( const ALTIUM_COMPOUND_FILE& aAltiumPcbFile
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ALTIUM_PCB::ParseExtendedPrimitiveInformationData( const ALTIUM_COMPOUND_FILE& aAltiumPcbFile,
|
||||||
|
const CFB::COMPOUND_FILE_ENTRY* aEntry )
|
||||||
|
{
|
||||||
|
if( m_progressReporter )
|
||||||
|
m_progressReporter->Report( _( "Loading extended primitive information data..." ) );
|
||||||
|
|
||||||
|
ALTIUM_PARSER reader( aAltiumPcbFile, aEntry );
|
||||||
|
|
||||||
|
while( reader.GetRemainingBytes() >= 4 /* TODO: use Header section of file */ )
|
||||||
|
{
|
||||||
|
checkpoint();
|
||||||
|
AEXTENDED_PRIMITIVE_INFORMATION elem( reader );
|
||||||
|
|
||||||
|
m_extendedPrimitiveInformationMaps[elem.primitiveObjectId].emplace( elem.primitiveIndex,
|
||||||
|
std::move( elem ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( reader.GetRemainingBytes() != 0 )
|
||||||
|
THROW_IO_ERROR( wxT( "ExtendedPrimitiveInformation stream is not fully parsed" ) );
|
||||||
|
}
|
||||||
|
|
||||||
void ALTIUM_PCB::ParseBoard6Data( const ALTIUM_COMPOUND_FILE& aAltiumPcbFile,
|
void ALTIUM_PCB::ParseBoard6Data( const ALTIUM_COMPOUND_FILE& aAltiumPcbFile,
|
||||||
const CFB::COMPOUND_FILE_ENTRY* aEntry )
|
const CFB::COMPOUND_FILE_ENTRY* aEntry )
|
||||||
{
|
{
|
||||||
|
@ -2128,19 +2155,19 @@ void ALTIUM_PCB::ParseArcs6Data( const ALTIUM_COMPOUND_FILE& aAltiumPcbFile,
|
||||||
|
|
||||||
ALTIUM_PARSER reader( aAltiumPcbFile, aEntry );
|
ALTIUM_PARSER reader( aAltiumPcbFile, aEntry );
|
||||||
|
|
||||||
while( reader.GetRemainingBytes() >= 4 /* TODO: use Header section of file */ )
|
for( int primitiveIndex = 0; reader.GetRemainingBytes() >= 4; primitiveIndex++ )
|
||||||
{
|
{
|
||||||
checkpoint();
|
checkpoint();
|
||||||
AARC6 elem( reader );
|
AARC6 elem( reader );
|
||||||
|
|
||||||
if( elem.component == ALTIUM_COMPONENT_NONE )
|
if( elem.component == ALTIUM_COMPONENT_NONE )
|
||||||
{
|
{
|
||||||
ConvertArcs6ToBoardItem( elem );
|
ConvertArcs6ToBoardItem( elem, primitiveIndex );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FOOTPRINT* footprint = HelperGetFootprint( elem.component );
|
FOOTPRINT* footprint = HelperGetFootprint( elem.component );
|
||||||
ConvertArcs6ToFootprintItem( footprint, elem, true );
|
ConvertArcs6ToFootprintItem( footprint, elem, primitiveIndex, true );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2178,7 +2205,7 @@ void ALTIUM_PCB::ConvertArcs6ToPcbShape( const AARC6& aElem, PCB_SHAPE* aShape )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ALTIUM_PCB::ConvertArcs6ToBoardItem( const AARC6& aElem )
|
void ALTIUM_PCB::ConvertArcs6ToBoardItem( const AARC6& aElem, const int aPrimitiveIndex )
|
||||||
{
|
{
|
||||||
if( aElem.is_polygonoutline || aElem.subpolyindex != ALTIUM_POLYGON_NONE )
|
if( aElem.is_polygonoutline || aElem.subpolyindex != ALTIUM_POLYGON_NONE )
|
||||||
return;
|
return;
|
||||||
|
@ -2200,11 +2227,27 @@ void ALTIUM_PCB::ConvertArcs6ToBoardItem( const AARC6& aElem )
|
||||||
ConvertArcs6ToBoardItemOnLayer( aElem, klayer );
|
ConvertArcs6ToBoardItemOnLayer( aElem, klayer );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for( const auto layerExpansionMask :
|
||||||
|
HelperGetSolderAndPasteMaskExpansions( ALTIUM_RECORD::ARC, aPrimitiveIndex, aElem.layer ) )
|
||||||
|
{
|
||||||
|
int width = aElem.width + ( layerExpansionMask.second * 2 );
|
||||||
|
if( width > 1 )
|
||||||
|
{
|
||||||
|
PCB_SHAPE* arc = new PCB_SHAPE( m_board );
|
||||||
|
|
||||||
|
ConvertArcs6ToPcbShape( aElem, arc );
|
||||||
|
arc->SetStroke( STROKE_PARAMS( width, PLOT_DASH_TYPE::SOLID ) );
|
||||||
|
arc->SetLayer( layerExpansionMask.first );
|
||||||
|
|
||||||
|
m_board->Add( arc, ADD_MODE::APPEND );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ALTIUM_PCB::ConvertArcs6ToFootprintItem( FOOTPRINT* aFootprint, const AARC6& aElem,
|
void ALTIUM_PCB::ConvertArcs6ToFootprintItem( FOOTPRINT* aFootprint, const AARC6& aElem,
|
||||||
const bool aIsBoardImport )
|
const int aPrimitiveIndex, const bool aIsBoardImport )
|
||||||
{
|
{
|
||||||
if( aElem.is_polygonoutline || aElem.subpolyindex != ALTIUM_POLYGON_NONE )
|
if( aElem.is_polygonoutline || aElem.subpolyindex != ALTIUM_POLYGON_NONE )
|
||||||
return;
|
return;
|
||||||
|
@ -2234,6 +2277,23 @@ void ALTIUM_PCB::ConvertArcs6ToFootprintItem( FOOTPRINT* aFootprint, const AARC6
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for( const auto layerExpansionMask :
|
||||||
|
HelperGetSolderAndPasteMaskExpansions( ALTIUM_RECORD::ARC, aPrimitiveIndex, aElem.layer ) )
|
||||||
|
{
|
||||||
|
int width = aElem.width + ( layerExpansionMask.second * 2 );
|
||||||
|
if( width > 1 )
|
||||||
|
{
|
||||||
|
FP_SHAPE* arc = new FP_SHAPE( aFootprint );
|
||||||
|
|
||||||
|
ConvertArcs6ToPcbShape( aElem, arc );
|
||||||
|
arc->SetStroke( STROKE_PARAMS( width, PLOT_DASH_TYPE::SOLID ) );
|
||||||
|
arc->SetLayer( layerExpansionMask.first );
|
||||||
|
|
||||||
|
arc->SetLocalCoord();
|
||||||
|
aFootprint->Add( arc, ADD_MODE::APPEND );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2508,12 +2568,12 @@ void ALTIUM_PCB::ConvertPads6ToFootprintItemOnCopper( FOOTPRINT* aFootprint, con
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( aElem.pastemaskexpansionmode == ALTIUM_PAD_RULE::MANUAL )
|
if( aElem.pastemaskexpansionmode == ALTIUM_MODE::MANUAL )
|
||||||
{
|
{
|
||||||
pad->SetLocalSolderPasteMargin( aElem.pastemaskexpansionmanual );
|
pad->SetLocalSolderPasteMargin( aElem.pastemaskexpansionmanual );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( aElem.soldermaskexpansionmode == ALTIUM_PAD_RULE::MANUAL )
|
if( aElem.soldermaskexpansionmode == ALTIUM_MODE::MANUAL )
|
||||||
{
|
{
|
||||||
pad->SetLocalSolderMaskMargin( aElem.soldermaskexpansionmanual );
|
pad->SetLocalSolderMaskMargin( aElem.soldermaskexpansionmanual );
|
||||||
}
|
}
|
||||||
|
@ -2807,19 +2867,19 @@ void ALTIUM_PCB::ParseTracks6Data( const ALTIUM_COMPOUND_FILE& aAltiumPcbFil
|
||||||
|
|
||||||
ALTIUM_PARSER reader( aAltiumPcbFile, aEntry );
|
ALTIUM_PARSER reader( aAltiumPcbFile, aEntry );
|
||||||
|
|
||||||
while( reader.GetRemainingBytes() >= 4 /* TODO: use Header section of file */ )
|
for( int primitiveIndex = 0; reader.GetRemainingBytes() >= 4; primitiveIndex++ )
|
||||||
{
|
{
|
||||||
checkpoint();
|
checkpoint();
|
||||||
ATRACK6 elem( reader );
|
ATRACK6 elem( reader );
|
||||||
|
|
||||||
if( elem.component == ALTIUM_COMPONENT_NONE )
|
if( elem.component == ALTIUM_COMPONENT_NONE )
|
||||||
{
|
{
|
||||||
ConvertTracks6ToBoardItem( elem );
|
ConvertTracks6ToBoardItem( elem, primitiveIndex );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FOOTPRINT* footprint = HelperGetFootprint( elem.component );
|
FOOTPRINT* footprint = HelperGetFootprint( elem.component );
|
||||||
ConvertTracks6ToFootprintItem( footprint, elem, true );
|
ConvertTracks6ToFootprintItem( footprint, elem, primitiveIndex, true );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2830,7 +2890,7 @@ void ALTIUM_PCB::ParseTracks6Data( const ALTIUM_COMPOUND_FILE& aAltiumPcbFil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ALTIUM_PCB::ConvertTracks6ToBoardItem( const ATRACK6& aElem )
|
void ALTIUM_PCB::ConvertTracks6ToBoardItem( const ATRACK6& aElem, const int aPrimitiveIndex )
|
||||||
{
|
{
|
||||||
if( aElem.is_polygonoutline || aElem.subpolyindex != ALTIUM_POLYGON_NONE )
|
if( aElem.is_polygonoutline || aElem.subpolyindex != ALTIUM_POLYGON_NONE )
|
||||||
return;
|
return;
|
||||||
|
@ -2852,10 +2912,28 @@ void ALTIUM_PCB::ConvertTracks6ToBoardItem( const ATRACK6& aElem )
|
||||||
ConvertTracks6ToBoardItemOnLayer( aElem, klayer );
|
ConvertTracks6ToBoardItemOnLayer( aElem, klayer );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for( const auto layerExpansionMask : HelperGetSolderAndPasteMaskExpansions(
|
||||||
|
ALTIUM_RECORD::TRACK, aPrimitiveIndex, aElem.layer ) )
|
||||||
|
{
|
||||||
|
int width = aElem.width + ( layerExpansionMask.second * 2 );
|
||||||
|
if( width > 1 )
|
||||||
|
{
|
||||||
|
PCB_SHAPE* seg = new PCB_SHAPE( m_board, SHAPE_T::SEGMENT );
|
||||||
|
|
||||||
|
seg->SetStart( aElem.start );
|
||||||
|
seg->SetEnd( aElem.end );
|
||||||
|
seg->SetStroke( STROKE_PARAMS( width, PLOT_DASH_TYPE::SOLID ) );
|
||||||
|
seg->SetLayer( layerExpansionMask.first );
|
||||||
|
|
||||||
|
m_board->Add( seg, ADD_MODE::APPEND );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ALTIUM_PCB::ConvertTracks6ToFootprintItem( FOOTPRINT* aFootprint, const ATRACK6& aElem,
|
void ALTIUM_PCB::ConvertTracks6ToFootprintItem( FOOTPRINT* aFootprint, const ATRACK6& aElem,
|
||||||
|
const int aPrimitiveIndex,
|
||||||
const bool aIsBoardImport )
|
const bool aIsBoardImport )
|
||||||
{
|
{
|
||||||
if( aElem.is_polygonoutline || aElem.subpolyindex != ALTIUM_POLYGON_NONE )
|
if( aElem.is_polygonoutline || aElem.subpolyindex != ALTIUM_POLYGON_NONE )
|
||||||
|
@ -2886,6 +2964,24 @@ void ALTIUM_PCB::ConvertTracks6ToFootprintItem( FOOTPRINT* aFootprint, const ATR
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for( const auto layerExpansionMask : HelperGetSolderAndPasteMaskExpansions(
|
||||||
|
ALTIUM_RECORD::TRACK, aPrimitiveIndex, aElem.layer ) )
|
||||||
|
{
|
||||||
|
int width = aElem.width + ( layerExpansionMask.second * 2 );
|
||||||
|
if( width > 1 )
|
||||||
|
{
|
||||||
|
FP_SHAPE* seg = new FP_SHAPE( aFootprint, SHAPE_T::SEGMENT );
|
||||||
|
|
||||||
|
seg->SetStart( aElem.start );
|
||||||
|
seg->SetEnd( aElem.end );
|
||||||
|
seg->SetStroke( STROKE_PARAMS( width, PLOT_DASH_TYPE::SOLID ) );
|
||||||
|
seg->SetLayer( layerExpansionMask.first );
|
||||||
|
|
||||||
|
seg->SetLocalCoord();
|
||||||
|
aFootprint->Add( seg, ADD_MODE::APPEND );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3370,6 +3466,7 @@ void ALTIUM_PCB::HelperPcpShapeAsBoardKeepoutRegion( const PCB_SHAPE& aShape,
|
||||||
m_board->Add( zone, ADD_MODE::APPEND );
|
m_board->Add( zone, ADD_MODE::APPEND );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ALTIUM_PCB::HelperPcpShapeAsFootprintKeepoutRegion( FOOTPRINT* aFootprint,
|
void ALTIUM_PCB::HelperPcpShapeAsFootprintKeepoutRegion( FOOTPRINT* aFootprint,
|
||||||
const PCB_SHAPE& aShape,
|
const PCB_SHAPE& aShape,
|
||||||
ALTIUM_LAYER aAltiumLayer )
|
ALTIUM_LAYER aAltiumLayer )
|
||||||
|
@ -3394,3 +3491,58 @@ void ALTIUM_PCB::HelperPcpShapeAsFootprintKeepoutRegion( FOOTPRINT* aFootp
|
||||||
// TODO: zone->SetLocalCoord(); missing?
|
// TODO: zone->SetLocalCoord(); missing?
|
||||||
aFootprint->Add( zone, ADD_MODE::APPEND );
|
aFootprint->Add( zone, ADD_MODE::APPEND );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::vector<std::pair<PCB_LAYER_ID, int>> ALTIUM_PCB::HelperGetSolderAndPasteMaskExpansions(
|
||||||
|
const ALTIUM_RECORD aType, const int aPrimitiveIndex, const ALTIUM_LAYER aAltiumLayer )
|
||||||
|
{
|
||||||
|
if( m_extendedPrimitiveInformationMaps.count( aType ) == 0 )
|
||||||
|
return {}; // there is nothing to parse
|
||||||
|
|
||||||
|
auto elems =
|
||||||
|
m_extendedPrimitiveInformationMaps[ALTIUM_RECORD::TRACK].equal_range( aPrimitiveIndex );
|
||||||
|
if( elems.first == elems.second )
|
||||||
|
return {}; // there is nothing to parse
|
||||||
|
|
||||||
|
std::vector<std::pair<PCB_LAYER_ID, int>> layerExpansionPairs;
|
||||||
|
|
||||||
|
for( auto it = elems.first; it != elems.second; ++it )
|
||||||
|
{
|
||||||
|
const AEXTENDED_PRIMITIVE_INFORMATION& pInf = it->second;
|
||||||
|
|
||||||
|
if( pInf.type == AEXTENDED_PRIMITIVE_INFORMATION_TYPE::MASK )
|
||||||
|
{
|
||||||
|
if( pInf.soldermaskexpansionmode == ALTIUM_MODE::MANUAL
|
||||||
|
|| pInf.soldermaskexpansionmode == ALTIUM_MODE::RULE )
|
||||||
|
{
|
||||||
|
// TODO: what layers can lead to solder or paste mask usage? E.g. KEEP_OUT_LAYER and other top/bottom layers
|
||||||
|
if( aAltiumLayer == ALTIUM_LAYER::TOP_LAYER
|
||||||
|
|| aAltiumLayer == ALTIUM_LAYER::MULTI_LAYER )
|
||||||
|
{
|
||||||
|
layerExpansionPairs.emplace_back( F_Mask, pInf.soldermaskexpansionmanual );
|
||||||
|
}
|
||||||
|
if( aAltiumLayer == ALTIUM_LAYER::BOTTOM_LAYER
|
||||||
|
|| aAltiumLayer == ALTIUM_LAYER::MULTI_LAYER )
|
||||||
|
{
|
||||||
|
layerExpansionPairs.emplace_back( B_Mask, pInf.soldermaskexpansionmanual );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( pInf.pastemaskexpansionmode == ALTIUM_MODE::MANUAL
|
||||||
|
|| pInf.pastemaskexpansionmode == ALTIUM_MODE::RULE )
|
||||||
|
{
|
||||||
|
if( aAltiumLayer == ALTIUM_LAYER::TOP_LAYER
|
||||||
|
|| aAltiumLayer == ALTIUM_LAYER::MULTI_LAYER )
|
||||||
|
{
|
||||||
|
layerExpansionPairs.emplace_back( F_Paste, pInf.pastemaskexpansionmanual );
|
||||||
|
}
|
||||||
|
if( aAltiumLayer == ALTIUM_LAYER::BOTTOM_LAYER
|
||||||
|
|| aAltiumLayer == ALTIUM_LAYER::MULTI_LAYER )
|
||||||
|
{
|
||||||
|
layerExpansionPairs.emplace_back( B_Paste, pInf.pastemaskexpansionmanual );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return layerExpansionPairs;
|
||||||
|
}
|
|
@ -149,9 +149,9 @@ private:
|
||||||
void ParseArcs6Data( const ALTIUM_COMPOUND_FILE& aAltiumPcbFile,
|
void ParseArcs6Data( const ALTIUM_COMPOUND_FILE& aAltiumPcbFile,
|
||||||
const CFB::COMPOUND_FILE_ENTRY* aEntry );
|
const CFB::COMPOUND_FILE_ENTRY* aEntry );
|
||||||
void ConvertArcs6ToPcbShape( const AARC6& aElem, PCB_SHAPE* aShape );
|
void ConvertArcs6ToPcbShape( const AARC6& aElem, PCB_SHAPE* aShape );
|
||||||
void ConvertArcs6ToBoardItem( const AARC6& aElem );
|
void ConvertArcs6ToBoardItem( const AARC6& aElem, const int aPrimitiveIndex );
|
||||||
void ConvertArcs6ToFootprintItem( FOOTPRINT* aFootprint, const AARC6& aElem,
|
void ConvertArcs6ToFootprintItem( FOOTPRINT* aFootprint, const AARC6& aElem,
|
||||||
const bool aIsBoardImport );
|
const int aPrimitiveIndex, const bool aIsBoardImport );
|
||||||
void ConvertArcs6ToBoardItemOnLayer( const AARC6& aElem, PCB_LAYER_ID aLayer );
|
void ConvertArcs6ToBoardItemOnLayer( const AARC6& aElem, PCB_LAYER_ID aLayer );
|
||||||
void ConvertArcs6ToFootprintItemOnLayer( FOOTPRINT* aFootprint, const AARC6& aElem,
|
void ConvertArcs6ToFootprintItemOnLayer( FOOTPRINT* aFootprint, const AARC6& aElem,
|
||||||
PCB_LAYER_ID aLayer );
|
PCB_LAYER_ID aLayer );
|
||||||
|
@ -168,9 +168,9 @@ private:
|
||||||
const CFB::COMPOUND_FILE_ENTRY* aEntry );
|
const CFB::COMPOUND_FILE_ENTRY* aEntry );
|
||||||
void ParseTracks6Data( const ALTIUM_COMPOUND_FILE& aAltiumPcbFile,
|
void ParseTracks6Data( const ALTIUM_COMPOUND_FILE& aAltiumPcbFile,
|
||||||
const CFB::COMPOUND_FILE_ENTRY* aEntry );
|
const CFB::COMPOUND_FILE_ENTRY* aEntry );
|
||||||
void ConvertTracks6ToBoardItem( const ATRACK6& aElem );
|
void ConvertTracks6ToBoardItem( const ATRACK6& aElem, const int aPrimitiveIndex );
|
||||||
void ConvertTracks6ToFootprintItem( FOOTPRINT* aFootprint, const ATRACK6& aElem,
|
void ConvertTracks6ToFootprintItem( FOOTPRINT* aFootprint, const ATRACK6& aElem,
|
||||||
const bool aIsBoardImport );
|
const int aPrimitiveIndex, const bool aIsBoardImport );
|
||||||
void ConvertTracks6ToBoardItemOnLayer( const ATRACK6& aElem, PCB_LAYER_ID aLayer );
|
void ConvertTracks6ToBoardItemOnLayer( const ATRACK6& aElem, PCB_LAYER_ID aLayer );
|
||||||
void ConvertTracks6ToFootprintItemOnLayer( FOOTPRINT* aFootprint, const ATRACK6& aElem,
|
void ConvertTracks6ToFootprintItemOnLayer( FOOTPRINT* aFootprint, const ATRACK6& aElem,
|
||||||
PCB_LAYER_ID aLayer );
|
PCB_LAYER_ID aLayer );
|
||||||
|
@ -201,6 +201,8 @@ private:
|
||||||
void ConvertShapeBasedRegions6ToFootprintItemOnLayer( FOOTPRINT* aFootprint,
|
void ConvertShapeBasedRegions6ToFootprintItemOnLayer( FOOTPRINT* aFootprint,
|
||||||
const AREGION6& aElem,
|
const AREGION6& aElem,
|
||||||
PCB_LAYER_ID aLayer );
|
PCB_LAYER_ID aLayer );
|
||||||
|
void ParseExtendedPrimitiveInformationData( const ALTIUM_COMPOUND_FILE& aAltiumPcbFile,
|
||||||
|
const CFB::COMPOUND_FILE_ENTRY* aEntry );
|
||||||
void ParseRegions6Data( const ALTIUM_COMPOUND_FILE& aAltiumPcbFile,
|
void ParseRegions6Data( const ALTIUM_COMPOUND_FILE& aAltiumPcbFile,
|
||||||
const CFB::COMPOUND_FILE_ENTRY* aEntry );
|
const CFB::COMPOUND_FILE_ENTRY* aEntry );
|
||||||
void ParseWideStrings6Data( const ALTIUM_COMPOUND_FILE& aAltiumPcbFile,
|
void ParseWideStrings6Data( const ALTIUM_COMPOUND_FILE& aAltiumPcbFile,
|
||||||
|
@ -222,6 +224,10 @@ private:
|
||||||
void HelperPcpShapeAsFootprintKeepoutRegion( FOOTPRINT* aFootprint, const PCB_SHAPE& aShape,
|
void HelperPcpShapeAsFootprintKeepoutRegion( FOOTPRINT* aFootprint, const PCB_SHAPE& aShape,
|
||||||
ALTIUM_LAYER aAltiumLayer );
|
ALTIUM_LAYER aAltiumLayer );
|
||||||
|
|
||||||
|
std::vector<std::pair<PCB_LAYER_ID, int>>
|
||||||
|
HelperGetSolderAndPasteMaskExpansions( const ALTIUM_RECORD aType, const int aPrimitiveIndex,
|
||||||
|
const ALTIUM_LAYER aAltiumLayer );
|
||||||
|
|
||||||
FOOTPRINT* HelperGetFootprint( uint16_t aComponent ) const;
|
FOOTPRINT* HelperGetFootprint( uint16_t aComponent ) const;
|
||||||
PCB_SHAPE* HelperCreateAndAddShape( uint16_t aComponent );
|
PCB_SHAPE* HelperCreateAndAddShape( uint16_t aComponent );
|
||||||
void HelperShapeSetLocalCoord( PCB_SHAPE* aShape, uint16_t aComponent );
|
void HelperShapeSetLocalCoord( PCB_SHAPE* aShape, uint16_t aComponent );
|
||||||
|
@ -236,6 +242,8 @@ private:
|
||||||
size_t m_num_nets;
|
size_t m_num_nets;
|
||||||
std::map<ALTIUM_LAYER, PCB_LAYER_ID> m_layermap; // used to correctly map copper layers
|
std::map<ALTIUM_LAYER, PCB_LAYER_ID> m_layermap; // used to correctly map copper layers
|
||||||
std::map<ALTIUM_RULE_KIND, std::vector<ARULE6>> m_rules;
|
std::map<ALTIUM_RULE_KIND, std::vector<ARULE6>> m_rules;
|
||||||
|
std::map<ALTIUM_RECORD, std::multimap<int, const AEXTENDED_PRIMITIVE_INFORMATION>>
|
||||||
|
m_extendedPrimitiveInformationMaps;
|
||||||
|
|
||||||
std::map<ALTIUM_LAYER, ZONE*> m_outer_plane;
|
std::map<ALTIUM_LAYER, ZONE*> m_outer_plane;
|
||||||
|
|
||||||
|
|
|
@ -32,4 +32,6 @@
|
||||||
(stroke (width 0.5) (type solid)) (layer "F.Cu") (tstamp e16db058-fa43-40bf-9cff-c2ed4fab6ab5))
|
(stroke (width 0.5) (type solid)) (layer "F.Cu") (tstamp e16db058-fa43-40bf-9cff-c2ed4fab6ab5))
|
||||||
(fp_line (start 13 5) (end 13 -5)
|
(fp_line (start 13 5) (end 13 -5)
|
||||||
(stroke (width 0.5) (type solid)) (layer "F.Cu") (tstamp 3de27c1c-897a-4a6c-b0f7-6b3c6fd91fd1))
|
(stroke (width 0.5) (type solid)) (layer "F.Cu") (tstamp 3de27c1c-897a-4a6c-b0f7-6b3c6fd91fd1))
|
||||||
|
(fp_line (start 13 5) (end 13 -5)
|
||||||
|
(stroke (width 0.3) (type solid)) (layer "F.Mask") (tstamp 3466cda7-8b6d-422c-92e4-d22bbe2d4a4d))
|
||||||
)
|
)
|
||||||
|
|
|
@ -202,4 +202,12 @@
|
||||||
(stroke (width 0.5) (type solid)) (layer "B.Cu") (tstamp 775b50f1-c021-45e5-b4f4-3da4bfa305be))
|
(stroke (width 0.5) (type solid)) (layer "B.Cu") (tstamp 775b50f1-c021-45e5-b4f4-3da4bfa305be))
|
||||||
(fp_line (start -10 2) (end 10 2)
|
(fp_line (start -10 2) (end 10 2)
|
||||||
(stroke (width 0.5) (type solid)) (layer "B.Cu") (tstamp ee19307b-ab88-4d6f-9dfb-4149660b5a08))
|
(stroke (width 0.5) (type solid)) (layer "B.Cu") (tstamp ee19307b-ab88-4d6f-9dfb-4149660b5a08))
|
||||||
|
(fp_line (start -10 -2) (end 10 -2)
|
||||||
|
(stroke (width 1.5) (type solid)) (layer "B.Mask") (tstamp 786b6072-5772-4bc1-8eeb-6c4e19f2a91b))
|
||||||
|
(fp_line (start -10 0) (end 10 0)
|
||||||
|
(stroke (width 0.3) (type solid)) (layer "B.Mask") (tstamp 632acde9-b7fd-4f04-8cb4-d2cbb06b3595))
|
||||||
|
(fp_line (start -10 -2) (end 10 -2)
|
||||||
|
(stroke (width 1.5) (type solid)) (layer "F.Mask") (tstamp 4d609e7c-74c9-4ae9-a26d-946ff00c167d))
|
||||||
|
(fp_line (start -10 0) (end 10 0)
|
||||||
|
(stroke (width 0.3) (type solid)) (layer "F.Mask") (tstamp 0f41a909-27c4-4be2-9d5e-9ae2108c8ff5))
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue