mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-09-13 17:53:11 +02:00
ADDED: Support for IPC-4761 Via protection features
Fixes https://gitlab.com/kicad/code/kicad/-/work_items/18837
This commit is contained in:
parent
5bdeb40d66
commit
3768221d9c
@ -294,15 +294,31 @@ message PadStackLayer
|
||||
|
||||
enum SolderMaskMode
|
||||
{
|
||||
SMM_UNKOWN = 0;
|
||||
SMM_UNKNOWN = 0;
|
||||
SMM_MASKED = 1;
|
||||
SMM_UNMASKED = 2;
|
||||
SMM_FROM_DESIGN_RULES = 3;
|
||||
}
|
||||
|
||||
enum ViaCoveringMode
|
||||
{
|
||||
VCM_UNKNOWN = 0;
|
||||
VCM_COVERED = 1;
|
||||
VCM_UNCOVERED = 2;
|
||||
VCM_FROM_DESIGN_RULES = 3;
|
||||
}
|
||||
|
||||
enum ViaPluggingMode
|
||||
{
|
||||
VPM_UNKNOWN = 0;
|
||||
VPM_PLUGGED = 1;
|
||||
VPM_UNPLUGGED = 2;
|
||||
VPM_FROM_DESIGN_RULES = 3;
|
||||
}
|
||||
|
||||
enum SolderPasteMode
|
||||
{
|
||||
SPM_UNKOWN = 0;
|
||||
SPM_UNKNOWN = 0;
|
||||
SPM_PASTE = 1;
|
||||
SPM_NO_PASTE = 2;
|
||||
SPM_FROM_DESIGN_RULES = 3;
|
||||
@ -319,6 +335,9 @@ message PadStackOuterLayer
|
||||
|
||||
// NOTE: At present, KiCad does not support different solder paste expansion settings for the top and bottom layers
|
||||
SolderPasteOverrides solder_paste_settings = 4;
|
||||
|
||||
ViaPluggingMode plugging_mode = 5;
|
||||
ViaCoveringMode covering_mode = 6;
|
||||
}
|
||||
|
||||
enum DrillShape
|
||||
@ -329,6 +348,22 @@ enum DrillShape
|
||||
DS_UNDEFINED = 3;
|
||||
}
|
||||
|
||||
enum ViaDrillCappingMode
|
||||
{
|
||||
VDCM_UNKNOWN = 0;
|
||||
VDCM_CAPPED = 1;
|
||||
VDCM_UNCAPPED = 2;
|
||||
VDCM_FROM_DESIGN_RULES = 3;
|
||||
}
|
||||
|
||||
enum ViaDrillFillingMode
|
||||
{
|
||||
VDFM_UNKNOWN = 0;
|
||||
VDFM_FILLED = 1;
|
||||
VDFM_UNFILLED = 2;
|
||||
VDFM_FROM_DESIGN_RULES = 3;
|
||||
}
|
||||
|
||||
message DrillProperties
|
||||
{
|
||||
// Lowest (closest to F_Cu) layer this drill exists on.
|
||||
@ -342,6 +377,10 @@ message DrillProperties
|
||||
kiapi.common.types.Vector2 diameter = 3;
|
||||
|
||||
DrillShape shape = 4;
|
||||
|
||||
ViaDrillCappingMode capped = 5;
|
||||
|
||||
ViaDrillFillingMode filled = 6;
|
||||
}
|
||||
|
||||
// A pad stack definition for a multilayer pad or via.
|
||||
|
@ -157,7 +157,8 @@ wxString GbrMakeProjectGUIDfromString( const wxString& aText )
|
||||
|
||||
|
||||
std::string GBR_APERTURE_METADATA::FormatAttribute( GBR_APERTURE_ATTRIB aAttribute,
|
||||
bool aUseX1StructuredComment )
|
||||
bool aUseX1StructuredComment,
|
||||
const std::string& aCustomAttribute )
|
||||
{
|
||||
std::string attribute_string; // the specific aperture attribute (TA.xxx)
|
||||
std::string comment_string; // a optional G04 comment line to write before the TA. line
|
||||
@ -321,7 +322,9 @@ std::string GBR_APERTURE_METADATA::FormatAttribute( GBR_APERTURE_ATTRIB aAttribu
|
||||
attribute_string = "TA.AperFunction,ComponentOutline,Courtyard";
|
||||
break;
|
||||
|
||||
break;
|
||||
case GBR_APERTURE_ATTRIB_OTHER:
|
||||
attribute_string = "TA.AperFunction,Other," + aCustomAttribute;
|
||||
break;
|
||||
}
|
||||
|
||||
std::string full_attribute_string;
|
||||
|
@ -37,6 +37,14 @@ void FormatBool( OUTPUTFORMATTER* aOut, const wxString& aKey, bool aValue )
|
||||
aOut->Print( "(%ls %s)", aKey.wc_str(), aValue ? "yes" : "no" );
|
||||
}
|
||||
|
||||
void FormatOptBool( OUTPUTFORMATTER* aOut, const wxString& aKey, std::optional<bool> aValue )
|
||||
{
|
||||
if( aValue.has_value() )
|
||||
FormatBool( aOut, aKey, aValue.value() );
|
||||
else
|
||||
aOut->Print( "(%ls none)", aKey.wc_str() );
|
||||
}
|
||||
|
||||
|
||||
void FormatUuid( OUTPUTFORMATTER* aOut, const KIID& aUuid )
|
||||
{
|
||||
|
@ -70,7 +70,8 @@ JOB_EXPORT_PCB_DRILL::JOB_EXPORT_PCB_DRILL() :
|
||||
m_zeroFormat( ZEROS_FORMAT::DECIMAL ),
|
||||
m_mapFormat( MAP_FORMAT::PDF ),
|
||||
m_gerberPrecision( 5 ),
|
||||
m_generateMap( false )
|
||||
m_generateMap( false ),
|
||||
m_generateTenting( false )
|
||||
{
|
||||
m_params.emplace_back( new JOB_PARAM<bool>( "excellon.mirror_y",
|
||||
&m_excellonMirrorY,
|
||||
@ -108,6 +109,10 @@ JOB_EXPORT_PCB_DRILL::JOB_EXPORT_PCB_DRILL() :
|
||||
&m_generateMap,
|
||||
m_generateMap ) );
|
||||
|
||||
m_params.emplace_back( new JOB_PARAM<bool>( "generate_tenting",
|
||||
&m_generateTenting,
|
||||
m_generateTenting ) );
|
||||
|
||||
m_params.emplace_back( new JOB_PARAM<MAP_FORMAT>( "map_format",
|
||||
&m_mapFormat,
|
||||
m_mapFormat ) );
|
||||
|
@ -89,6 +89,8 @@ public:
|
||||
int m_gerberPrecision;
|
||||
|
||||
bool m_generateMap;
|
||||
|
||||
bool m_generateTenting;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -333,6 +333,10 @@ teardrop
|
||||
teardrops
|
||||
tedit
|
||||
tenting
|
||||
covering
|
||||
plugging
|
||||
filling
|
||||
capping
|
||||
text_frame
|
||||
text_position_mode
|
||||
thermal_width
|
||||
|
@ -405,17 +405,24 @@ void GERBER_PLOTTER::SetCurrentLineWidth( int aWidth, void* aData )
|
||||
wxASSERT_MSG( aWidth >= 0, "Plotter called to set negative pen width" );
|
||||
|
||||
GBR_METADATA* gbr_metadata = static_cast<GBR_METADATA*>( aData );
|
||||
int aperture_attribute = gbr_metadata ? gbr_metadata->GetApertureAttrib() : 0;
|
||||
int aperture_attribute = 0;
|
||||
std::string custom_attribute = "";
|
||||
if( gbr_metadata )
|
||||
{
|
||||
aperture_attribute = gbr_metadata->GetApertureAttrib();
|
||||
custom_attribute = gbr_metadata->GetCustomAttribute();
|
||||
}
|
||||
|
||||
selectAperture( VECTOR2I( aWidth, aWidth ), 0, ANGLE_0, APERTURE::AT_PLOTTING,
|
||||
aperture_attribute );
|
||||
aperture_attribute, custom_attribute );
|
||||
m_currentPenWidth = aWidth;
|
||||
}
|
||||
|
||||
|
||||
int GERBER_PLOTTER::GetOrCreateAperture( const VECTOR2I& aSize, int aRadius,
|
||||
const EDA_ANGLE& aRotation, APERTURE::APERTURE_TYPE aType,
|
||||
int aApertureAttribute )
|
||||
int aApertureAttribute,
|
||||
const std::string& aCustomAttribute )
|
||||
{
|
||||
int last_D_code = 9;
|
||||
|
||||
@ -425,10 +432,13 @@ int GERBER_PLOTTER::GetOrCreateAperture( const VECTOR2I& aSize, int aRadius,
|
||||
APERTURE* tool = &m_apertures[idx];
|
||||
last_D_code = tool->m_DCode;
|
||||
|
||||
if( (tool->m_Type == aType) && (tool->m_Size == aSize) &&
|
||||
(tool->m_Radius == aRadius) && (tool->m_Rotation == aRotation) &&
|
||||
(tool->m_ApertureAttribute == aApertureAttribute) )
|
||||
if( ( tool->m_Type == aType ) && ( tool->m_Size == aSize ) && ( tool->m_Radius == aRadius )
|
||||
&& ( tool->m_Rotation == aRotation )
|
||||
&& ( tool->m_ApertureAttribute == aApertureAttribute )
|
||||
&& ( tool->m_CustomAttribute == aCustomAttribute ) )
|
||||
{
|
||||
return idx;
|
||||
}
|
||||
}
|
||||
|
||||
// Allocate a new aperture
|
||||
@ -439,6 +449,7 @@ int GERBER_PLOTTER::GetOrCreateAperture( const VECTOR2I& aSize, int aRadius,
|
||||
new_tool.m_Rotation = aRotation;
|
||||
new_tool.m_DCode = last_D_code + 1;
|
||||
new_tool.m_ApertureAttribute = aApertureAttribute;
|
||||
new_tool.m_CustomAttribute = aCustomAttribute;
|
||||
|
||||
m_apertures.push_back( new_tool );
|
||||
|
||||
@ -448,7 +459,8 @@ int GERBER_PLOTTER::GetOrCreateAperture( const VECTOR2I& aSize, int aRadius,
|
||||
|
||||
int GERBER_PLOTTER::GetOrCreateAperture( const std::vector<VECTOR2I>& aCorners,
|
||||
const EDA_ANGLE& aRotation, APERTURE::APERTURE_TYPE aType,
|
||||
int aApertureAttribute )
|
||||
int aApertureAttribute,
|
||||
const std::string& aCustomAttribute )
|
||||
{
|
||||
int last_D_code = 9;
|
||||
|
||||
@ -468,12 +480,12 @@ int GERBER_PLOTTER::GetOrCreateAperture( const std::vector<VECTOR2I>& aCorners,
|
||||
{
|
||||
APERTURE* tool = &m_apertures[idx];
|
||||
|
||||
last_D_code = tool->m_DCode;
|
||||
last_D_code = tool->m_DCode;
|
||||
|
||||
if( (tool->m_Type == aType) &&
|
||||
(tool->m_Corners.size() == aCorners.size() ) &&
|
||||
(tool->m_Rotation == aRotation) &&
|
||||
(tool->m_ApertureAttribute == aApertureAttribute) )
|
||||
if( ( tool->m_Type == aType ) && ( tool->m_Corners.size() == aCorners.size() )
|
||||
&& ( tool->m_Rotation == aRotation )
|
||||
&& ( tool->m_ApertureAttribute == aApertureAttribute )
|
||||
&& ( tool->m_CustomAttribute == aCustomAttribute ) )
|
||||
{
|
||||
// A candidate is found. the corner lists must be similar
|
||||
bool is_same = polyCompare( tool->m_Corners, aCorners );
|
||||
@ -493,6 +505,7 @@ int GERBER_PLOTTER::GetOrCreateAperture( const std::vector<VECTOR2I>& aCorners,
|
||||
new_tool.m_Rotation = aRotation;
|
||||
new_tool.m_DCode = last_D_code + 1;
|
||||
new_tool.m_ApertureAttribute = aApertureAttribute;
|
||||
new_tool.m_CustomAttribute = aCustomAttribute;
|
||||
|
||||
m_apertures.push_back( new_tool );
|
||||
|
||||
@ -501,7 +514,8 @@ int GERBER_PLOTTER::GetOrCreateAperture( const std::vector<VECTOR2I>& aCorners,
|
||||
|
||||
|
||||
void GERBER_PLOTTER::selectAperture( const VECTOR2I& aSize, int aRadius, const EDA_ANGLE& aRotation,
|
||||
APERTURE::APERTURE_TYPE aType, int aApertureAttribute )
|
||||
APERTURE::APERTURE_TYPE aType, int aApertureAttribute,
|
||||
const std::string& aCustomAttribute )
|
||||
{
|
||||
bool change = ( m_currentApertureIdx < 0 ) ||
|
||||
( m_apertures[m_currentApertureIdx].m_Type != aType ) ||
|
||||
@ -510,13 +524,16 @@ void GERBER_PLOTTER::selectAperture( const VECTOR2I& aSize, int aRadius, const E
|
||||
( m_apertures[m_currentApertureIdx].m_Rotation != aRotation );
|
||||
|
||||
if( !change )
|
||||
change = m_apertures[m_currentApertureIdx].m_ApertureAttribute != aApertureAttribute;
|
||||
{
|
||||
change = ( m_apertures[m_currentApertureIdx].m_ApertureAttribute != aApertureAttribute )
|
||||
|| ( m_apertures[m_currentApertureIdx].m_CustomAttribute != aCustomAttribute );
|
||||
}
|
||||
|
||||
if( change )
|
||||
{
|
||||
// Pick an existing aperture or create a new one
|
||||
m_currentApertureIdx = GetOrCreateAperture( aSize, aRadius, aRotation, aType,
|
||||
aApertureAttribute );
|
||||
aApertureAttribute, aCustomAttribute );
|
||||
fprintf( m_outputFile, "D%d*\n", m_apertures[m_currentApertureIdx].m_DCode );
|
||||
}
|
||||
}
|
||||
@ -524,7 +541,7 @@ void GERBER_PLOTTER::selectAperture( const VECTOR2I& aSize, int aRadius, const E
|
||||
|
||||
void GERBER_PLOTTER::selectAperture( const std::vector<VECTOR2I>& aCorners,
|
||||
const EDA_ANGLE& aRotation, APERTURE::APERTURE_TYPE aType,
|
||||
int aApertureAttribute )
|
||||
int aApertureAttribute, const std::string& aCustomAttribute )
|
||||
{
|
||||
bool change = ( m_currentApertureIdx < 0 ) ||
|
||||
( m_apertures[m_currentApertureIdx].m_Type != aType ) ||
|
||||
@ -544,30 +561,43 @@ void GERBER_PLOTTER::selectAperture( const std::vector<VECTOR2I>& aCorners,
|
||||
}
|
||||
|
||||
if( !change )
|
||||
change = m_apertures[m_currentApertureIdx].m_ApertureAttribute != aApertureAttribute;
|
||||
{
|
||||
change = ( m_apertures[m_currentApertureIdx].m_ApertureAttribute != aApertureAttribute )
|
||||
|| ( m_apertures[m_currentApertureIdx].m_CustomAttribute != aCustomAttribute );
|
||||
}
|
||||
|
||||
if( change )
|
||||
{
|
||||
// Pick an existing aperture or create a new one
|
||||
m_currentApertureIdx = GetOrCreateAperture( aCorners, aRotation, aType,
|
||||
aApertureAttribute );
|
||||
m_currentApertureIdx = GetOrCreateAperture( aCorners, aRotation, aType, aApertureAttribute,
|
||||
aCustomAttribute );
|
||||
fprintf( m_outputFile, "D%d*\n", m_apertures[m_currentApertureIdx].m_DCode );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GERBER_PLOTTER::selectAperture( int aDiameter, const EDA_ANGLE& aPolygonRotation,
|
||||
APERTURE::APERTURE_TYPE aType, int aApertureAttribute )
|
||||
void GERBER_PLOTTER::selectApertureWithAttributes( const VECTOR2I& aPos, GBR_METADATA* aGbrMetadata,
|
||||
VECTOR2I aSize, int aRadius,
|
||||
const EDA_ANGLE& aAngle,
|
||||
APERTURE::APERTURE_TYPE aType )
|
||||
{
|
||||
// Pick an existing aperture or create a new one, matching the
|
||||
// aDiameter, aPolygonRotation, type and attributes for type =
|
||||
// AT_REGULAR_POLY3 to AT_REGULAR_POLY12
|
||||
VECTOR2D pos_dev = userToDeviceCoordinates( aPos );
|
||||
|
||||
wxASSERT( aType>= APERTURE::APERTURE_TYPE::AT_REGULAR_POLY3 &&
|
||||
aType <= APERTURE::APERTURE_TYPE::AT_REGULAR_POLY12 );
|
||||
int aperture_attribute = 0;
|
||||
std::string custom_attribute = "";
|
||||
|
||||
VECTOR2I size( aDiameter, (int) ( aPolygonRotation.AsDegrees() * 1000.0 ) );
|
||||
selectAperture( VECTOR2I( 0, 0 ), aDiameter / 2, aPolygonRotation, aType, aApertureAttribute );
|
||||
if( aGbrMetadata )
|
||||
{
|
||||
aperture_attribute = aGbrMetadata->GetApertureAttrib();
|
||||
custom_attribute = aGbrMetadata->GetCustomAttribute();
|
||||
}
|
||||
|
||||
selectAperture( aSize, aRadius, aAngle, aType, aperture_attribute, custom_attribute );
|
||||
|
||||
if( aGbrMetadata )
|
||||
formatNetAttribute( &aGbrMetadata->m_NetlistMetadata );
|
||||
|
||||
emitDcode( pos_dev, 3 );
|
||||
}
|
||||
|
||||
|
||||
@ -595,8 +625,10 @@ void GERBER_PLOTTER::writeApertureList()
|
||||
if( attribute != m_apertureAttribute )
|
||||
{
|
||||
fputs( GBR_APERTURE_METADATA::FormatAttribute(
|
||||
(GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB) attribute,
|
||||
useX1StructuredComment ).c_str(), m_outputFile );
|
||||
(GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB) attribute,
|
||||
useX1StructuredComment, tool.m_CustomAttribute )
|
||||
.c_str(),
|
||||
m_outputFile );
|
||||
}
|
||||
|
||||
fprintf( m_outputFile, "%%ADD%d", tool.m_DCode );
|
||||
@ -1291,15 +1323,7 @@ void GERBER_PLOTTER::FlashPadCircle( const VECTOR2I& pos, int diametre, OUTLINE_
|
||||
}
|
||||
else
|
||||
{
|
||||
VECTOR2D pos_dev = userToDeviceCoordinates( pos );
|
||||
|
||||
int aperture_attrib = gbr_metadata ? gbr_metadata->GetApertureAttrib() : 0;
|
||||
selectAperture( size, 0, ANGLE_0, APERTURE::AT_CIRCLE, aperture_attrib );
|
||||
|
||||
if( gbr_metadata )
|
||||
formatNetAttribute( &gbr_metadata->m_NetlistMetadata );
|
||||
|
||||
emitDcode( pos_dev, 3 );
|
||||
selectApertureWithAttributes( pos, gbr_metadata, size, 0, ANGLE_0, APERTURE::AT_CIRCLE );
|
||||
}
|
||||
}
|
||||
|
||||
@ -1320,14 +1344,7 @@ void GERBER_PLOTTER::FlashPadOval( const VECTOR2I& aPos, const VECTOR2I& aSize,
|
||||
if( orient.IsCardinal90() )
|
||||
std::swap( size.x, size.y );
|
||||
|
||||
VECTOR2D pos_device = userToDeviceCoordinates( aPos );
|
||||
int aperture_attrib = gbr_metadata ? gbr_metadata->GetApertureAttrib() : 0;
|
||||
selectAperture( size, 0, ANGLE_0, APERTURE::AT_OVAL, aperture_attrib );
|
||||
|
||||
if( gbr_metadata )
|
||||
formatNetAttribute( &gbr_metadata->m_NetlistMetadata );
|
||||
|
||||
emitDcode( pos_device, 3 );
|
||||
selectApertureWithAttributes( aPos, gbr_metadata, size, 0, ANGLE_0, APERTURE::AT_OVAL );
|
||||
}
|
||||
else // Plot pad as region.
|
||||
// Only regions and flashed items accept a object attribute TO.P for the pin name
|
||||
@ -1351,14 +1368,8 @@ void GERBER_PLOTTER::FlashPadOval( const VECTOR2I& aPos, const VECTOR2I& aSize,
|
||||
orient -= ANGLE_180;
|
||||
}
|
||||
|
||||
VECTOR2D pos_device = userToDeviceCoordinates( aPos );
|
||||
int aperture_attrib = gbr_metadata ? gbr_metadata->GetApertureAttrib() : 0;
|
||||
selectAperture( size, 0, orient, APERTURE::AM_ROTATED_OVAL, aperture_attrib );
|
||||
|
||||
if( gbr_metadata )
|
||||
formatNetAttribute( &gbr_metadata->m_NetlistMetadata );
|
||||
|
||||
emitDcode( pos_device, 3 );
|
||||
selectApertureWithAttributes( aPos, gbr_metadata, size, 0, orient,
|
||||
APERTURE::AM_ROTATED_OVAL );
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1415,14 +1426,7 @@ void GERBER_PLOTTER::FlashPadRect( const VECTOR2I& pos, const VECTOR2I& aSize,
|
||||
}
|
||||
else
|
||||
{
|
||||
VECTOR2D pos_device = userToDeviceCoordinates( pos );
|
||||
int aperture_attrib = gbr_metadata ? gbr_metadata->GetApertureAttrib() : 0;
|
||||
selectAperture( size, 0, ANGLE_0, APERTURE::AT_RECT, aperture_attrib );
|
||||
|
||||
if( gbr_metadata )
|
||||
formatNetAttribute( &gbr_metadata->m_NetlistMetadata );
|
||||
|
||||
emitDcode( pos_device, 3 );
|
||||
selectApertureWithAttributes( pos, gbr_metadata, size, 0, ANGLE_0, APERTURE::AT_RECT );
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -1432,14 +1436,8 @@ void GERBER_PLOTTER::FlashPadRect( const VECTOR2I& pos, const VECTOR2I& aSize,
|
||||
{
|
||||
m_hasApertureRotRect = true;
|
||||
|
||||
VECTOR2D pos_device = userToDeviceCoordinates( pos );
|
||||
int aperture_attrib = gbr_metadata ? gbr_metadata->GetApertureAttrib() : 0;
|
||||
selectAperture( size, 0, aOrient, APERTURE::AM_ROT_RECT, aperture_attrib );
|
||||
|
||||
if( gbr_metadata )
|
||||
formatNetAttribute( &gbr_metadata->m_NetlistMetadata );
|
||||
|
||||
emitDcode( pos_device, 3 );
|
||||
selectApertureWithAttributes( pos, gbr_metadata, size, 0, aOrient,
|
||||
APERTURE::AM_ROT_RECT );
|
||||
}
|
||||
else
|
||||
#endif
|
||||
@ -1504,15 +1502,8 @@ void GERBER_PLOTTER::FlashPadRoundRect( const VECTOR2I& aPadPos, const VECTOR2I&
|
||||
{
|
||||
m_hasApertureRoundRect = true;
|
||||
|
||||
VECTOR2D pos_dev = userToDeviceCoordinates( aPadPos );
|
||||
int aperture_attrib = gbr_metadata ? gbr_metadata->GetApertureAttrib() : 0;
|
||||
selectAperture( aSize, aCornerRadius, aOrient, APERTURE::AM_ROUND_RECT,
|
||||
aperture_attrib );
|
||||
|
||||
if( gbr_metadata )
|
||||
formatNetAttribute( &gbr_metadata->m_NetlistMetadata );
|
||||
|
||||
emitDcode( pos_dev, 3 );
|
||||
selectApertureWithAttributes( aPadPos, gbr_metadata, aSize, aCornerRadius, aOrient,
|
||||
APERTURE::AM_ROUND_RECT );
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1732,7 +1723,8 @@ void GERBER_PLOTTER::FlashPadCustom( const VECTOR2I& aPadPos, const VECTOR2I& aS
|
||||
|
||||
VECTOR2D pos_dev = userToDeviceCoordinates( aPadPos );
|
||||
selectAperture( cornerList, aOrient, APERTURE::AM_FREE_POLYGON,
|
||||
gbr_metadata.GetApertureAttrib() );
|
||||
gbr_metadata.GetApertureAttrib(),
|
||||
gbr_metadata.GetCustomAttribute() );
|
||||
formatNetAttribute( &gbr_metadata.m_NetlistMetadata );
|
||||
|
||||
emitDcode( pos_dev, 3 );
|
||||
@ -1802,7 +1794,8 @@ void GERBER_PLOTTER::FlashPadChamferRoundRect( const VECTOR2I& aShapePos, const
|
||||
}
|
||||
|
||||
selectAperture( cornerList, aPadOrient, APERTURE::AM_FREE_POLYGON,
|
||||
gbr_metadata.GetApertureAttrib() );
|
||||
gbr_metadata.GetApertureAttrib(),
|
||||
gbr_metadata.GetCustomAttribute() );
|
||||
formatNetAttribute( &gbr_metadata.m_NetlistMetadata );
|
||||
|
||||
emitDcode( pos_device, 3 );
|
||||
@ -1832,31 +1825,31 @@ void GERBER_PLOTTER::FlashPadChamferRoundRect( const VECTOR2I& aShapePos, const
|
||||
case 4:
|
||||
m_hasApertureOutline4P = true;
|
||||
selectAperture( cornerList, aPadOrient, APERTURE::APER_MACRO_OUTLINE4P,
|
||||
gbr_metadata.GetApertureAttrib() );
|
||||
gbr_metadata.GetApertureAttrib(), gbr_metadata.GetCustomAttribute() );
|
||||
break;
|
||||
|
||||
case 5:
|
||||
m_hasApertureChamferedRect = true;
|
||||
selectAperture( cornerList, aPadOrient, APERTURE::APER_MACRO_OUTLINE5P,
|
||||
gbr_metadata.GetApertureAttrib() );
|
||||
gbr_metadata.GetApertureAttrib(), gbr_metadata.GetCustomAttribute() );
|
||||
break;
|
||||
|
||||
case 6:
|
||||
m_hasApertureChamferedRect = true;
|
||||
selectAperture( cornerList, aPadOrient, APERTURE::APER_MACRO_OUTLINE6P,
|
||||
gbr_metadata.GetApertureAttrib() );
|
||||
gbr_metadata.GetApertureAttrib(), gbr_metadata.GetCustomAttribute() );
|
||||
break;
|
||||
|
||||
case 7:
|
||||
m_hasApertureChamferedRect = true;
|
||||
selectAperture( cornerList, aPadOrient, APERTURE::APER_MACRO_OUTLINE7P,
|
||||
gbr_metadata.GetApertureAttrib() );
|
||||
gbr_metadata.GetApertureAttrib(), gbr_metadata.GetCustomAttribute() );
|
||||
break;
|
||||
|
||||
case 8:
|
||||
m_hasApertureChamferedRect = true;
|
||||
selectAperture( cornerList, aPadOrient, APERTURE::APER_MACRO_OUTLINE8P,
|
||||
gbr_metadata.GetApertureAttrib() );
|
||||
gbr_metadata.GetApertureAttrib(), gbr_metadata.GetCustomAttribute() );
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -1911,8 +1904,15 @@ void GERBER_PLOTTER::FlashPadTrapez( const VECTOR2I& aPadPos, const VECTOR2I* aC
|
||||
|
||||
// polygon corners list
|
||||
std::vector<VECTOR2I> corners = { aCorners[0], aCorners[1], aCorners[2], aCorners[3] };
|
||||
int aperture_attrib = gbr_metadata ? gbr_metadata->GetApertureAttrib() : 0;
|
||||
selectAperture( corners, aPadOrient, APERTURE::APER_MACRO_OUTLINE4P, aperture_attrib );
|
||||
int aperture_attribute = 0;
|
||||
std::string custom_attribute = "";
|
||||
if( gbr_metadata )
|
||||
{
|
||||
aperture_attribute = gbr_metadata->GetApertureAttrib();
|
||||
custom_attribute = gbr_metadata->GetCustomAttribute();
|
||||
}
|
||||
selectAperture( corners, aPadOrient, APERTURE::APER_MACRO_OUTLINE4P, aperture_attribute,
|
||||
custom_attribute );
|
||||
|
||||
if( gbr_metadata )
|
||||
formatNetAttribute( &gbr_metadata->m_NetlistMetadata );
|
||||
@ -1959,17 +1959,14 @@ void GERBER_PLOTTER::FlashRegularPolygon( const VECTOR2I& aShapePos, int aDiamet
|
||||
}
|
||||
else
|
||||
{
|
||||
VECTOR2D pos_dev = userToDeviceCoordinates( aShapePos );
|
||||
int aperture_attrib = gbr_metadata ? gbr_metadata->GetApertureAttrib() : 0;
|
||||
|
||||
APERTURE::APERTURE_TYPE apert_type =
|
||||
(APERTURE::APERTURE_TYPE)(APERTURE::AT_REGULAR_POLY3 + aCornerCount - 3);
|
||||
selectAperture( aDiameter, aOrient, apert_type, aperture_attrib );
|
||||
( APERTURE::APERTURE_TYPE )( APERTURE::AT_REGULAR_POLY3 + aCornerCount - 3 );
|
||||
|
||||
if( gbr_metadata )
|
||||
formatNetAttribute( &gbr_metadata->m_NetlistMetadata );
|
||||
wxASSERT( apert_type >= APERTURE::APERTURE_TYPE::AT_REGULAR_POLY3
|
||||
&& apert_type <= APERTURE::APERTURE_TYPE::AT_REGULAR_POLY12 );
|
||||
|
||||
emitDcode( pos_dev, 3 );
|
||||
selectApertureWithAttributes( aShapePos, gbr_metadata, VECTOR2I( 0, 0 ), aDiameter / 2,
|
||||
aOrient, apert_type );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -745,9 +745,22 @@ public:
|
||||
int m_SolderPasteMargin; // Solder paste margin absolute value
|
||||
double m_SolderPasteMarginRatio; // Solder mask margin ratio value of pad size
|
||||
// The final margin is the sum of these 2 values
|
||||
bool m_AllowSoldermaskBridgesInFPs;
|
||||
bool m_TentViasFront; // The default tenting option if not overridden on an
|
||||
bool m_TentViasBack; // individual via
|
||||
bool m_AllowSoldermaskBridgesInFPs;
|
||||
|
||||
bool m_TentViasFront; // The default tenting option if not overridden on an
|
||||
bool m_TentViasBack; // individual via
|
||||
|
||||
bool m_CoverViasFront; // The default covering option if not overridden on an
|
||||
bool m_CoverViasBack; // individual via
|
||||
|
||||
bool m_PlugViasFront; // The default plugging option if not overridden on an
|
||||
bool m_PlugViasBack; // individual via
|
||||
|
||||
bool m_CapVias; // The default capping option if not overridden on an
|
||||
// individual via
|
||||
|
||||
bool m_FillVias; // The default filling option if not overridden on ana
|
||||
// individual via
|
||||
|
||||
std::shared_ptr<NET_SETTINGS> m_NetSettings;
|
||||
|
||||
|
@ -91,16 +91,16 @@ class GBR_APERTURE_METADATA
|
||||
public:
|
||||
enum GBR_APERTURE_ATTRIB
|
||||
{
|
||||
GBR_APERTURE_ATTRIB_NONE, ///< uninitialized attribute.
|
||||
GBR_APERTURE_ATTRIB_ETCHEDCMP, ///< Aperture used for etched components.
|
||||
GBR_APERTURE_ATTRIB_NONE, ///< uninitialized attribute.
|
||||
GBR_APERTURE_ATTRIB_ETCHEDCMP, ///< Aperture used for etched components.
|
||||
|
||||
/// Aperture used for connected items like tracks (not vias).
|
||||
GBR_APERTURE_ATTRIB_CONDUCTOR,
|
||||
GBR_APERTURE_ATTRIB_EDGECUT, ///< Aperture used for board cutout,
|
||||
GBR_APERTURE_ATTRIB_EDGECUT, ///< Aperture used for board cutout,
|
||||
|
||||
/// Aperture used for not connected items (texts, outlines on copper).
|
||||
GBR_APERTURE_ATTRIB_NONCONDUCTOR,
|
||||
GBR_APERTURE_ATTRIB_VIAPAD, ///< Aperture used for vias.
|
||||
GBR_APERTURE_ATTRIB_VIAPAD, ///< Aperture used for vias.
|
||||
|
||||
/// Aperture used for through hole component on outer layer.
|
||||
GBR_APERTURE_ATTRIB_COMPONENTPAD,
|
||||
@ -119,8 +119,8 @@ public:
|
||||
|
||||
/// Aperture used for edge connector pad (outer layers).
|
||||
GBR_APERTURE_ATTRIB_CONNECTORPAD,
|
||||
GBR_APERTURE_ATTRIB_WASHERPAD, ///< Aperture used for mechanical pads (NPTH).
|
||||
GBR_APERTURE_ATTRIB_TESTPOINT, ///< Aperture used for test point pad (outer layers).
|
||||
GBR_APERTURE_ATTRIB_WASHERPAD, ///< Aperture used for mechanical pads (NPTH).
|
||||
GBR_APERTURE_ATTRIB_TESTPOINT, ///< Aperture used for test point pad (outer layers).
|
||||
|
||||
/// Aperture used for fiducial pad (outer layers), at board level.
|
||||
GBR_APERTURE_ATTRIB_FIDUCIAL_GLBL,
|
||||
@ -137,8 +137,8 @@ public:
|
||||
/// Aperture used for castellated pads in drill files.
|
||||
GBR_APERTURE_ATTRIB_CASTELLATEDDRILL,
|
||||
|
||||
GBR_APERTURE_ATTRIB_VIADRILL, ///< Aperture used for via holes in drill files.
|
||||
GBR_APERTURE_ATTRIB_CMP_DRILL, ///< Aperture used for pad holes in drill files.
|
||||
GBR_APERTURE_ATTRIB_VIADRILL, ///< Aperture used for via holes in drill files.
|
||||
GBR_APERTURE_ATTRIB_CMP_DRILL, ///< Aperture used for pad holes in drill files.
|
||||
|
||||
/// Aperture used for pads oblong holes in drill files.
|
||||
GBR_APERTURE_ATTRIB_CMP_OBLONG_DRILL,
|
||||
@ -163,11 +163,13 @@ public:
|
||||
|
||||
/// Aperture used to draw component outline courtyard in placement files.
|
||||
GBR_APERTURE_ATTRIB_CMP_COURTYARD,
|
||||
GBR_APERTURE_ATTRIB_END ///< sentinel: max value
|
||||
|
||||
///< aperture used for other purposes. Requires a text description of this feature.
|
||||
GBR_APERTURE_ATTRIB_OTHER,
|
||||
GBR_APERTURE_ATTRIB_END ///< sentinel: max value
|
||||
};
|
||||
|
||||
GBR_APERTURE_METADATA()
|
||||
:m_ApertAttribute( GBR_APERTURE_ATTRIB_NONE )
|
||||
GBR_APERTURE_METADATA() : m_ApertAttribute( GBR_APERTURE_ATTRIB_NONE ), m_CustomAttribute( "" )
|
||||
{}
|
||||
|
||||
/**
|
||||
@ -187,15 +189,18 @@ public:
|
||||
* like "%TA.AperFunction,<function>*%"
|
||||
*/
|
||||
static std::string FormatAttribute( GBR_APERTURE_ATTRIB aAttribute,
|
||||
bool aUseX1StructuredComment );
|
||||
bool aUseX1StructuredComment,
|
||||
const std::string& aCustomAttribute );
|
||||
|
||||
std::string FormatAttribute( bool aUseX1StructuredComment )
|
||||
{
|
||||
return FormatAttribute( m_ApertAttribute, aUseX1StructuredComment );
|
||||
return FormatAttribute( m_ApertAttribute, aUseX1StructuredComment, m_CustomAttribute );
|
||||
}
|
||||
|
||||
// The id of the aperture attribute
|
||||
GBR_APERTURE_ATTRIB m_ApertAttribute;
|
||||
|
||||
std::string m_CustomAttribute;
|
||||
};
|
||||
|
||||
|
||||
@ -212,11 +217,19 @@ public:
|
||||
m_ApertureMetadata.m_ApertAttribute = aApertAttribute;
|
||||
}
|
||||
|
||||
void SetApertureAttrib( std::string aCustomAttribute )
|
||||
{
|
||||
m_ApertureMetadata.m_ApertAttribute = GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_OTHER;
|
||||
m_ApertureMetadata.m_CustomAttribute = aCustomAttribute;
|
||||
}
|
||||
|
||||
GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB GetApertureAttrib()
|
||||
{
|
||||
return m_ApertureMetadata.m_ApertAttribute;
|
||||
}
|
||||
|
||||
std::string GetCustomAttribute() { return m_ApertureMetadata.m_CustomAttribute; }
|
||||
|
||||
void SetNetAttribType( int aNetAttribType )
|
||||
{
|
||||
m_NetlistMetadata.m_NetAttribType = aNetAttribType;
|
||||
|
@ -19,6 +19,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <optional>
|
||||
|
||||
#include <wx/stream.h>
|
||||
#include <wx/string.h>
|
||||
|
||||
@ -38,6 +40,18 @@ namespace KICAD_FORMAT {
|
||||
*/
|
||||
KICOMMON_API void FormatBool( OUTPUTFORMATTER* aOut, const wxString& aKey, bool aValue );
|
||||
|
||||
/**
|
||||
* Writes an optional boolean to the formatter.
|
||||
* If a value is present, calls FormatBool.
|
||||
* If no value is present, Writes (aKey none).
|
||||
*
|
||||
* @param aOut is the output formatter to write to
|
||||
* @param aKey is the name of the boolean flag
|
||||
* @param aValue is the value to write
|
||||
*/
|
||||
KICOMMON_API void FormatOptBool( OUTPUTFORMATTER* aOut, const wxString& aKey,
|
||||
std::optional<bool> aValue );
|
||||
|
||||
KICOMMON_API void FormatUuid( OUTPUTFORMATTER* aOut, const KIID& aUuid );
|
||||
|
||||
/**
|
||||
|
@ -139,6 +139,8 @@ public:
|
||||
// Only one attribute is allowed by aperture
|
||||
// 0 = no specific aperture attribute
|
||||
int m_ApertureAttribute;
|
||||
|
||||
std::string m_CustomAttribute;
|
||||
};
|
||||
|
||||
|
||||
|
@ -245,11 +245,13 @@ public:
|
||||
* @param aType is the type ( shape ) of tool.
|
||||
* @param aApertureAttribute is an aperture attribute of the tool (a tool can have only one
|
||||
* attribute) 0 = no specific attribute.
|
||||
* @param aCustomAttribute a String describing custom tools
|
||||
* @return an index to the aperture in aperture list which meets the size and type of tool
|
||||
* if the aperture does not exist, it is created and entered in aperture list.
|
||||
*/
|
||||
int GetOrCreateAperture( const VECTOR2I& aSize, int aRadius, const EDA_ANGLE& aRotation,
|
||||
APERTURE::APERTURE_TYPE aType, int aApertureAttribute );
|
||||
APERTURE::APERTURE_TYPE aType, int aApertureAttribute,
|
||||
const std::string& aCustomAttribute );
|
||||
|
||||
/**
|
||||
* @param aCorners is the corner list.
|
||||
@ -257,11 +259,13 @@ public:
|
||||
* @param aType is the type ( shape ) of tool that can manage a list of corners (polygon).
|
||||
* @param aApertureAttribute is an aperture attribute of the tool (a tool can have only one
|
||||
* attribute) 0 = no specific attribute.
|
||||
* @param aCustomAttribute a String describing custom tools
|
||||
* @return an index to the aperture in aperture list which meets the data and type of tool
|
||||
* if the aperture does not exist, it is created and entered in aperture list.
|
||||
*/
|
||||
int GetOrCreateAperture( const std::vector<VECTOR2I>& aCorners, const EDA_ANGLE& aRotation,
|
||||
APERTURE::APERTURE_TYPE aType, int aApertureAttribute );
|
||||
APERTURE::APERTURE_TYPE aType, int aApertureAttribute,
|
||||
const std::string& aCustomAttribute );
|
||||
|
||||
protected:
|
||||
virtual void ThickArc( const VECTOR2D& aCentre, const EDA_ANGLE& aStartAngle,
|
||||
@ -301,7 +305,8 @@ protected:
|
||||
* Write the DCode selection on gerber file.
|
||||
*/
|
||||
void selectAperture( const VECTOR2I& aSize, int aRadius, const EDA_ANGLE& aRotation,
|
||||
APERTURE::APERTURE_TYPE aType, int aApertureAttribute );
|
||||
APERTURE::APERTURE_TYPE aType, int aApertureAttribute,
|
||||
const std::string& aCustomAttribute );
|
||||
/**
|
||||
* Pick an existing aperture or create a new one, matching the aDiameter, aPolygonRotation,
|
||||
* type and attributes.
|
||||
@ -310,18 +315,17 @@ protected:
|
||||
* write the DCode selection on gerber file
|
||||
*/
|
||||
void selectAperture( const std::vector<VECTOR2I>& aCorners, const EDA_ANGLE& aPolygonRotation,
|
||||
APERTURE::APERTURE_TYPE aType, int aApertureAttribute );
|
||||
APERTURE::APERTURE_TYPE aType, int aApertureAttribute,
|
||||
const std::string& aCustomAttribute );
|
||||
|
||||
|
||||
/**
|
||||
* Pick an existing aperture or create a new one, matching the corner list, aRotDegree,
|
||||
* type and attributes.
|
||||
*
|
||||
* It only applies to apertures managing a polygon that differs from AT_REGULAR_POLY3
|
||||
* to AT_REGULAR_POLY12 (for instance APER_MACRO_TRAPEZOID ) write the DCode selection
|
||||
* on gerber file.
|
||||
* Pick an aperture or create a new one and emits the DCode.
|
||||
*
|
||||
*/
|
||||
void selectAperture( int aDiameter, const EDA_ANGLE& aRotation,
|
||||
APERTURE::APERTURE_TYPE aType, int aApertureAttribute );
|
||||
void selectApertureWithAttributes( const VECTOR2I& aPos, GBR_METADATA* aGbrMetadata,
|
||||
VECTOR2I aSize, int aRadius, const EDA_ANGLE& aAngle,
|
||||
APERTURE::APERTURE_TYPE aType );
|
||||
|
||||
/**
|
||||
* Emit a D-Code record, using proper conversions to format a leading zero omitted gerber
|
||||
|
@ -38,6 +38,7 @@
|
||||
#define ARG_GERBER_PRECISION "--gerber-precision"
|
||||
#define ARG_EXCELLON_UNITS "--excellon-units"
|
||||
#define ARG_GENERATE_MAP "--generate-map"
|
||||
#define ARG_GENERATE_TENTING "--generate-tenting"
|
||||
#define ARG_MAP_FORMAT "--map-format"
|
||||
#define ARG_DRILL_ORIGIN "--drill-origin"
|
||||
|
||||
@ -89,6 +90,10 @@ CLI::PCB_EXPORT_DRILL_COMMAND::PCB_EXPORT_DRILL_COMMAND() : PCB_EXPORT_BASE_COMM
|
||||
.help( UTF8STDSTR( _( "Generate map / summary of drill hits" ) ) )
|
||||
.flag();
|
||||
|
||||
m_argParser.add_argument( ARG_GENERATE_TENTING )
|
||||
.help( UTF8STDSTR( _( "Generate a file specifically for tenting" ) ) )
|
||||
.flag();
|
||||
|
||||
m_argParser.add_argument( ARG_MAP_FORMAT )
|
||||
.default_value( std::string( "pdf" ) )
|
||||
.help( UTF8STDSTR( _( "Valid options: pdf,gerberx2,ps,dxf,svg" ) ) )
|
||||
@ -240,6 +245,7 @@ int CLI::PCB_EXPORT_DRILL_COMMAND::doPerform( KIWAY& aKiway )
|
||||
drillJob->m_excellonMinimalHeader = m_argParser.get<bool>( ARG_EXCELLON_MINIMALHEAD );
|
||||
drillJob->m_excellonCombinePTHNPTH = !m_argParser.get<bool>( ARG_EXCELLON_SEPARATE_TH );
|
||||
drillJob->m_generateMap = m_argParser.get<bool>( ARG_GENERATE_MAP );
|
||||
drillJob->m_generateTenting = m_argParser.get<bool>( ARG_GENERATE_TENTING );
|
||||
drillJob->m_gerberPrecision = m_argParser.get<int>( ARG_GERBER_PRECISION );
|
||||
|
||||
if( drillJob->m_gerberPrecision != 5 && drillJob->m_gerberPrecision != 6 )
|
||||
|
@ -222,6 +222,16 @@ BOARD_DESIGN_SETTINGS::BOARD_DESIGN_SETTINGS( JSON_SETTINGS* aParent, const std:
|
||||
m_TentViasFront = true;
|
||||
m_TentViasBack = true;
|
||||
|
||||
m_CoverViasFront = false;
|
||||
m_CoverViasBack = false;
|
||||
|
||||
m_PlugViasFront = false;
|
||||
m_PlugViasBack = false;
|
||||
|
||||
m_CapVias = false;
|
||||
|
||||
m_FillVias = false;
|
||||
|
||||
// Layer thickness for 3D viewer
|
||||
m_boardThickness = pcbIUScale.mmToIU( DEFAULT_BOARD_THICKNESS_MM );
|
||||
|
||||
|
@ -59,6 +59,7 @@ bool DIALOG_GENDRILL::g_minimalHeader = false; // Only for Excellon format
|
||||
bool DIALOG_GENDRILL::g_mirror = false; // Only for Excellon format
|
||||
bool DIALOG_GENDRILL::g_merge_PTH_NPTH = false; // Only for Excellon format
|
||||
bool DIALOG_GENDRILL::g_generateMap = false;
|
||||
bool DIALOG_GENDRILL::g_generateTenting = false;
|
||||
int DIALOG_GENDRILL::g_mapFileType = 4; // The last choice in m_Choice_Drill_Map
|
||||
int DIALOG_GENDRILL::g_drillFileType = 0;
|
||||
|
||||
@ -129,7 +130,8 @@ bool DIALOG_GENDRILL::TransferDataFromWindow()
|
||||
{
|
||||
if( !m_job )
|
||||
{
|
||||
genDrillAndMapFiles( true, m_cbGenerateMap->GetValue() );
|
||||
genDrillAndMapFiles( true, m_cbGenerateMap->GetValue(),
|
||||
m_generateTentingLayers->GetValue() );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -147,6 +149,7 @@ bool DIALOG_GENDRILL::TransferDataFromWindow()
|
||||
m_job->m_mapFormat = static_cast<JOB_EXPORT_PCB_DRILL::MAP_FORMAT>( m_choiceDrillMap->GetSelection() );
|
||||
m_job->m_zeroFormat = static_cast<JOB_EXPORT_PCB_DRILL::ZEROS_FORMAT>( m_zeros->GetSelection() );
|
||||
m_job->m_generateMap = m_cbGenerateMap->IsChecked();
|
||||
m_job->m_generateTenting = m_generateTentingLayers->IsChecked();
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -171,6 +174,7 @@ bool DIALOG_GENDRILL::TransferDataToWindow()
|
||||
m_choiceDrillMap->SetSelection( g_mapFileType );
|
||||
m_altDrillMode->SetValue( !g_useRouteModeForOvalHoles );
|
||||
m_cbGenerateMap->SetValue( g_generateMap );
|
||||
m_generateTentingLayers->SetValue( g_generateTenting );
|
||||
|
||||
// Output directory
|
||||
m_outputDirectoryName->SetValue( m_plotOpts.GetOutputDirectory() );
|
||||
@ -194,6 +198,7 @@ bool DIALOG_GENDRILL::TransferDataToWindow()
|
||||
m_choiceDrillMap->SetSelection( static_cast<int>( m_job->m_mapFormat ) );
|
||||
m_altDrillMode->SetValue( !m_job->m_excellonOvalDrillRoute );
|
||||
m_cbGenerateMap->SetValue( m_job->m_generateMap );
|
||||
m_generateTentingLayers->SetValue( m_job->m_generateTenting );
|
||||
}
|
||||
|
||||
wxCommandEvent dummy;
|
||||
@ -221,6 +226,7 @@ void DIALOG_GENDRILL::initDialog()
|
||||
g_mapFileType = cfg->m_GenDrill.map_file_type;
|
||||
g_zerosFormat = cfg->m_GenDrill.zeros_format;
|
||||
g_generateMap = cfg->m_GenDrill.generate_map;
|
||||
g_generateTenting = cfg->m_GenDrill.generate_tenting;
|
||||
|
||||
// Ensure validity of g_mapFileType
|
||||
if( g_mapFileType < 0 || g_mapFileType >= (int) m_choiceDrillMap->GetCount() )
|
||||
@ -249,6 +255,7 @@ void DIALOG_GENDRILL::onFileFormatSelection( wxCommandEvent& event )
|
||||
m_Check_Minimal->Enable( enbl_Excellon );
|
||||
m_Check_Merge_PTH_NPTH->Enable( enbl_Excellon );
|
||||
m_altDrillMode->Enable( enbl_Excellon );
|
||||
m_generateTentingLayers->Enable( !enbl_Excellon );
|
||||
|
||||
if( enbl_Excellon )
|
||||
{
|
||||
@ -279,6 +286,7 @@ void DIALOG_GENDRILL::updateConfig()
|
||||
cfg->m_GenDrill.map_file_type = g_mapFileType;
|
||||
cfg->m_GenDrill.zeros_format = g_zerosFormat;
|
||||
cfg->m_GenDrill.generate_map = g_generateMap;
|
||||
cfg->m_GenDrill.generate_tenting = g_generateTenting;
|
||||
}
|
||||
|
||||
|
||||
@ -373,6 +381,7 @@ void DIALOG_GENDRILL::UpdateDrillParams()
|
||||
g_zerosFormat = m_zeros->GetSelection();
|
||||
g_useRouteModeForOvalHoles = !m_altDrillMode->GetValue();
|
||||
g_generateMap = m_cbGenerateMap->IsChecked();
|
||||
g_generateTenting = m_generateTentingLayers->IsChecked();
|
||||
|
||||
if( m_origin->GetSelection() == 0 )
|
||||
g_drillFileOffset = VECTOR2I( 0, 0 );
|
||||
@ -392,7 +401,7 @@ void DIALOG_GENDRILL::UpdateDrillParams()
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_GENDRILL::genDrillAndMapFiles( bool aGenDrill, bool aGenMap )
|
||||
void DIALOG_GENDRILL::genDrillAndMapFiles( bool aGenDrill, bool aGenMap, bool aGenTenting )
|
||||
{
|
||||
updateConfig(); // set params and Save drill options
|
||||
|
||||
@ -462,7 +471,7 @@ void DIALOG_GENDRILL::genDrillAndMapFiles( bool aGenDrill, bool aGenMap )
|
||||
gerberWriter.SetMapFileFormat( filefmt[choice] );
|
||||
|
||||
gerberWriter.CreateDrillandMapFilesSet( outputDir.GetFullPath(), aGenDrill, aGenMap,
|
||||
&reporter );
|
||||
aGenTenting, &reporter );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -84,7 +84,7 @@ private:
|
||||
* plated through holes, and one file per layer pair, which have one or more holes, excluding
|
||||
* through holes, already in the first file. One file for all Not Plated through holes.
|
||||
*/
|
||||
void genDrillAndMapFiles( bool aGenDrill, bool aGenMap );
|
||||
void genDrillAndMapFiles( bool aGenDrill, bool aGenMap, bool aGenTenting );
|
||||
|
||||
void updatePrecisionOptions();
|
||||
void updateConfig();
|
||||
@ -96,6 +96,7 @@ private:
|
||||
static bool g_mirror;
|
||||
static bool g_merge_PTH_NPTH;
|
||||
static bool g_generateMap;
|
||||
static bool g_generateTenting;
|
||||
static DRILL_PRECISION g_precision; // Precision for drill files in non-decimal
|
||||
// format
|
||||
static VECTOR2I g_drillFileOffset; // Drill offset: 0,0 for absolute
|
||||
|
@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6)
|
||||
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6-dirty)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
@ -84,6 +84,19 @@ DIALOG_GENDRILL_BASE::DIALOG_GENDRILL_BASE( wxWindow* parent, wxWindowID id, con
|
||||
m_rbGerberX2 = new wxRadioButton( this, wxID_ANY, _("Gerber X2"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
bSizerMargins->Add( m_rbGerberX2, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
|
||||
|
||||
wxFlexGridSizer* fgSizerGerberX2Options;
|
||||
fgSizerGerberX2Options = new wxFlexGridSizer( 4, 1, 3, 0 );
|
||||
fgSizerGerberX2Options->SetFlexibleDirection( wxBOTH );
|
||||
fgSizerGerberX2Options->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
|
||||
|
||||
m_generateTentingLayers = new wxCheckBox( this, wxID_ANY, _("Generate tenting layers"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_generateTentingLayers->Enable( false );
|
||||
|
||||
fgSizerGerberX2Options->Add( m_generateTentingLayers, 0, wxBOTTOM|wxLEFT|wxRIGHT, 5 );
|
||||
|
||||
|
||||
bSizerMargins->Add( fgSizerGerberX2Options, 1, wxEXPAND|wxLEFT, 20 );
|
||||
|
||||
|
||||
bSizerMargins->Add( 0, 6, 0, wxEXPAND, 5 );
|
||||
|
||||
@ -172,6 +185,9 @@ DIALOG_GENDRILL_BASE::DIALOG_GENDRILL_BASE( wxWindow* parent, wxWindowID id, con
|
||||
fgSizer1->Add( m_staticTextPrecision, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
|
||||
|
||||
|
||||
fgSizer1->Add( 0, 0, 1, wxEXPAND, 5 );
|
||||
|
||||
|
||||
bRightCol->Add( fgSizer1, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 );
|
||||
|
||||
|
||||
|
@ -846,6 +846,89 @@
|
||||
<event name="OnRadioButton">onFileFormatSelection</event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="true">
|
||||
<property name="border">20</property>
|
||||
<property name="flag">wxEXPAND|wxLEFT</property>
|
||||
<property name="proportion">1</property>
|
||||
<object class="wxFlexGridSizer" expanded="true">
|
||||
<property name="cols">1</property>
|
||||
<property name="flexible_direction">wxBOTH</property>
|
||||
<property name="growablecols"></property>
|
||||
<property name="growablerows"></property>
|
||||
<property name="hgap">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">fgSizerGerberX2Options</property>
|
||||
<property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
|
||||
<property name="permission">none</property>
|
||||
<property name="rows">4</property>
|
||||
<property name="vgap">3</property>
|
||||
<object class="sizeritem" expanded="true">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxBOTTOM|wxLEFT|wxRIGHT</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxCheckBox" expanded="true">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer">0</property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position">0</property>
|
||||
<property name="aui_row">0</property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="checked">0</property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="default_pane">0</property>
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="drag_accept_files">0</property>
|
||||
<property name="enabled">0</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
<property name="font"></property>
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">Generate tenting layers</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="min_size"></property>
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_generateTentingLayers</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pin_button">1</property>
|
||||
<property name="pos"></property>
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="style"></property>
|
||||
<property name="subclass">; ; forward_declare</property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="validator_data_type"></property>
|
||||
<property name="validator_style">wxFILTER_NONE</property>
|
||||
<property name="validator_type">wxDefaultValidator</property>
|
||||
<property name="validator_variable"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="true">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND</property>
|
||||
@ -1684,6 +1767,16 @@
|
||||
<property name="wrap">-1</property>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="true">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND</property>
|
||||
<property name="proportion">1</property>
|
||||
<object class="spacer" expanded="true">
|
||||
<property name="height">0</property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="width">0</property>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
|
@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6)
|
||||
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6-dirty)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
@ -55,6 +55,7 @@ class DIALOG_GENDRILL_BASE : public DIALOG_SHIM
|
||||
wxCheckBox* m_Check_Merge_PTH_NPTH;
|
||||
wxCheckBox* m_altDrillMode;
|
||||
wxRadioButton* m_rbGerberX2;
|
||||
wxCheckBox* m_generateTentingLayers;
|
||||
wxCheckBox* m_cbGenerateMap;
|
||||
wxChoice* m_choiceDrillMap;
|
||||
wxStaticText* m_optionsLabel;
|
||||
|
@ -35,6 +35,15 @@
|
||||
#include <kidialog.h>
|
||||
#include <connectivity/connectivity_data.h>
|
||||
#include <board_commit.h>
|
||||
#include <magic_enum.hpp>
|
||||
|
||||
|
||||
bool DIALOG_TRACK_VIA_PROPERTIES::IPC4761_CONFIGURATION::operator==(
|
||||
const IPC4761_CONFIGURATION& aOther ) const
|
||||
{
|
||||
return ( tent == aOther.tent ) && ( plug == aOther.plug ) && ( cover == aOther.cover )
|
||||
&& ( cap == aOther.cap ) && ( fill == aOther.fill );
|
||||
}
|
||||
|
||||
|
||||
DIALOG_TRACK_VIA_PROPERTIES::DIALOG_TRACK_VIA_PROPERTIES( PCB_BASE_EDIT_FRAME* aParent,
|
||||
@ -101,11 +110,6 @@ DIALOG_TRACK_VIA_PROPERTIES::DIALOG_TRACK_VIA_PROPERTIES( PCB_BASE_EDIT_FRAME* a
|
||||
m_ViaEndLayer->SetBoardFrame( aParent );
|
||||
m_ViaEndLayer->Resync();
|
||||
|
||||
m_btnLinkTenting->SetBitmap( KiBitmapBundle( BITMAPS::edit_cmp_symb_links ) );
|
||||
m_btnLinkTenting->SetValue( true );
|
||||
m_tentingBackCtrl->Disable();
|
||||
m_tentingBackLabel->Disable();
|
||||
|
||||
wxFont infoFont = KIUI::GetInfoFont( this );
|
||||
m_techLayersLabel->SetFont( infoFont );
|
||||
|
||||
@ -123,33 +127,101 @@ DIALOG_TRACK_VIA_PROPERTIES::DIALOG_TRACK_VIA_PROPERTIES( PCB_BASE_EDIT_FRAME* a
|
||||
// The selection layer for tracks
|
||||
int track_selection_layer = -1;
|
||||
|
||||
auto getAnnularRingSelection =
|
||||
[]( const PCB_VIA* via ) -> int
|
||||
{
|
||||
switch( via->Padstack().UnconnectedLayerMode() )
|
||||
{
|
||||
default:
|
||||
case PADSTACK::UNCONNECTED_LAYER_MODE::KEEP_ALL: return 0;
|
||||
case PADSTACK::UNCONNECTED_LAYER_MODE::REMOVE_EXCEPT_START_AND_END: return 1;
|
||||
case PADSTACK::UNCONNECTED_LAYER_MODE::REMOVE_ALL: return 2;
|
||||
}
|
||||
};
|
||||
auto getAnnularRingSelection = []( const PCB_VIA* via ) -> int
|
||||
{
|
||||
switch( via->Padstack().UnconnectedLayerMode() )
|
||||
{
|
||||
default:
|
||||
case PADSTACK::UNCONNECTED_LAYER_MODE::KEEP_ALL: return 0;
|
||||
case PADSTACK::UNCONNECTED_LAYER_MODE::REMOVE_EXCEPT_START_AND_END: return 1;
|
||||
case PADSTACK::UNCONNECTED_LAYER_MODE::REMOVE_ALL: return 2;
|
||||
}
|
||||
};
|
||||
|
||||
auto getTentingSelection =
|
||||
[]( const PCB_VIA* via, PCB_LAYER_ID aLayer ) -> int
|
||||
{
|
||||
std::optional<bool> tentingOverride = via->Padstack().IsTented( aLayer );
|
||||
for( auto& preset : magic_enum::enum_values<IPC4761_PRESET>() )
|
||||
{
|
||||
if( preset >= IPC4761_PRESET::CUSTOM )
|
||||
continue;
|
||||
|
||||
if( tentingOverride.has_value() )
|
||||
{
|
||||
if( *tentingOverride )
|
||||
return 1; // Tented
|
||||
const auto& name_it = m_IPC4761Names.find( preset );
|
||||
|
||||
return 2; // Not tented
|
||||
}
|
||||
wxString name = _( "Unknown choice" );
|
||||
|
||||
return 0; // From design rules
|
||||
};
|
||||
if( name_it != m_IPC4761Names.end() )
|
||||
name = name_it->second;
|
||||
|
||||
m_protectionFeatures->AppendString( name );
|
||||
}
|
||||
|
||||
auto getProtectionSurface = []( const std::optional<bool>& front,
|
||||
const std::optional<bool>& back ) -> IPC4761_SURFACE
|
||||
{
|
||||
IPC4761_SURFACE value = IPC4761_SURFACE::CUSTOM;
|
||||
|
||||
if( !front.has_value() )
|
||||
value = IPC4761_SURFACE::FROM_RULES;
|
||||
else if( front.value() )
|
||||
value = IPC4761_SURFACE::FRONT;
|
||||
else
|
||||
value = IPC4761_SURFACE::NONE;
|
||||
|
||||
if( !back.has_value() )
|
||||
{
|
||||
if( value == IPC4761_SURFACE::FROM_RULES )
|
||||
return IPC4761_SURFACE::FROM_RULES;
|
||||
}
|
||||
else if( back.value() )
|
||||
{
|
||||
if( value == IPC4761_SURFACE::FRONT )
|
||||
return IPC4761_SURFACE::BOTH;
|
||||
else if( value == IPC4761_SURFACE::NONE )
|
||||
return IPC4761_SURFACE::BACK;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( value == IPC4761_SURFACE::FRONT )
|
||||
return IPC4761_SURFACE::FRONT;
|
||||
else if( value == IPC4761_SURFACE::NONE )
|
||||
return IPC4761_SURFACE::NONE;
|
||||
}
|
||||
|
||||
return IPC4761_SURFACE::CUSTOM;
|
||||
};
|
||||
|
||||
auto getProtectionDrill = []( const std::optional<bool>& drill ) -> IPC4761_DRILL
|
||||
{
|
||||
if( !drill.has_value() )
|
||||
return IPC4761_DRILL::FROM_RULES;
|
||||
if( drill.value() )
|
||||
return IPC4761_DRILL::SET;
|
||||
|
||||
return IPC4761_DRILL::NOT_SET;
|
||||
};
|
||||
|
||||
auto getViaConfiguration = [&]( const PCB_VIA* via ) -> IPC4761_PRESET
|
||||
{
|
||||
IPC4761_CONFIGURATION config;
|
||||
config.tent = getProtectionSurface( via->Padstack().FrontOuterLayers().has_solder_mask,
|
||||
via->Padstack().BackOuterLayers().has_solder_mask );
|
||||
|
||||
config.cover = getProtectionSurface( via->Padstack().FrontOuterLayers().has_covering,
|
||||
via->Padstack().BackOuterLayers().has_covering );
|
||||
|
||||
config.plug = getProtectionSurface( via->Padstack().FrontOuterLayers().has_plugging,
|
||||
via->Padstack().BackOuterLayers().has_plugging );
|
||||
|
||||
config.cap = getProtectionDrill( via->Padstack().Drill().is_capped );
|
||||
|
||||
config.fill = getProtectionDrill( via->Padstack().Drill().is_filled );
|
||||
|
||||
for( const auto& [preset, configuration] : m_IPC4761Presets )
|
||||
{
|
||||
if( configuration == config )
|
||||
return preset;
|
||||
}
|
||||
|
||||
return IPC4761_PRESET::CUSTOM;
|
||||
};
|
||||
|
||||
// Look for values that are common for every item that is selected
|
||||
for( EDA_ITEM* item : m_items )
|
||||
@ -239,16 +311,6 @@ DIALOG_TRACK_VIA_PROPERTIES::DIALOG_TRACK_VIA_PROPERTIES( PCB_BASE_EDIT_FRAME* a
|
||||
m_viaNotFree->SetValue( !v->GetIsFree() );
|
||||
m_annularRingsCtrl->SetSelection( getAnnularRingSelection( v ) );
|
||||
|
||||
m_tentingFrontCtrl->SetSelection( getTentingSelection( v, F_Mask ) );
|
||||
m_tentingBackCtrl->SetSelection( getTentingSelection( v, B_Mask ) );
|
||||
|
||||
bool link = m_tentingFrontCtrl->GetSelection()
|
||||
== m_tentingBackCtrl->GetSelection();
|
||||
|
||||
m_btnLinkTenting->SetValue( link );
|
||||
m_tentingBackCtrl->Enable( !link );
|
||||
m_tentingBackLabel->Enable( !link );
|
||||
|
||||
selection_first_layer = v->TopLayer();
|
||||
selection_last_layer = v->BottomLayer();
|
||||
|
||||
@ -260,6 +322,18 @@ DIALOG_TRACK_VIA_PROPERTIES::DIALOG_TRACK_VIA_PROPERTIES( PCB_BASE_EDIT_FRAME* a
|
||||
m_teardropWidthPercent.SetDoubleValue( v->GetTeardropParams().m_BestWidthRatio*100.0 );
|
||||
m_teardropHDPercent.SetDoubleValue( v->GetTeardropParams().m_WidthtoSizeFilterRatio*100.0 );
|
||||
m_curvedEdges->SetValue( v->GetTeardropParams().m_CurvedEdges );
|
||||
|
||||
IPC4761_PRESET preset = getViaConfiguration( v );
|
||||
|
||||
if( preset >= IPC4761_PRESET::CUSTOM )
|
||||
{
|
||||
m_protectionFeatures->SetSelection(
|
||||
m_protectionFeatures->Append( INDETERMINATE_ACTION ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_protectionFeatures->SetSelection( static_cast<int>( preset ) );
|
||||
}
|
||||
}
|
||||
else // check if values are the same for every selected via
|
||||
{
|
||||
@ -315,6 +389,14 @@ DIALOG_TRACK_VIA_PROPERTIES::DIALOG_TRACK_VIA_PROPERTIES( PCB_BASE_EDIT_FRAME* a
|
||||
|
||||
if( m_teardropHDPercent.GetDoubleValue() != v->GetTeardropParams().m_WidthtoSizeFilterRatio*100.0 )
|
||||
m_teardropHDPercent.SetValue( INDETERMINATE_STATE );
|
||||
|
||||
|
||||
if( static_cast<int>( getViaConfiguration( v ) )
|
||||
!= m_protectionFeatures->GetSelection() )
|
||||
{
|
||||
m_protectionFeatures->SetSelection(
|
||||
m_protectionFeatures->Append( INDETERMINATE_STATE ) );
|
||||
}
|
||||
}
|
||||
|
||||
if( v->IsLocked() )
|
||||
@ -775,21 +857,6 @@ bool DIALOG_TRACK_VIA_PROPERTIES::TransferDataFromWindow()
|
||||
break;
|
||||
}
|
||||
|
||||
switch( m_tentingFrontCtrl->GetSelection() )
|
||||
{
|
||||
default:
|
||||
case 0: via->Padstack().FrontOuterLayers().has_solder_mask.reset(); break;
|
||||
case 1: via->Padstack().FrontOuterLayers().has_solder_mask = true; break;
|
||||
case 2: via->Padstack().FrontOuterLayers().has_solder_mask = false; break;
|
||||
}
|
||||
|
||||
switch( m_tentingBackCtrl->GetSelection() )
|
||||
{
|
||||
default:
|
||||
case 0: via->Padstack().BackOuterLayers().has_solder_mask.reset(); break;
|
||||
case 1: via->Padstack().BackOuterLayers().has_solder_mask = true; break;
|
||||
case 2: via->Padstack().BackOuterLayers().has_solder_mask = false; break;
|
||||
}
|
||||
|
||||
if( !m_viaDrill.IsIndeterminate() )
|
||||
via->SetDrill( m_viaDrill.GetIntValue() );
|
||||
@ -824,6 +891,72 @@ bool DIALOG_TRACK_VIA_PROPERTIES::TransferDataFromWindow()
|
||||
if( changeLock )
|
||||
via->SetLocked( setLock );
|
||||
|
||||
auto setSurfaceProtection = [&]( std::optional<bool>& aFront,
|
||||
std::optional<bool>& aBack,
|
||||
IPC4761_SURFACE aProtection )
|
||||
{
|
||||
switch( aProtection )
|
||||
{
|
||||
case IPC4761_SURFACE::FROM_RULES:
|
||||
aFront.reset();
|
||||
aBack.reset();
|
||||
break;
|
||||
case IPC4761_SURFACE::NONE:
|
||||
aFront = false;
|
||||
aBack = false;
|
||||
break;
|
||||
case IPC4761_SURFACE::FRONT:
|
||||
aFront = true;
|
||||
aBack = false;
|
||||
break;
|
||||
case IPC4761_SURFACE::BACK:
|
||||
aFront = false;
|
||||
aBack = true;
|
||||
break;
|
||||
case IPC4761_SURFACE::BOTH:
|
||||
aFront = true;
|
||||
aBack = true;
|
||||
break;
|
||||
case IPC4761_SURFACE::CUSTOM: return;
|
||||
}
|
||||
};
|
||||
|
||||
auto setDrillProtection =
|
||||
[&]( std::optional<bool>& aDrill, IPC4761_DRILL aProtection )
|
||||
{
|
||||
switch( aProtection )
|
||||
{
|
||||
case IPC4761_DRILL::FROM_RULES: aDrill.reset(); break;
|
||||
case IPC4761_DRILL::NOT_SET: aDrill = false; break;
|
||||
case IPC4761_DRILL::SET: aDrill = true; break;
|
||||
}
|
||||
};
|
||||
|
||||
IPC4761_PRESET selectedPreset =
|
||||
static_cast<IPC4761_PRESET>( m_protectionFeatures->GetSelection() );
|
||||
|
||||
if( selectedPreset < IPC4761_PRESET::CUSTOM ) // Do not change custom feaure list.
|
||||
{
|
||||
const IPC4761_CONFIGURATION config = m_IPC4761Presets.at( selectedPreset );
|
||||
|
||||
setSurfaceProtection( via->Padstack().FrontOuterLayers().has_solder_mask,
|
||||
via->Padstack().BackOuterLayers().has_solder_mask,
|
||||
config.tent );
|
||||
|
||||
setSurfaceProtection( via->Padstack().FrontOuterLayers().has_plugging,
|
||||
via->Padstack().BackOuterLayers().has_plugging,
|
||||
config.plug );
|
||||
|
||||
setSurfaceProtection( via->Padstack().FrontOuterLayers().has_covering,
|
||||
via->Padstack().BackOuterLayers().has_covering,
|
||||
config.cover );
|
||||
|
||||
setDrillProtection( via->Padstack().Drill().is_filled, config.fill );
|
||||
|
||||
setDrillProtection( via->Padstack().Drill().is_capped, config.cap );
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1122,29 +1255,6 @@ void DIALOG_TRACK_VIA_PROPERTIES::onViaEdit( wxCommandEvent& aEvent )
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_TRACK_VIA_PROPERTIES::onFrontTentingChanged( wxCommandEvent& event )
|
||||
{
|
||||
if( m_btnLinkTenting->GetValue() )
|
||||
m_tentingBackCtrl->SetSelection( m_tentingFrontCtrl->GetSelection() );
|
||||
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_TRACK_VIA_PROPERTIES::onTentingLinkToggle( wxCommandEvent& event )
|
||||
{
|
||||
bool link = m_btnLinkTenting->GetValue();
|
||||
|
||||
m_tentingBackCtrl->Enable( !link );
|
||||
m_tentingBackLabel->Enable( !link );
|
||||
|
||||
if( link )
|
||||
m_tentingBackCtrl->SetSelection( m_tentingFrontCtrl->GetSelection() );
|
||||
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_TRACK_VIA_PROPERTIES::onTrackEdit( wxCommandEvent& aEvent )
|
||||
{
|
||||
bool externalCuLayer = m_TrackLayerCtrl->GetLayerSelection() == F_Cu
|
||||
|
@ -49,8 +49,6 @@ private:
|
||||
void onWidthEdit( wxCommandEvent& aEvent ) override;
|
||||
void onViaSelect( wxCommandEvent& aEvent ) override;
|
||||
void onViaEdit( wxCommandEvent& aEvent ) override;
|
||||
void onTentingLinkToggle( wxCommandEvent& event ) override;
|
||||
void onFrontTentingChanged( wxCommandEvent& event ) override;
|
||||
void onTrackEdit( wxCommandEvent& aEvent ) override;
|
||||
void onPadstackModeChanged( wxCommandEvent& aEvent ) override;
|
||||
void onEditLayerChanged( wxCommandEvent& aEvent ) override;
|
||||
@ -91,4 +89,112 @@ private:
|
||||
/// The currently-shown copper layer of the edited via(s)
|
||||
PCB_LAYER_ID m_editLayer;
|
||||
std::map<int, PCB_LAYER_ID> m_editLayerCtrlMap;
|
||||
|
||||
|
||||
enum class IPC4761_SURFACE
|
||||
{
|
||||
FROM_RULES = 0,
|
||||
NONE = 1,
|
||||
FRONT = 2,
|
||||
BACK = 3,
|
||||
BOTH = 4,
|
||||
CUSTOM = 5
|
||||
};
|
||||
|
||||
enum class IPC4761_DRILL
|
||||
{
|
||||
FROM_RULES = 0,
|
||||
NOT_SET = 1,
|
||||
SET = 2
|
||||
};
|
||||
|
||||
enum class IPC4761_PRESET
|
||||
{
|
||||
FROM_RULES = 0,
|
||||
NONE = 1,
|
||||
IA = 2,
|
||||
IB = 3,
|
||||
IA_INVERTED = 4,
|
||||
IIA = 5,
|
||||
IIB = 6,
|
||||
IIA_INVERTED = 7,
|
||||
IIIA = 8,
|
||||
IIIB = 9,
|
||||
IIIA_INVERTED = 10,
|
||||
IVA = 11,
|
||||
IVB = 12,
|
||||
IVA_INVERTED = 13,
|
||||
V = 14,
|
||||
VIA = 15,
|
||||
VIB = 16,
|
||||
VIA_INVERTED = 17,
|
||||
VII = 18,
|
||||
CUSTOM = 19,
|
||||
END = 20
|
||||
};
|
||||
|
||||
struct IPC4761_CONFIGURATION
|
||||
{
|
||||
IPC4761_SURFACE tent{ IPC4761_SURFACE::NONE };
|
||||
IPC4761_SURFACE cover{ IPC4761_SURFACE::NONE };
|
||||
IPC4761_SURFACE plug{ IPC4761_SURFACE::NONE };
|
||||
IPC4761_DRILL fill{ IPC4761_DRILL::NOT_SET };
|
||||
IPC4761_DRILL cap{ IPC4761_DRILL::NOT_SET };
|
||||
|
||||
bool operator==( const IPC4761_CONFIGURATION& other ) const;
|
||||
};
|
||||
|
||||
const std::map<IPC4761_PRESET, IPC4761_CONFIGURATION> m_IPC4761Presets{
|
||||
{ IPC4761_PRESET::FROM_RULES,
|
||||
{ IPC4761_SURFACE::FROM_RULES, IPC4761_SURFACE::FROM_RULES, IPC4761_SURFACE::FROM_RULES,
|
||||
IPC4761_DRILL::FROM_RULES, IPC4761_DRILL::FROM_RULES } },
|
||||
{ IPC4761_PRESET::NONE, {} },
|
||||
{ IPC4761_PRESET::IA, { .tent = IPC4761_SURFACE::FRONT } },
|
||||
{ IPC4761_PRESET::IB, { .tent = IPC4761_SURFACE::BOTH } },
|
||||
{ IPC4761_PRESET::IA_INVERTED, { .tent = IPC4761_SURFACE::BACK } },
|
||||
{ IPC4761_PRESET::IIA,
|
||||
{ .tent = IPC4761_SURFACE::FRONT, .cover = IPC4761_SURFACE::FRONT } },
|
||||
{ IPC4761_PRESET::IIB, { .tent = IPC4761_SURFACE::BOTH, .cover = IPC4761_SURFACE::BOTH } },
|
||||
{ IPC4761_PRESET::IIA_INVERTED,
|
||||
{ .tent = IPC4761_SURFACE::BACK, .cover = IPC4761_SURFACE::BACK } },
|
||||
{ IPC4761_PRESET::IIIA, { .plug = IPC4761_SURFACE::FRONT } },
|
||||
{ IPC4761_PRESET::IIIB, { .plug = IPC4761_SURFACE::BOTH } },
|
||||
{ IPC4761_PRESET::IIIA_INVERTED, { .plug = IPC4761_SURFACE::BACK } },
|
||||
{ IPC4761_PRESET::IVA, { .tent = IPC4761_SURFACE::FRONT, .plug = IPC4761_SURFACE::FRONT } },
|
||||
{ IPC4761_PRESET::IVB, { .tent = IPC4761_SURFACE::BOTH, .plug = IPC4761_SURFACE::BOTH } },
|
||||
{ IPC4761_PRESET::IVA_INVERTED,
|
||||
{ .tent = IPC4761_SURFACE::BACK, .plug = IPC4761_SURFACE::BACK } },
|
||||
{ IPC4761_PRESET::V, { .fill = IPC4761_DRILL::SET } },
|
||||
{ IPC4761_PRESET::VIA, { .tent = IPC4761_SURFACE::FRONT, .fill = IPC4761_DRILL::SET } },
|
||||
{ IPC4761_PRESET::VIB, { .tent = IPC4761_SURFACE::BOTH, .fill = IPC4761_DRILL::SET } },
|
||||
{ IPC4761_PRESET::VIA_INVERTED,
|
||||
{ .tent = IPC4761_SURFACE::BACK, .fill = IPC4761_DRILL::SET } },
|
||||
{ IPC4761_PRESET::VII, { .fill = IPC4761_DRILL::SET, .cap = IPC4761_DRILL::SET } },
|
||||
{ IPC4761_PRESET::CUSTOM, {} },
|
||||
{ IPC4761_PRESET::END, {} }
|
||||
};
|
||||
|
||||
const std::map<IPC4761_PRESET, wxString> m_IPC4761Names{
|
||||
{ IPC4761_PRESET::FROM_RULES, _( "From rules" ) },
|
||||
{ IPC4761_PRESET::NONE, _( "None" ) },
|
||||
{ IPC4761_PRESET::IA, _( "Type I a ( tented top )" ) },
|
||||
{ IPC4761_PRESET::IB, _( "Type I b ( tented both sides )" ) },
|
||||
{ IPC4761_PRESET::IA_INVERTED, _( "Type I a ( tented bottom )" ) },
|
||||
{ IPC4761_PRESET::IIA, _( "Type II a ( covered and tented top )" ) },
|
||||
{ IPC4761_PRESET::IIB, _( "Type II b ( covered and tented both sides )" ) },
|
||||
{ IPC4761_PRESET::IIA_INVERTED, _( "Type II a ( covered and tented bottom )" ) },
|
||||
{ IPC4761_PRESET::IIIA, _( "Type III a ( plugged top )" ) },
|
||||
{ IPC4761_PRESET::IIIB, _( "Type III b ( plugged both sides )" ) },
|
||||
{ IPC4761_PRESET::IIIA_INVERTED, _( "Type III a ( plugged bottom )" ) },
|
||||
{ IPC4761_PRESET::IVA, _( "Type IV a ( plugged and tented top )" ) },
|
||||
{ IPC4761_PRESET::IVB, _( "Type IV b ( plugged and tented both sides )" ) },
|
||||
{ IPC4761_PRESET::IVA_INVERTED, _( "Type IV a ( plugged and tented bottom )" ) },
|
||||
{ IPC4761_PRESET::V, _( "Type V ( filled )" ) },
|
||||
{ IPC4761_PRESET::VIA, _( "Type VI a ( filled and tented top )" ) },
|
||||
{ IPC4761_PRESET::VIB, _( "Type VI b ( filled and tented both sides )" ) },
|
||||
{ IPC4761_PRESET::VIA_INVERTED, _( "Type VI a ( filled and tented bottom )" ) },
|
||||
{ IPC4761_PRESET::VII, _( "Type VII ( filled and capped )" ) },
|
||||
{ IPC4761_PRESET::CUSTOM, _( "Custom" ) },
|
||||
{ IPC4761_PRESET::END, _( "End" ) }
|
||||
};
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6)
|
||||
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6-dirty)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
@ -334,18 +334,14 @@ DIALOG_TRACK_VIA_PROPERTIES_BASE::DIALOG_TRACK_VIA_PROPERTIES_BASE( wxWindow* pa
|
||||
wxBoxSizer* viaRightColumn;
|
||||
viaRightColumn = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
wxFlexGridSizer* fgSizer4;
|
||||
fgSizer4 = new wxFlexGridSizer( 0, 2, 0, 5 );
|
||||
fgSizer4->AddGrowableCol( 1 );
|
||||
fgSizer4->AddGrowableRow( 0 );
|
||||
fgSizer4->AddGrowableRow( 1 );
|
||||
fgSizer4->AddGrowableRow( 2 );
|
||||
fgSizer4->SetFlexibleDirection( wxBOTH );
|
||||
fgSizer4->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
|
||||
wxGridBagSizer* gbSizer4;
|
||||
gbSizer4 = new wxGridBagSizer( 0, 0 );
|
||||
gbSizer4->SetFlexibleDirection( wxBOTH );
|
||||
gbSizer4->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
|
||||
|
||||
m_ViaTypeLabel = new wxStaticText( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("Via type:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_ViaTypeLabel->Wrap( -1 );
|
||||
fgSizer4->Add( m_ViaTypeLabel, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
|
||||
gbSizer4->Add( m_ViaTypeLabel, wxGBPosition( 0, 0 ), wxGBSpan( 1, 1 ), wxALL, 5 );
|
||||
|
||||
wxString m_ViaTypeChoiceChoices[] = { _("Through"), _("Micro"), _("Blind/buried") };
|
||||
int m_ViaTypeChoiceNChoices = sizeof( m_ViaTypeChoiceChoices ) / sizeof( wxString );
|
||||
@ -353,79 +349,47 @@ DIALOG_TRACK_VIA_PROPERTIES_BASE::DIALOG_TRACK_VIA_PROPERTIES_BASE( wxWindow* pa
|
||||
m_ViaTypeChoice->SetSelection( 0 );
|
||||
m_ViaTypeChoice->Enable( false );
|
||||
|
||||
fgSizer4->Add( m_ViaTypeChoice, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
|
||||
|
||||
|
||||
fgSizer4->Add( 0, 3, 1, wxEXPAND, 5 );
|
||||
|
||||
|
||||
fgSizer4->Add( 0, 0, 1, wxEXPAND, 5 );
|
||||
gbSizer4->Add( m_ViaTypeChoice, wxGBPosition( 0, 1 ), wxGBSpan( 1, 1 ), wxBOTTOM|wxEXPAND, 5 );
|
||||
|
||||
m_ViaStartLayerLabel = new wxStaticText( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("Start layer:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_ViaStartLayerLabel->Wrap( -1 );
|
||||
fgSizer4->Add( m_ViaStartLayerLabel, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
|
||||
gbSizer4->Add( m_ViaStartLayerLabel, wxGBPosition( 1, 0 ), wxGBSpan( 1, 1 ), wxALIGN_LEFT|wxALL, 5 );
|
||||
|
||||
m_ViaStartLayer = new PCB_LAYER_BOX_SELECTOR( m_sbViaSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 );
|
||||
fgSizer4->Add( m_ViaStartLayer, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
|
||||
gbSizer4->Add( m_ViaStartLayer, wxGBPosition( 1, 1 ), wxGBSpan( 1, 1 ), wxBOTTOM|wxEXPAND, 5 );
|
||||
|
||||
m_ViaEndLayerLabel1 = new wxStaticText( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("End layer:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_ViaEndLayerLabel1->Wrap( -1 );
|
||||
fgSizer4->Add( m_ViaEndLayerLabel1, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
|
||||
gbSizer4->Add( m_ViaEndLayerLabel1, wxGBPosition( 2, 0 ), wxGBSpan( 1, 1 ), wxALIGN_LEFT|wxALL, 5 );
|
||||
|
||||
m_ViaEndLayer = new PCB_LAYER_BOX_SELECTOR( m_sbViaSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 );
|
||||
fgSizer4->Add( m_ViaEndLayer, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
|
||||
|
||||
|
||||
fgSizer4->Add( 0, 15, 1, wxEXPAND, 5 );
|
||||
|
||||
|
||||
fgSizer4->Add( 0, 0, 1, wxEXPAND, 5 );
|
||||
gbSizer4->Add( m_ViaEndLayer, wxGBPosition( 2, 1 ), wxGBSpan( 1, 1 ), wxBOTTOM|wxEXPAND, 5 );
|
||||
|
||||
m_annularRingsLabel = new wxStaticText( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("Annular rings:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_annularRingsLabel->Wrap( -1 );
|
||||
fgSizer4->Add( m_annularRingsLabel, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT, 5 );
|
||||
gbSizer4->Add( m_annularRingsLabel, wxGBPosition( 3, 0 ), wxGBSpan( 1, 1 ), wxALIGN_LEFT|wxALL, 5 );
|
||||
|
||||
wxString m_annularRingsCtrlChoices[] = { _("All copper layers"), _("Start, end, and connected layers"), _("Connected layers only") };
|
||||
int m_annularRingsCtrlNChoices = sizeof( m_annularRingsCtrlChoices ) / sizeof( wxString );
|
||||
m_annularRingsCtrl = new wxChoice( m_sbViaSizer->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, m_annularRingsCtrlNChoices, m_annularRingsCtrlChoices, 0 );
|
||||
m_annularRingsCtrl->SetSelection( 1 );
|
||||
fgSizer4->Add( m_annularRingsCtrl, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxEXPAND, 5 );
|
||||
m_annularRingsCtrl->SetSelection( 0 );
|
||||
gbSizer4->Add( m_annularRingsCtrl, wxGBPosition( 3, 1 ), wxGBSpan( 1, 1 ), wxBOTTOM|wxEXPAND, 5 );
|
||||
|
||||
m_tentingFrontLabel = new wxStaticText( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("Front tenting:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_tentingFrontLabel->Wrap( -1 );
|
||||
fgSizer4->Add( m_tentingFrontLabel, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
|
||||
m_protectionPresetsLabel = new wxStaticText( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("Protection features:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_protectionPresetsLabel->Wrap( -1 );
|
||||
gbSizer4->Add( m_protectionPresetsLabel, wxGBPosition( 4, 0 ), wxGBSpan( 1, 1 ), wxALIGN_LEFT|wxALL, 5 );
|
||||
|
||||
wxString m_tentingFrontCtrlChoices[] = { _("From design rules"), _("Tented"), _("Not tented") };
|
||||
int m_tentingFrontCtrlNChoices = sizeof( m_tentingFrontCtrlChoices ) / sizeof( wxString );
|
||||
m_tentingFrontCtrl = new wxChoice( m_sbViaSizer->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, m_tentingFrontCtrlNChoices, m_tentingFrontCtrlChoices, 0 );
|
||||
m_tentingFrontCtrl->SetSelection( 0 );
|
||||
m_tentingFrontCtrl->SetToolTip( _("Whether to tent (cover with soldermask) this via on the front side") );
|
||||
wxArrayString m_protectionFeaturesChoices;
|
||||
m_protectionFeatures = new wxChoice( m_sbViaSizer->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, m_protectionFeaturesChoices, 0 );
|
||||
m_protectionFeatures->SetSelection( 0 );
|
||||
m_protectionFeatures->SetToolTip( _("Select which protection feature according to IPC-4761 the via should have.") );
|
||||
|
||||
fgSizer4->Add( m_tentingFrontCtrl, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxEXPAND, 5 );
|
||||
|
||||
m_btnLinkTenting = new wxBitmapToggleButton( m_sbViaSizer->GetStaticBox(), wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_btnLinkTenting->SetValue( true );
|
||||
m_btnLinkTenting->SetToolTip( _("Link front and back tenting settings") );
|
||||
|
||||
fgSizer4->Add( m_btnLinkTenting, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5 );
|
||||
gbSizer4->Add( m_protectionFeatures, wxGBPosition( 4, 1 ), wxGBSpan( 1, 1 ), wxBOTTOM|wxEXPAND, 5 );
|
||||
|
||||
|
||||
fgSizer4->Add( 0, 0, 1, wxEXPAND, 5 );
|
||||
gbSizer4->AddGrowableCol( 1 );
|
||||
|
||||
m_tentingBackLabel = new wxStaticText( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("Back tenting:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_tentingBackLabel->Wrap( -1 );
|
||||
fgSizer4->Add( m_tentingBackLabel, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5 );
|
||||
|
||||
wxString m_tentingBackCtrlChoices[] = { _("From design rules"), _("Tented"), _("Not tented") };
|
||||
int m_tentingBackCtrlNChoices = sizeof( m_tentingBackCtrlChoices ) / sizeof( wxString );
|
||||
m_tentingBackCtrl = new wxChoice( m_sbViaSizer->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, m_tentingBackCtrlNChoices, m_tentingBackCtrlChoices, 0 );
|
||||
m_tentingBackCtrl->SetSelection( 0 );
|
||||
m_tentingBackCtrl->SetToolTip( _("Whether to tent (cover with soldermask) this via on the back side") );
|
||||
|
||||
fgSizer4->Add( m_tentingBackCtrl, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
|
||||
|
||||
|
||||
viaRightColumn->Add( fgSizer4, 0, wxEXPAND|wxBOTTOM, 3 );
|
||||
viaRightColumn->Add( gbSizer4, 1, wxEXPAND, 5 );
|
||||
|
||||
|
||||
bSizerViaCols->Add( viaRightColumn, 1, wxEXPAND, 5 );
|
||||
@ -692,8 +656,6 @@ DIALOG_TRACK_VIA_PROPERTIES_BASE::DIALOG_TRACK_VIA_PROPERTIES_BASE( wxWindow* pa
|
||||
m_ViaTypeChoice->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onViaEdit ), NULL, this );
|
||||
m_ViaStartLayer->Connect( wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onViaEdit ), NULL, this );
|
||||
m_ViaEndLayer->Connect( wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onViaEdit ), NULL, this );
|
||||
m_tentingFrontCtrl->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onFrontTentingChanged ), NULL, this );
|
||||
m_btnLinkTenting->Connect( wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTentingLinkToggle ), NULL, this );
|
||||
m_cbTeardrops->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
|
||||
m_cbTeardropsUseNextTrack->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
|
||||
m_stHDRatio->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
|
||||
@ -735,8 +697,6 @@ DIALOG_TRACK_VIA_PROPERTIES_BASE::~DIALOG_TRACK_VIA_PROPERTIES_BASE()
|
||||
m_ViaTypeChoice->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onViaEdit ), NULL, this );
|
||||
m_ViaStartLayer->Disconnect( wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onViaEdit ), NULL, this );
|
||||
m_ViaEndLayer->Disconnect( wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onViaEdit ), NULL, this );
|
||||
m_tentingFrontCtrl->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onFrontTentingChanged ), NULL, this );
|
||||
m_btnLinkTenting->Disconnect( wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTentingLinkToggle ), NULL, this );
|
||||
m_cbTeardrops->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
|
||||
m_cbTeardropsUseNextTrack->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
|
||||
m_stHDRatio->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
|
||||
|
@ -2084,7 +2084,7 @@
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND</property>
|
||||
<property name="proportion">1</property>
|
||||
<object class="wxBoxSizer" expanded="true">
|
||||
<object class="wxBoxSizer" expanded="false">
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">bSizerViasLeftCol</property>
|
||||
<property name="orient">wxVERTICAL</property>
|
||||
@ -2423,11 +2423,11 @@
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="true">
|
||||
<object class="sizeritem" expanded="false">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND|wxTOP</property>
|
||||
<property name="proportion">1</property>
|
||||
<object class="wxGridBagSizer" expanded="true">
|
||||
<object class="wxGridBagSizer" expanded="false">
|
||||
<property name="empty_cell_size">-1,0</property>
|
||||
<property name="flexible_direction">wxBOTH</property>
|
||||
<property name="growablecols">1</property>
|
||||
@ -2438,7 +2438,7 @@
|
||||
<property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
|
||||
<property name="permission">none</property>
|
||||
<property name="vgap">3</property>
|
||||
<object class="gbsizeritem" expanded="true">
|
||||
<object class="gbsizeritem" expanded="false">
|
||||
<property name="border">1</property>
|
||||
<property name="colspan">1</property>
|
||||
<property name="column">0</property>
|
||||
@ -2503,7 +2503,7 @@
|
||||
<property name="wrap">-1</property>
|
||||
</object>
|
||||
</object>
|
||||
<object class="gbsizeritem" expanded="true">
|
||||
<object class="gbsizeritem" expanded="false">
|
||||
<property name="border">3</property>
|
||||
<property name="colspan">1</property>
|
||||
<property name="column">1</property>
|
||||
@ -2572,7 +2572,7 @@
|
||||
<event name="OnChoice">onViaSelect</event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="gbsizeritem" expanded="true">
|
||||
<object class="gbsizeritem" expanded="false">
|
||||
<property name="border">5</property>
|
||||
<property name="colspan">1</property>
|
||||
<property name="column">2</property>
|
||||
@ -2637,23 +2637,23 @@
|
||||
<property name="wrap">-1</property>
|
||||
</object>
|
||||
</object>
|
||||
<object class="gbsizeritem" expanded="true">
|
||||
<object class="gbsizeritem" expanded="false">
|
||||
<property name="border">0</property>
|
||||
<property name="colspan">3</property>
|
||||
<property name="column">0</property>
|
||||
<property name="flag">wxEXPAND</property>
|
||||
<property name="row">2</property>
|
||||
<property name="rowspan">1</property>
|
||||
<object class="wxBoxSizer" expanded="true">
|
||||
<object class="wxBoxSizer" expanded="false">
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">m_sbPadstackSettings</property>
|
||||
<property name="orient">wxHORIZONTAL</property>
|
||||
<property name="permission">protected</property>
|
||||
<object class="sizeritem" expanded="true">
|
||||
<object class="sizeritem" expanded="false">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALIGN_CENTER_VERTICAL</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxStaticText" expanded="true">
|
||||
<object class="wxStaticText" expanded="false">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
@ -2711,11 +2711,11 @@
|
||||
<property name="wrap">-1</property>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="true">
|
||||
<object class="sizeritem" expanded="false">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALL</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxChoice" expanded="true">
|
||||
<object class="wxChoice" expanded="false">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
@ -2777,11 +2777,11 @@
|
||||
<event name="OnChoice">onPadstackModeChanged</event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="true">
|
||||
<object class="sizeritem" expanded="false">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxStaticText" expanded="true">
|
||||
<object class="wxStaticText" expanded="false">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
@ -2839,11 +2839,11 @@
|
||||
<property name="wrap">-1</property>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="true">
|
||||
<object class="sizeritem" expanded="false">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALL</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxChoice" expanded="true">
|
||||
<object class="wxChoice" expanded="false">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
@ -2907,7 +2907,7 @@
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<object class="gbsizeritem" expanded="true">
|
||||
<object class="gbsizeritem" expanded="false">
|
||||
<property name="border">1</property>
|
||||
<property name="colspan">1</property>
|
||||
<property name="column">0</property>
|
||||
@ -2972,7 +2972,7 @@
|
||||
<property name="wrap">-1</property>
|
||||
</object>
|
||||
</object>
|
||||
<object class="gbsizeritem" expanded="true">
|
||||
<object class="gbsizeritem" expanded="false">
|
||||
<property name="border">5</property>
|
||||
<property name="colspan">1</property>
|
||||
<property name="column">1</property>
|
||||
@ -3041,7 +3041,7 @@
|
||||
<event name="OnText">onViaEdit</event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="gbsizeritem" expanded="true">
|
||||
<object class="gbsizeritem" expanded="false">
|
||||
<property name="border">5</property>
|
||||
<property name="colspan">1</property>
|
||||
<property name="column">2</property>
|
||||
@ -3106,7 +3106,7 @@
|
||||
<property name="wrap">-1</property>
|
||||
</object>
|
||||
</object>
|
||||
<object class="gbsizeritem" expanded="true">
|
||||
<object class="gbsizeritem" expanded="false">
|
||||
<property name="border">1</property>
|
||||
<property name="colspan">1</property>
|
||||
<property name="column">0</property>
|
||||
@ -3171,7 +3171,7 @@
|
||||
<property name="wrap">-1</property>
|
||||
</object>
|
||||
</object>
|
||||
<object class="gbsizeritem" expanded="true">
|
||||
<object class="gbsizeritem" expanded="false">
|
||||
<property name="border">5</property>
|
||||
<property name="colspan">1</property>
|
||||
<property name="column">1</property>
|
||||
@ -3240,7 +3240,7 @@
|
||||
<event name="OnText">onViaEdit</event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="gbsizeritem" expanded="true">
|
||||
<object class="gbsizeritem" expanded="false">
|
||||
<property name="border">5</property>
|
||||
<property name="colspan">1</property>
|
||||
<property name="column">2</property>
|
||||
@ -3329,25 +3329,27 @@
|
||||
<property name="orient">wxVERTICAL</property>
|
||||
<property name="permission">none</property>
|
||||
<object class="sizeritem" expanded="true">
|
||||
<property name="border">3</property>
|
||||
<property name="flag">wxEXPAND|wxBOTTOM</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxFlexGridSizer" expanded="true">
|
||||
<property name="cols">2</property>
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND</property>
|
||||
<property name="proportion">1</property>
|
||||
<object class="wxGridBagSizer" expanded="true">
|
||||
<property name="empty_cell_size"></property>
|
||||
<property name="flexible_direction">wxBOTH</property>
|
||||
<property name="growablecols">1</property>
|
||||
<property name="growablerows">0,1,2</property>
|
||||
<property name="hgap">5</property>
|
||||
<property name="growablerows"></property>
|
||||
<property name="hgap">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">fgSizer4</property>
|
||||
<property name="name">gbSizer4</property>
|
||||
<property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
|
||||
<property name="permission">none</property>
|
||||
<property name="rows">0</property>
|
||||
<property name="vgap">0</property>
|
||||
<object class="sizeritem" expanded="true">
|
||||
<object class="gbsizeritem" expanded="true">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT</property>
|
||||
<property name="proportion">0</property>
|
||||
<property name="colspan">1</property>
|
||||
<property name="column">0</property>
|
||||
<property name="flag">wxALL</property>
|
||||
<property name="row">0</property>
|
||||
<property name="rowspan">1</property>
|
||||
<object class="wxStaticText" expanded="false">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
@ -3406,10 +3408,13 @@
|
||||
<property name="wrap">-1</property>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="true">
|
||||
<object class="gbsizeritem" expanded="true">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
|
||||
<property name="proportion">0</property>
|
||||
<property name="colspan">1</property>
|
||||
<property name="column">1</property>
|
||||
<property name="flag">wxBOTTOM|wxEXPAND</property>
|
||||
<property name="row">0</property>
|
||||
<property name="rowspan">1</property>
|
||||
<object class="wxChoice" expanded="false">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
@ -3472,30 +3477,13 @@
|
||||
<event name="OnChoice">onViaEdit</event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="true">
|
||||
<object class="gbsizeritem" expanded="true">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND</property>
|
||||
<property name="proportion">1</property>
|
||||
<object class="spacer" expanded="true">
|
||||
<property name="height">3</property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="width">0</property>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="true">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND</property>
|
||||
<property name="proportion">1</property>
|
||||
<object class="spacer" expanded="true">
|
||||
<property name="height">0</property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="width">0</property>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="true">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property>
|
||||
<property name="proportion">0</property>
|
||||
<property name="colspan">1</property>
|
||||
<property name="column">0</property>
|
||||
<property name="flag">wxALIGN_LEFT|wxALL</property>
|
||||
<property name="row">1</property>
|
||||
<property name="rowspan">1</property>
|
||||
<object class="wxStaticText" expanded="false">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
@ -3554,10 +3542,13 @@
|
||||
<property name="wrap">-1</property>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="true">
|
||||
<object class="gbsizeritem" expanded="true">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
|
||||
<property name="proportion">0</property>
|
||||
<property name="colspan">1</property>
|
||||
<property name="column">1</property>
|
||||
<property name="flag">wxBOTTOM|wxEXPAND</property>
|
||||
<property name="row">1</property>
|
||||
<property name="rowspan">1</property>
|
||||
<object class="wxBitmapComboBox" expanded="false">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
@ -3621,10 +3612,13 @@
|
||||
<event name="OnCombobox">onViaEdit</event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="true">
|
||||
<object class="gbsizeritem" expanded="true">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property>
|
||||
<property name="proportion">0</property>
|
||||
<property name="colspan">1</property>
|
||||
<property name="column">0</property>
|
||||
<property name="flag">wxALIGN_LEFT|wxALL</property>
|
||||
<property name="row">2</property>
|
||||
<property name="rowspan">1</property>
|
||||
<object class="wxStaticText" expanded="false">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
@ -3683,10 +3677,13 @@
|
||||
<property name="wrap">-1</property>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="true">
|
||||
<object class="gbsizeritem" expanded="true">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
|
||||
<property name="proportion">0</property>
|
||||
<property name="colspan">1</property>
|
||||
<property name="column">1</property>
|
||||
<property name="flag">wxBOTTOM|wxEXPAND</property>
|
||||
<property name="row">2</property>
|
||||
<property name="rowspan">1</property>
|
||||
<object class="wxBitmapComboBox" expanded="false">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
@ -3750,31 +3747,14 @@
|
||||
<event name="OnCombobox">onViaEdit</event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="true">
|
||||
<object class="gbsizeritem" expanded="true">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND</property>
|
||||
<property name="proportion">1</property>
|
||||
<object class="spacer" expanded="true">
|
||||
<property name="height">15</property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="width">0</property>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="true">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND</property>
|
||||
<property name="proportion">1</property>
|
||||
<object class="spacer" expanded="true">
|
||||
<property name="height">0</property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="width">0</property>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="true">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxStaticText" expanded="true">
|
||||
<property name="colspan">1</property>
|
||||
<property name="column">0</property>
|
||||
<property name="flag">wxALIGN_LEFT|wxALL</property>
|
||||
<property name="row">3</property>
|
||||
<property name="rowspan">1</property>
|
||||
<object class="wxStaticText" expanded="false">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
@ -3832,11 +3812,14 @@
|
||||
<property name="wrap">-1</property>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="true">
|
||||
<object class="gbsizeritem" expanded="true">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxEXPAND</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxChoice" expanded="true">
|
||||
<property name="colspan">1</property>
|
||||
<property name="column">1</property>
|
||||
<property name="flag">wxBOTTOM|wxEXPAND</property>
|
||||
<property name="row">3</property>
|
||||
<property name="rowspan">1</property>
|
||||
<object class="wxChoice" expanded="false">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
@ -3881,7 +3864,7 @@
|
||||
<property name="pin_button">1</property>
|
||||
<property name="pos"></property>
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="selection">1</property>
|
||||
<property name="selection">0</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="style"></property>
|
||||
@ -3897,11 +3880,14 @@
|
||||
<property name="window_style"></property>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="true">
|
||||
<object class="gbsizeritem" expanded="true">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxLEFT</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxStaticText" expanded="true">
|
||||
<property name="colspan">1</property>
|
||||
<property name="column">0</property>
|
||||
<property name="flag">wxALIGN_LEFT|wxALL</property>
|
||||
<property name="row">4</property>
|
||||
<property name="rowspan">1</property>
|
||||
<object class="wxStaticText" expanded="false">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
@ -3930,7 +3916,7 @@
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">Front tenting:</property>
|
||||
<property name="label">Protection features:</property>
|
||||
<property name="markup">0</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
@ -3939,7 +3925,7 @@
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_tentingFrontLabel</property>
|
||||
<property name="name">m_protectionPresetsLabel</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
@ -3959,10 +3945,13 @@
|
||||
<property name="wrap">-1</property>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="true">
|
||||
<object class="gbsizeritem" expanded="true">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxEXPAND</property>
|
||||
<property name="proportion">0</property>
|
||||
<property name="colspan">1</property>
|
||||
<property name="column">1</property>
|
||||
<property name="flag">wxBOTTOM|wxEXPAND</property>
|
||||
<property name="row">4</property>
|
||||
<property name="rowspan">1</property>
|
||||
<object class="wxChoice" expanded="true">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
@ -3977,7 +3966,7 @@
|
||||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="choices">"From design rules" "Tented" "Not tented"</property>
|
||||
<property name="choices"></property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
@ -4000,7 +3989,7 @@
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_tentingFrontCtrl</property>
|
||||
<property name="name">m_protectionFeatures</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
@ -4014,218 +4003,7 @@
|
||||
<property name="style"></property>
|
||||
<property name="subclass">; ; forward_declare</property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip">Whether to tent (cover with soldermask) this via on the front side</property>
|
||||
<property name="validator_data_type"></property>
|
||||
<property name="validator_style">wxFILTER_NONE</property>
|
||||
<property name="validator_type">wxDefaultValidator</property>
|
||||
<property name="validator_variable"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<event name="OnChoice">onFrontTentingChanged</event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="true">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxBitmapToggleButton" expanded="true">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer">0</property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position">0</property>
|
||||
<property name="aui_row">0</property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="bitmap"></property>
|
||||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="current"></property>
|
||||
<property name="default_pane">0</property>
|
||||
<property name="disabled"></property>
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="drag_accept_files">0</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
<property name="focus"></property>
|
||||
<property name="font"></property>
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">Link</property>
|
||||
<property name="margins"></property>
|
||||
<property name="markup">0</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="min_size"></property>
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_btnLinkTenting</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pin_button">1</property>
|
||||
<property name="pos"></property>
|
||||
<property name="position"></property>
|
||||
<property name="pressed"></property>
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="subclass">; ; forward_declare</property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip">Link front and back tenting settings</property>
|
||||
<property name="validator_data_type"></property>
|
||||
<property name="validator_style">wxFILTER_NONE</property>
|
||||
<property name="validator_type">wxDefaultValidator</property>
|
||||
<property name="validator_variable"></property>
|
||||
<property name="value">1</property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<event name="OnToggleButton">onTentingLinkToggle</event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="true">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND</property>
|
||||
<property name="proportion">1</property>
|
||||
<object class="spacer" expanded="true">
|
||||
<property name="height">0</property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="width">0</property>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="true">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxStaticText" expanded="true">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer">0</property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position">0</property>
|
||||
<property name="aui_row">0</property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="default_pane">0</property>
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="drag_accept_files">0</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
<property name="font"></property>
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">Back tenting:</property>
|
||||
<property name="markup">0</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="min_size"></property>
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_tentingBackLabel</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pin_button">1</property>
|
||||
<property name="pos"></property>
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="style"></property>
|
||||
<property name="subclass">; ; forward_declare</property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<property name="wrap">-1</property>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="true">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxChoice" expanded="true">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer">0</property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position">0</property>
|
||||
<property name="aui_row">0</property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="choices">"From design rules" "Tented" "Not tented"</property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="default_pane">0</property>
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="drag_accept_files">0</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
<property name="font"></property>
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="min_size"></property>
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_tentingBackCtrl</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pin_button">1</property>
|
||||
<property name="pos"></property>
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="selection">0</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="style"></property>
|
||||
<property name="subclass">; ; forward_declare</property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip">Whether to tent (cover with soldermask) this via on the back side</property>
|
||||
<property name="tooltip">Select which protection feature according to IPC-4761 the via should have.</property>
|
||||
<property name="validator_data_type"></property>
|
||||
<property name="validator_style">wxFILTER_NONE</property>
|
||||
<property name="validator_type">wxDefaultValidator</property>
|
||||
|
@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6)
|
||||
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6-dirty)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
@ -28,7 +28,6 @@ class PCB_LAYER_BOX_SELECTOR;
|
||||
#include <wx/choice.h>
|
||||
#include <wx/gbsizer.h>
|
||||
#include <wx/bmpcbox.h>
|
||||
#include <wx/tglbtn.h>
|
||||
#include <wx/bitmap.h>
|
||||
#include <wx/image.h>
|
||||
#include <wx/icon.h>
|
||||
@ -111,11 +110,8 @@ class DIALOG_TRACK_VIA_PROPERTIES_BASE : public DIALOG_SHIM
|
||||
PCB_LAYER_BOX_SELECTOR* m_ViaEndLayer;
|
||||
wxStaticText* m_annularRingsLabel;
|
||||
wxChoice* m_annularRingsCtrl;
|
||||
wxStaticText* m_tentingFrontLabel;
|
||||
wxChoice* m_tentingFrontCtrl;
|
||||
wxBitmapToggleButton* m_btnLinkTenting;
|
||||
wxStaticText* m_tentingBackLabel;
|
||||
wxChoice* m_tentingBackCtrl;
|
||||
wxStaticText* m_protectionPresetsLabel;
|
||||
wxChoice* m_protectionFeatures;
|
||||
wxStaticLine* m_staticline2;
|
||||
wxBoxSizer* m_legacyTeardropsWarning;
|
||||
wxStaticBitmap* m_legacyTeardropsIcon;
|
||||
@ -152,8 +148,6 @@ class DIALOG_TRACK_VIA_PROPERTIES_BASE : public DIALOG_SHIM
|
||||
virtual void onPadstackModeChanged( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void onEditLayerChanged( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void onViaEdit( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void onFrontTentingChanged( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void onTentingLinkToggle( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void onTeardropsUpdateUi( wxUpdateUIEvent& event ) { event.Skip(); }
|
||||
|
||||
|
||||
|
@ -106,6 +106,27 @@ void GENDRILL_WRITER_BASE::buildHolesList( DRILL_LAYER_PAIR aLayerPair,
|
||||
|
||||
via->LayerPair( &new_hole.m_Hole_Top_Layer, &new_hole.m_Hole_Bottom_Layer );
|
||||
|
||||
new_hole.m_Hole_Filled = via->Padstack().IsFilled().value_or( false );
|
||||
new_hole.m_Hole_Capped = via->Padstack().IsCapped().value_or( false );
|
||||
|
||||
new_hole.m_Hole_Top_Covered =
|
||||
via->Padstack().IsCovered( new_hole.m_Hole_Top_Layer ).value_or( false );
|
||||
|
||||
new_hole.m_Hole_Bot_Covered =
|
||||
via->Padstack().IsCovered( new_hole.m_Hole_Bottom_Layer ).value_or( false );
|
||||
|
||||
new_hole.m_Hole_Top_Plugged =
|
||||
via->Padstack().IsPlugged( new_hole.m_Hole_Top_Layer ).value_or( false );
|
||||
|
||||
new_hole.m_Hole_Bot_Plugged =
|
||||
via->Padstack().IsPlugged( new_hole.m_Hole_Bottom_Layer ).value_or( false );
|
||||
|
||||
new_hole.m_Hole_Top_Tented =
|
||||
via->Padstack().IsTented( new_hole.m_Hole_Top_Layer ).value_or( false );
|
||||
|
||||
new_hole.m_Hole_Bot_Tented =
|
||||
via->Padstack().IsTented( new_hole.m_Hole_Bottom_Layer ).value_or( false );
|
||||
|
||||
// LayerPair() returns params with m_Hole_Bottom_Layer > m_Hole_Top_Layer
|
||||
// Remember: top layer = 0 and bottom layer = 31 for through hole vias
|
||||
// Any captured via should be from aLayerPair.first to aLayerPair.second exactly.
|
||||
@ -302,6 +323,61 @@ const wxString GENDRILL_WRITER_BASE::getDrillFileName( DRILL_LAYER_PAIR aPair, b
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
const wxString GENDRILL_WRITER_BASE::getProtectionFileName( DRILL_LAYER_PAIR aPair,
|
||||
IPC4761_FEATURES aFeature ) const
|
||||
{
|
||||
wxASSERT( m_pcb );
|
||||
|
||||
wxString extend;
|
||||
|
||||
switch( aFeature )
|
||||
{
|
||||
case IPC4761_FEATURES::FILLED:
|
||||
extend << wxT( "-filling-" );
|
||||
extend << layerPairName( aPair );
|
||||
break;
|
||||
case IPC4761_FEATURES::CAPPED:
|
||||
extend << wxT( "-capping-" );
|
||||
extend << layerPairName( aPair );
|
||||
break;
|
||||
case IPC4761_FEATURES::COVERED_BACK:
|
||||
extend << wxT( "-covering-" );
|
||||
extend << layerName( aPair.second );
|
||||
break;
|
||||
case IPC4761_FEATURES::COVERED_FRONT:
|
||||
extend << wxT( "-covering-" );
|
||||
extend << layerName( aPair.first );
|
||||
break;
|
||||
case IPC4761_FEATURES::PLUGGED_BACK:
|
||||
extend << wxT( "-plugging-" );
|
||||
extend << layerName( aPair.second );
|
||||
break;
|
||||
case IPC4761_FEATURES::PLUGGED_FRONT:
|
||||
extend << wxT( "-plugging-" );
|
||||
extend << layerName( aPair.first );
|
||||
break;
|
||||
case IPC4761_FEATURES::TENTED_BACK:
|
||||
extend << wxT( "-tenting-" );
|
||||
extend << layerName( aPair.second );
|
||||
break;
|
||||
case IPC4761_FEATURES::TENTED_FRONT:
|
||||
extend << wxT( "-tenting-" );
|
||||
extend << layerName( aPair.first );
|
||||
break;
|
||||
}
|
||||
|
||||
wxFileName fn = m_pcb->GetFileName();
|
||||
|
||||
fn.SetName( fn.GetName() + extend );
|
||||
fn.SetExt( m_drillFileExtension );
|
||||
|
||||
wxString ret = fn.GetFullName();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
bool GENDRILL_WRITER_BASE::CreateMapFilesSet( const wxString& aPlotDirectory,
|
||||
REPORTER * aReporter )
|
||||
{
|
||||
|
@ -50,6 +50,18 @@ enum class HOLE_ATTRIBUTE
|
||||
HOLE_MECHANICAL // a mechanical pad (provided, not used)
|
||||
};
|
||||
|
||||
// Via Protection features according to IPC-4761.
|
||||
enum class IPC4761_FEATURES : int
|
||||
{
|
||||
FILLED,
|
||||
CAPPED,
|
||||
PLUGGED_FRONT,
|
||||
PLUGGED_BACK,
|
||||
COVERED_FRONT,
|
||||
COVERED_BACK,
|
||||
TENTED_FRONT,
|
||||
TENTED_BACK
|
||||
};
|
||||
|
||||
// the DRILL_TOOL class handles tools used in the excellon drill file:
|
||||
class DRILL_TOOL
|
||||
@ -95,6 +107,14 @@ public:
|
||||
m_Hole_Bottom_Layer = B_Cu;
|
||||
m_Hole_Top_Layer = F_Cu;
|
||||
m_HoleAttribute = HOLE_ATTRIBUTE::HOLE_UNKNOWN;
|
||||
m_Hole_Filled = false;
|
||||
m_Hole_Capped = false;
|
||||
m_Hole_Top_Covered = false;
|
||||
m_Hole_Bot_Covered = false;
|
||||
m_Hole_Top_Plugged = false;
|
||||
m_Hole_Bot_Plugged = false;
|
||||
m_Hole_Top_Tented = false;
|
||||
m_Hole_Bot_Tented = false;
|
||||
}
|
||||
|
||||
public:
|
||||
@ -114,6 +134,15 @@ public:
|
||||
// section.
|
||||
HOLE_ATTRIBUTE m_HoleAttribute; // Attribute, used in Excellon drill file and to sort holes
|
||||
// by type.
|
||||
|
||||
bool m_Hole_Filled; // hole should be filled
|
||||
bool m_Hole_Capped; // hole should be capped
|
||||
bool m_Hole_Top_Covered; // hole should be covered on top
|
||||
bool m_Hole_Bot_Covered; // hole should be covered on bottom
|
||||
bool m_Hole_Top_Plugged; // hole should be plugged on top
|
||||
bool m_Hole_Bot_Plugged; // hole should be plugged on bottom
|
||||
bool m_Hole_Top_Tented; // hole should be tented on top
|
||||
bool m_Hole_Bot_Tented; // hole should be tented on bottom
|
||||
};
|
||||
|
||||
|
||||
@ -347,6 +376,16 @@ protected:
|
||||
bool aMerge_PTH_NPTH ) const;
|
||||
|
||||
|
||||
/**
|
||||
* @param aPair is the layer pair.
|
||||
* @param aFeature Is the protection feature represented by the file
|
||||
* @return a filename which identifies the specific protection feature.
|
||||
* It is the board file name followed by the feature name and the layer(s) associated with it.
|
||||
*/
|
||||
virtual const wxString getProtectionFileName( DRILL_LAYER_PAIR aPair,
|
||||
IPC4761_FEATURES aFeature ) const;
|
||||
|
||||
|
||||
/**
|
||||
* @param aLayerPair is the layer pair (Drill from rom first layer to second layer)
|
||||
* @param aHoleType is type of drill file (PTH, NPTH, mixed)
|
||||
|
@ -58,7 +58,7 @@ GERBER_WRITER::GERBER_WRITER( BOARD* aPcb )
|
||||
|
||||
|
||||
bool GERBER_WRITER::CreateDrillandMapFilesSet( const wxString& aPlotDirectory, bool aGenDrill,
|
||||
bool aGenMap, REPORTER* aReporter )
|
||||
bool aGenMap, bool aGenTenting, REPORTER* aReporter )
|
||||
{
|
||||
bool success = true;
|
||||
// Note: In Gerber drill files, NPTH and PTH are always separate files
|
||||
@ -117,7 +117,48 @@ bool GERBER_WRITER::CreateDrillandMapFilesSet( const wxString& aPlotDirectory, b
|
||||
aReporter->Report( msg, RPT_SEVERITY_ACTION );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( getHolesCount() > 0 && !doing_npth )
|
||||
{
|
||||
for( IPC4761_FEATURES feature :
|
||||
{ IPC4761_FEATURES::FILLED, IPC4761_FEATURES::CAPPED,
|
||||
IPC4761_FEATURES::COVERED_BACK, IPC4761_FEATURES::COVERED_FRONT,
|
||||
IPC4761_FEATURES::PLUGGED_BACK, IPC4761_FEATURES::PLUGGED_FRONT,
|
||||
IPC4761_FEATURES::TENTED_BACK, IPC4761_FEATURES::TENTED_FRONT } )
|
||||
{
|
||||
if( !aGenTenting )
|
||||
{
|
||||
if( feature == IPC4761_FEATURES::TENTED_BACK
|
||||
|| feature == IPC4761_FEATURES::TENTED_FRONT )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
fn = getProtectionFileName( pair, feature );
|
||||
fn.SetPath( aPlotDirectory );
|
||||
|
||||
wxString fullFilename = fn.GetFullPath();
|
||||
|
||||
if( createProtectionFile( fullFilename, feature, pair ) < 0 )
|
||||
{
|
||||
if( aReporter )
|
||||
{
|
||||
msg.Printf( _( "Failed to create file '%s'." ), fullFilename );
|
||||
aReporter->Report( msg, RPT_SEVERITY_ERROR );
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( aReporter )
|
||||
{
|
||||
msg.Printf( _( "Created file '%s'." ), fullFilename );
|
||||
aReporter->Report( msg, RPT_SEVERITY_ACTION );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -137,6 +178,141 @@ bool GERBER_WRITER::CreateDrillandMapFilesSet( const wxString& aPlotDirectory, b
|
||||
static void convertOblong2Segment( const VECTOR2I& aSize, const EDA_ANGLE& aOrient, VECTOR2I& aStart, VECTOR2I& aEnd );
|
||||
#endif
|
||||
|
||||
int GERBER_WRITER::createProtectionFile( const wxString& aFullFilename, IPC4761_FEATURES aFeature,
|
||||
DRILL_LAYER_PAIR aLayerPair )
|
||||
{
|
||||
GERBER_PLOTTER plotter;
|
||||
// Gerber drill file imply X2 format:
|
||||
plotter.UseX2format( true );
|
||||
plotter.UseX2NetAttributes( true );
|
||||
plotter.DisableApertMacros( false );
|
||||
|
||||
// Add the standard X2 header, without FileFunction
|
||||
AddGerberX2Header( &plotter, m_pcb );
|
||||
plotter.SetViewport( m_offset, pcbIUScale.IU_PER_MILS / 10, /* scale */ 1.0,
|
||||
/* mirror */ false );
|
||||
|
||||
// has meaning only for gerber plotter. Must be called only after SetViewport
|
||||
plotter.SetGerberCoordinatesFormat( 6 );
|
||||
plotter.SetCreator( wxT( "PCBNEW" ) );
|
||||
|
||||
// Add the standard X2 FileFunction for drill files
|
||||
// %TF.FileFunction,Plated[NonPlated],layer1num,layer2num,PTH[NPTH][Blind][Buried],Drill[Rout][Mixed]*%
|
||||
wxString text = "%TF,FileFunction,Other,";
|
||||
|
||||
std::string attrib;
|
||||
switch( aFeature )
|
||||
{
|
||||
case IPC4761_FEATURES::CAPPED:
|
||||
text << wxT( "Capping" );
|
||||
attrib = "Capping";
|
||||
break;
|
||||
case IPC4761_FEATURES::FILLED:
|
||||
text << wxT( "Filling" );
|
||||
attrib = "Filling";
|
||||
break;
|
||||
case IPC4761_FEATURES::COVERED_BACK:
|
||||
text << wxT( "Covering-Back" );
|
||||
attrib = "Covering";
|
||||
break;
|
||||
case IPC4761_FEATURES::COVERED_FRONT:
|
||||
text << wxT( "Covering-Front" );
|
||||
attrib = "Covering";
|
||||
break;
|
||||
case IPC4761_FEATURES::PLUGGED_BACK:
|
||||
text << wxT( "Plugging-Back" );
|
||||
attrib = "Plugging";
|
||||
break;
|
||||
case IPC4761_FEATURES::PLUGGED_FRONT:
|
||||
text << wxT( "Plugging-Front" );
|
||||
attrib = "Plugging";
|
||||
break;
|
||||
case IPC4761_FEATURES::TENTED_BACK:
|
||||
text << wxT( "Tenting-Back" );
|
||||
attrib = "Tenting";
|
||||
break;
|
||||
case IPC4761_FEATURES::TENTED_FRONT:
|
||||
text << wxT( "Tenting-Front" );
|
||||
attrib = "Tenting";
|
||||
break;
|
||||
default: return -1;
|
||||
}
|
||||
text << wxT( "*%" );
|
||||
plotter.AddLineToHeader( text );
|
||||
|
||||
// Add file polarity (positive)
|
||||
text = wxT( "%TF.FilePolarity,Positive*%" );
|
||||
plotter.AddLineToHeader( text );
|
||||
|
||||
|
||||
if( !plotter.OpenFile( aFullFilename ) )
|
||||
return -1;
|
||||
|
||||
plotter.StartPlot( wxT( "1" ) );
|
||||
|
||||
int holes_count = 0;
|
||||
|
||||
for( auto& hole_descr : m_holeListBuffer )
|
||||
{
|
||||
if( !dyn_cast<const PCB_VIA*>( hole_descr.m_ItemParent ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const PCB_VIA* via = dyn_cast<const PCB_VIA*>( hole_descr.m_ItemParent );
|
||||
|
||||
bool cont = false;
|
||||
int diameter = hole_descr.m_Hole_Diameter;
|
||||
// clang-format off: suggestion is inconsitent
|
||||
switch( aFeature )
|
||||
{
|
||||
case IPC4761_FEATURES::FILLED:
|
||||
cont = ! hole_descr.m_Hole_Filled;
|
||||
break;
|
||||
case IPC4761_FEATURES::CAPPED:
|
||||
cont = ! hole_descr.m_Hole_Capped;
|
||||
break;
|
||||
case IPC4761_FEATURES::COVERED_BACK:
|
||||
cont = !hole_descr.m_Hole_Bot_Covered;
|
||||
diameter = via->GetWidth( via->BottomLayer() );
|
||||
break;
|
||||
case IPC4761_FEATURES::COVERED_FRONT:
|
||||
cont = ! hole_descr.m_Hole_Top_Covered;
|
||||
diameter = via->GetWidth( via->TopLayer() );
|
||||
break;
|
||||
case IPC4761_FEATURES::PLUGGED_BACK:
|
||||
cont = !hole_descr.m_Hole_Bot_Plugged;
|
||||
break;
|
||||
case IPC4761_FEATURES::PLUGGED_FRONT:
|
||||
cont = ! hole_descr.m_Hole_Top_Plugged;
|
||||
break;
|
||||
case IPC4761_FEATURES::TENTED_BACK:
|
||||
cont = ! hole_descr.m_Hole_Bot_Tented;
|
||||
diameter = via->GetWidth( via->BottomLayer() );
|
||||
break;
|
||||
case IPC4761_FEATURES::TENTED_FRONT:
|
||||
cont = ! hole_descr.m_Hole_Top_Tented;
|
||||
diameter = via->GetWidth( via->TopLayer() );
|
||||
break;
|
||||
}
|
||||
// clang-format on: suggestion is inconsitent
|
||||
|
||||
if( cont )
|
||||
continue;
|
||||
|
||||
GBR_METADATA gbr_metadata;
|
||||
|
||||
gbr_metadata.SetApertureAttrib( attrib );
|
||||
|
||||
plotter.FlashPadCircle( hole_descr.m_Hole_Pos, diameter, FILLED, &gbr_metadata );
|
||||
|
||||
holes_count++;
|
||||
}
|
||||
|
||||
plotter.EndPlot();
|
||||
|
||||
return holes_count;
|
||||
}
|
||||
|
||||
int GERBER_WRITER::createDrillFile( wxString& aFullFilename, bool aIsNpth,
|
||||
DRILL_LAYER_PAIR aLayerPair )
|
||||
|
@ -73,13 +73,13 @@ public:
|
||||
* @param aPlotDirectory is the output folder.
|
||||
* @param aGenDrill set to true to generate the EXCELLON drill file.
|
||||
* @param aGenMap set to true to generate a drill map file.
|
||||
* @param aGenTenting set to true to generate tenting layer files.
|
||||
* @param aReporter is a #REPORTER to return activity or any message (can be NULL).
|
||||
*
|
||||
* @return True if successful, false if any error occurred
|
||||
*/
|
||||
bool CreateDrillandMapFilesSet( const wxString& aPlotDirectory,
|
||||
bool aGenDrill, bool aGenMap,
|
||||
REPORTER * aReporter = nullptr );
|
||||
bool CreateDrillandMapFilesSet( const wxString& aPlotDirectory, bool aGenDrill, bool aGenMap,
|
||||
bool aGenTenting, REPORTER* aReporter = nullptr );
|
||||
|
||||
private:
|
||||
/**
|
||||
@ -93,6 +93,16 @@ private:
|
||||
*/
|
||||
int createDrillFile( wxString& aFullFilename, bool aIsNpth, DRILL_LAYER_PAIR aLayerPair );
|
||||
|
||||
/**
|
||||
* Create a Gerber X2 file for via protection features.
|
||||
*
|
||||
* @param aFullFilename is the full file name
|
||||
* @param aFeature the protection feature this file represents
|
||||
* @param aLayerPair is the first and last layer pair for the via drill. Usually is top and bottom.
|
||||
*/
|
||||
int createProtectionFile( const wxString& aFullFilename, IPC4761_FEATURES aFeature,
|
||||
DRILL_LAYER_PAIR aLayerPair );
|
||||
|
||||
/**
|
||||
* @param aPair is the layer pair.
|
||||
* @param aNPTH set to true to generate the filename of NPTH holes.
|
||||
|
@ -213,6 +213,18 @@ bool PADSTACK::Deserialize( const google::protobuf::Any& aContainer )
|
||||
using namespace kiapi::board::types;
|
||||
PadStack padstack;
|
||||
|
||||
auto unpackOptional = []<typename ProtoEnum>( const ProtoEnum& aProto,
|
||||
std::optional<bool>& aDest, ProtoEnum aTrueValue,
|
||||
ProtoEnum aFalseValue )
|
||||
{
|
||||
if( aProto == aTrueValue )
|
||||
aDest = true;
|
||||
else if( aProto == aFalseValue )
|
||||
aDest = false;
|
||||
else
|
||||
aDest = std::nullopt;
|
||||
};
|
||||
|
||||
if( !aContainer.UnpackTo( &padstack ) )
|
||||
return false;
|
||||
|
||||
@ -223,6 +235,8 @@ bool PADSTACK::Deserialize( const google::protobuf::Any& aContainer )
|
||||
Drill().size = kiapi::common::UnpackVector2( padstack.drill().diameter() );
|
||||
Drill().start = FromProtoEnum<PCB_LAYER_ID>( padstack.drill().start_layer() );
|
||||
Drill().end = FromProtoEnum<PCB_LAYER_ID>( padstack.drill().end_layer() );
|
||||
unpackOptional( padstack.drill().capped(), Drill().is_capped, VDCM_CAPPED, VDCM_UNCAPPED );
|
||||
unpackOptional( padstack.drill().filled(), Drill().is_filled, VDFM_FILLED, VDFM_UNFILLED );
|
||||
|
||||
for( const PadStackLayer& layer : padstack.copper_layers() )
|
||||
{
|
||||
@ -260,57 +274,29 @@ bool PADSTACK::Deserialize( const google::protobuf::Any& aContainer )
|
||||
SetUnconnectedLayerMode(
|
||||
FromProtoEnum<UNCONNECTED_LAYER_MODE>( padstack.unconnected_layer_removal() ) );
|
||||
|
||||
auto unpackMask =
|
||||
[]( const SolderMaskMode& aProto, std::optional<bool>& aDest )
|
||||
{
|
||||
switch( aProto )
|
||||
{
|
||||
case kiapi::board::types::SMM_MASKED:
|
||||
aDest = true;
|
||||
break;
|
||||
unpackOptional( padstack.front_outer_layers().solder_mask_mode(),
|
||||
FrontOuterLayers().has_solder_mask, SMM_MASKED, SMM_UNMASKED );
|
||||
|
||||
case kiapi::board::types::SMM_UNMASKED:
|
||||
aDest = false;
|
||||
break;
|
||||
unpackOptional( padstack.back_outer_layers().solder_mask_mode(),
|
||||
BackOuterLayers().has_solder_mask, SMM_MASKED, SMM_UNMASKED );
|
||||
|
||||
default:
|
||||
case kiapi::board::types::SMM_FROM_DESIGN_RULES:
|
||||
aDest = std::nullopt;
|
||||
break;
|
||||
}
|
||||
};
|
||||
unpackOptional( padstack.front_outer_layers().covering_mode(), FrontOuterLayers().has_covering,
|
||||
VCM_COVERED, VCM_UNCOVERED );
|
||||
|
||||
unpackMask( padstack.front_outer_layers().solder_mask_mode(),
|
||||
FrontOuterLayers().has_solder_mask );
|
||||
unpackOptional( padstack.back_outer_layers().covering_mode(), BackOuterLayers().has_covering,
|
||||
VCM_COVERED, VCM_UNCOVERED );
|
||||
|
||||
unpackMask( padstack.back_outer_layers().solder_mask_mode(),
|
||||
BackOuterLayers().has_solder_mask );
|
||||
unpackOptional( padstack.front_outer_layers().plugging_mode(), FrontOuterLayers().has_plugging,
|
||||
VPM_PLUGGED, VPM_UNPLUGGED );
|
||||
|
||||
auto unpackPaste =
|
||||
[]( const SolderPasteMode& aProto, std::optional<bool>& aDest )
|
||||
{
|
||||
switch( aProto )
|
||||
{
|
||||
case kiapi::board::types::SPM_PASTE:
|
||||
aDest = true;
|
||||
break;
|
||||
unpackOptional( padstack.back_outer_layers().plugging_mode(), BackOuterLayers().has_plugging,
|
||||
VPM_PLUGGED, VPM_UNPLUGGED );
|
||||
|
||||
case kiapi::board::types::SPM_NO_PASTE:
|
||||
aDest = false;
|
||||
break;
|
||||
unpackOptional( padstack.front_outer_layers().solder_paste_mode(),
|
||||
FrontOuterLayers().has_solder_paste, SPM_PASTE, SPM_NO_PASTE );
|
||||
|
||||
default:
|
||||
case kiapi::board::types::SPM_FROM_DESIGN_RULES:
|
||||
aDest = std::nullopt;
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
unpackPaste( padstack.front_outer_layers().solder_paste_mode(),
|
||||
FrontOuterLayers().has_solder_paste );
|
||||
|
||||
unpackPaste( padstack.back_outer_layers().solder_paste_mode(),
|
||||
BackOuterLayers().has_solder_paste );
|
||||
unpackOptional( padstack.back_outer_layers().solder_paste_mode(),
|
||||
BackOuterLayers().has_solder_paste, SPM_PASTE, SPM_NO_PASTE );
|
||||
|
||||
if( padstack.front_outer_layers().has_solder_mask_settings()
|
||||
&& padstack.front_outer_layers().solder_mask_settings().has_solder_mask_margin() )
|
||||
@ -429,6 +415,16 @@ void PADSTACK::Serialize( google::protobuf::Any& aContainer ) const
|
||||
using namespace kiapi::board::types;
|
||||
PadStack padstack;
|
||||
|
||||
auto packOptional = []<typename ProtoEnum>( const std::optional<bool>& aVal, ProtoEnum aTrueVal,
|
||||
ProtoEnum aFalseVal,
|
||||
ProtoEnum aNullVal ) -> ProtoEnum
|
||||
{
|
||||
if( aVal.has_value() )
|
||||
return *aVal ? aTrueVal : aFalseVal;
|
||||
|
||||
return aNullVal;
|
||||
};
|
||||
|
||||
padstack.set_type( ToProtoEnum<MODE, PadStackType>( m_mode ) );
|
||||
kiapi::board::PackLayerSet( *padstack.mutable_layers(), m_layerSet );
|
||||
padstack.mutable_angle()->set_value_degrees( m_orientation.AsDegrees() );
|
||||
@ -436,6 +432,12 @@ void PADSTACK::Serialize( google::protobuf::Any& aContainer ) const
|
||||
DrillProperties* drill = padstack.mutable_drill();
|
||||
drill->set_start_layer( ToProtoEnum<PCB_LAYER_ID, BoardLayer>( StartLayer() ) );
|
||||
drill->set_end_layer( ToProtoEnum<PCB_LAYER_ID, BoardLayer>( EndLayer() ) );
|
||||
drill->set_filled(
|
||||
packOptional( Drill().is_filled, VDFM_FILLED, VDFM_UNFILLED, VDFM_FROM_DESIGN_RULES ) );
|
||||
|
||||
drill->set_capped(
|
||||
packOptional( Drill().is_capped, VDCM_CAPPED, VDCM_UNCAPPED, VDCM_FROM_DESIGN_RULES ) );
|
||||
|
||||
kiapi::common::PackVector2( *drill->mutable_diameter(), Drill().size );
|
||||
|
||||
ForEachUniqueLayer( [&]( PCB_LAYER_ID aLayer )
|
||||
@ -463,34 +465,32 @@ void PADSTACK::Serialize( google::protobuf::Any& aContainer ) const
|
||||
padstack.set_unconnected_layer_removal(
|
||||
ToProtoEnum<UNCONNECTED_LAYER_MODE, UnconnectedLayerRemoval>( m_unconnectedLayerMode ) );
|
||||
|
||||
auto packOptional =
|
||||
[]<typename ProtoEnum>( const std::optional<bool>& aVal, ProtoEnum aTrueVal,
|
||||
ProtoEnum aFalseVal, ProtoEnum aNullVal ) -> ProtoEnum
|
||||
{
|
||||
if( aVal.has_value() )
|
||||
return *aVal ? aTrueVal : aFalseVal;
|
||||
|
||||
return aNullVal;
|
||||
};
|
||||
|
||||
PadStackOuterLayer* frontOuter = padstack.mutable_front_outer_layers();
|
||||
PadStackOuterLayer* backOuter = padstack.mutable_back_outer_layers();
|
||||
|
||||
frontOuter->set_solder_mask_mode( packOptional( FrontOuterLayers().has_solder_mask,
|
||||
SMM_MASKED, SMM_UNMASKED,
|
||||
SMM_FROM_DESIGN_RULES ) );
|
||||
frontOuter->set_solder_mask_mode( packOptional( FrontOuterLayers().has_solder_mask, SMM_MASKED,
|
||||
SMM_UNMASKED, SMM_FROM_DESIGN_RULES ) );
|
||||
|
||||
backOuter->set_solder_mask_mode( packOptional( BackOuterLayers().has_solder_mask,
|
||||
SMM_MASKED, SMM_UNMASKED,
|
||||
SMM_FROM_DESIGN_RULES ) );
|
||||
backOuter->set_solder_mask_mode( packOptional( BackOuterLayers().has_solder_mask, SMM_MASKED,
|
||||
SMM_UNMASKED, SMM_FROM_DESIGN_RULES ) );
|
||||
|
||||
frontOuter->set_solder_paste_mode( packOptional( FrontOuterLayers().has_solder_paste,
|
||||
SPM_PASTE, SPM_NO_PASTE,
|
||||
SPM_FROM_DESIGN_RULES ) );
|
||||
frontOuter->set_plugging_mode( packOptional( FrontOuterLayers().has_plugging, VPM_PLUGGED,
|
||||
VPM_UNPLUGGED, VPM_FROM_DESIGN_RULES ) );
|
||||
|
||||
backOuter->set_solder_paste_mode( packOptional( BackOuterLayers().has_solder_paste,
|
||||
SPM_PASTE, SPM_NO_PASTE,
|
||||
SPM_FROM_DESIGN_RULES ) );
|
||||
backOuter->set_plugging_mode( packOptional( BackOuterLayers().has_plugging, VPM_PLUGGED,
|
||||
VPM_UNPLUGGED, VPM_FROM_DESIGN_RULES ) );
|
||||
|
||||
frontOuter->set_covering_mode( packOptional( FrontOuterLayers().has_covering, VCM_COVERED,
|
||||
VCM_UNCOVERED, VCM_FROM_DESIGN_RULES ) );
|
||||
|
||||
backOuter->set_covering_mode( packOptional( BackOuterLayers().has_covering, VCM_COVERED,
|
||||
VCM_UNCOVERED, VCM_FROM_DESIGN_RULES ) );
|
||||
|
||||
frontOuter->set_solder_paste_mode( packOptional( FrontOuterLayers().has_solder_paste, SPM_PASTE,
|
||||
SPM_NO_PASTE, SPM_FROM_DESIGN_RULES ) );
|
||||
|
||||
backOuter->set_solder_paste_mode( packOptional( BackOuterLayers().has_solder_paste, SPM_PASTE,
|
||||
SPM_NO_PASTE, SPM_FROM_DESIGN_RULES ) );
|
||||
|
||||
if( FrontOuterLayers().solder_mask_margin.has_value() )
|
||||
{
|
||||
@ -1346,5 +1346,37 @@ std::optional<bool> PADSTACK::IsTented( PCB_LAYER_ID aSide ) const
|
||||
wxCHECK_MSG( false, std::nullopt, "IsTented expects a front or back layer" );
|
||||
}
|
||||
|
||||
std::optional<bool> PADSTACK::IsCovered( PCB_LAYER_ID aSide ) const
|
||||
{
|
||||
if( IsFrontLayer( aSide ) )
|
||||
return m_frontMaskProps.has_covering;
|
||||
|
||||
if( IsBackLayer( aSide ) )
|
||||
return m_backMaskProps.has_covering;
|
||||
|
||||
wxCHECK_MSG( false, std::nullopt, "IsCovered expects a front or back layer" );
|
||||
}
|
||||
|
||||
std::optional<bool> PADSTACK::IsPlugged( PCB_LAYER_ID aSide ) const
|
||||
{
|
||||
if( IsFrontLayer( aSide ) )
|
||||
return m_frontMaskProps.has_plugging;
|
||||
|
||||
if( IsBackLayer( aSide ) )
|
||||
return m_backMaskProps.has_plugging;
|
||||
|
||||
wxCHECK_MSG( false, std::nullopt, "IsPlugged expects a front or back layer" );
|
||||
}
|
||||
|
||||
std::optional<bool> PADSTACK::IsCapped() const
|
||||
{
|
||||
return m_drill.is_capped;
|
||||
}
|
||||
|
||||
std::optional<bool> PADSTACK::IsFilled() const
|
||||
{
|
||||
return m_drill.is_filled;
|
||||
}
|
||||
|
||||
|
||||
IMPLEMENT_ENUM_TO_WXANY( PADSTACK::UNCONNECTED_LAYER_MODE )
|
||||
|
@ -228,8 +228,11 @@ public:
|
||||
std::optional<int> solder_mask_margin;
|
||||
std::optional<int> solder_paste_margin;
|
||||
std::optional<double> solder_paste_margin_ratio;
|
||||
|
||||
std::optional<bool> has_solder_mask; ///< True if this outer layer has mask (is not tented)
|
||||
std::optional<bool> has_solder_paste; ///< True if this outer layer has solder paste
|
||||
std::optional<bool> has_covering; ///< True if the pad on this side should have covering
|
||||
std::optional<bool> has_plugging; ///< True if the drill hole should be plugged on this side
|
||||
|
||||
bool operator==( const MASK_LAYER_PROPS& aOther ) const;
|
||||
};
|
||||
@ -242,6 +245,9 @@ public:
|
||||
PCB_LAYER_ID start;
|
||||
PCB_LAYER_ID end;
|
||||
|
||||
std::optional<bool> is_filled; ///< True if the drill hole should be filled completely
|
||||
std::optional<bool> is_capped; ///< True if the drill hole should be capped
|
||||
|
||||
bool operator==( const DRILL_PROPS& aOther ) const;
|
||||
};
|
||||
|
||||
@ -323,6 +329,14 @@ public:
|
||||
*/
|
||||
std::optional<bool> IsTented( PCB_LAYER_ID aSide ) const;
|
||||
|
||||
std::optional<bool> IsCovered( PCB_LAYER_ID aSide ) const;
|
||||
|
||||
std::optional<bool> IsPlugged( PCB_LAYER_ID aSide ) const;
|
||||
|
||||
std::optional<bool> IsCapped() const;
|
||||
|
||||
std::optional<bool> IsFilled() const;
|
||||
|
||||
CUSTOM_SHAPE_ZONE_MODE CustomShapeInZoneMode() const { return m_customShapeInZoneMode; }
|
||||
void SetCustomShapeInZoneMode( CUSTOM_SHAPE_ZONE_MODE aM ) { m_customShapeInZoneMode = aM; }
|
||||
|
||||
|
@ -55,6 +55,15 @@ enum class cadPinType
|
||||
SURFACE
|
||||
};
|
||||
|
||||
enum class auxLayerType
|
||||
{
|
||||
COVERING,
|
||||
PLUGGING,
|
||||
TENTING,
|
||||
FILLING,
|
||||
CAPPING,
|
||||
};
|
||||
|
||||
enum class certificationCategoryType
|
||||
{
|
||||
ASSEMBLYDRAWING,
|
||||
|
@ -1364,7 +1364,8 @@ wxXmlNode* PCB_IO_IPC2581::generateEcadSection()
|
||||
|
||||
wxXmlNode* cadDataNode = appendNode( ecadNode, "CadData" );
|
||||
generateCadLayers( cadDataNode );
|
||||
generateDrillLayers( cadDataNode);
|
||||
generateDrillLayers( cadDataNode );
|
||||
generateAuxilliaryLayers( cadDataNode );
|
||||
generateStackup( cadDataNode );
|
||||
generateStepSection( cadDataNode );
|
||||
|
||||
@ -1756,6 +1757,136 @@ void PCB_IO_IPC2581::generateDrillLayers( wxXmlNode* aCadLayerNode )
|
||||
}
|
||||
|
||||
|
||||
void PCB_IO_IPC2581::generateAuxilliaryLayers( wxXmlNode* aCadLayerNode )
|
||||
{
|
||||
for( BOARD_ITEM* item : m_board->Tracks() )
|
||||
{
|
||||
if( item->Type() != PCB_VIA_T )
|
||||
continue;
|
||||
|
||||
PCB_VIA* via = static_cast<PCB_VIA*>( item );
|
||||
|
||||
std::vector<std::tuple<auxLayerType, PCB_LAYER_ID, PCB_LAYER_ID>> new_layers;
|
||||
|
||||
if( via->Padstack().IsFilled().value_or( false ) )
|
||||
{
|
||||
new_layers.emplace_back( auxLayerType::FILLING, via->TopLayer(), via->BottomLayer() );
|
||||
}
|
||||
|
||||
if( via->Padstack().IsCapped().value_or( false ) )
|
||||
{
|
||||
new_layers.emplace_back( auxLayerType::CAPPING, via->TopLayer(), via->BottomLayer() );
|
||||
}
|
||||
|
||||
for( PCB_LAYER_ID layer : { via->TopLayer(), via->BottomLayer() } )
|
||||
{
|
||||
if( via->Padstack().IsPlugged( layer ).value_or( false ) )
|
||||
{
|
||||
new_layers.emplace_back( auxLayerType::PLUGGING, layer, UNDEFINED_LAYER );
|
||||
}
|
||||
|
||||
if( via->Padstack().IsCovered( layer ).value_or( false ) )
|
||||
{
|
||||
new_layers.emplace_back( auxLayerType::COVERING, layer, UNDEFINED_LAYER );
|
||||
}
|
||||
|
||||
if( via->Padstack().IsTented( layer ).value_or( false ) )
|
||||
{
|
||||
new_layers.emplace_back( auxLayerType::TENTING, layer, UNDEFINED_LAYER );
|
||||
}
|
||||
}
|
||||
|
||||
for( auto& tuple : new_layers )
|
||||
{
|
||||
m_auxilliary_Layers[tuple].push_back( via );
|
||||
}
|
||||
}
|
||||
|
||||
for( const auto& [layers, vec] : m_auxilliary_Layers )
|
||||
{
|
||||
bool add_node = true;
|
||||
|
||||
wxString name;
|
||||
wxString layerFunction;
|
||||
|
||||
// clang-format off: suggestion is inconsitent
|
||||
switch( std::get<0>(layers) )
|
||||
{
|
||||
case auxLayerType::COVERING:
|
||||
name = "COVERING";
|
||||
layerFunction = "COATINGNONCOND";
|
||||
break;
|
||||
case auxLayerType::PLUGGING:
|
||||
name = "PLUGGING";
|
||||
layerFunction = "HOLEFILL";
|
||||
break;
|
||||
case auxLayerType::TENTING:
|
||||
name = "TENTING";
|
||||
layerFunction = "COATINGNONCOND";
|
||||
break;
|
||||
case auxLayerType::FILLING:
|
||||
name = "FILLING";
|
||||
layerFunction = "HOLEFILL";
|
||||
break;
|
||||
case auxLayerType::CAPPING:
|
||||
name = "CAPPING";
|
||||
layerFunction = "COATINGCOND";
|
||||
break;
|
||||
default:
|
||||
add_node = false;
|
||||
break;
|
||||
}
|
||||
// clang-format on: suggestion is inconsitent
|
||||
|
||||
if( add_node && !vec.empty() )
|
||||
{
|
||||
wxXmlNode* node = appendNode( aCadLayerNode, "LAYER" );
|
||||
addAttribute( node, "layerFunction", layerFunction );
|
||||
addAttribute( node, "polarity", "POSITIVE" );
|
||||
|
||||
if( std::get<2>( layers ) == UNDEFINED_LAYER )
|
||||
{
|
||||
addAttribute( node, "name", genLayerString( std::get<1>( layers ), name ) );
|
||||
addAttribute( node, "side",
|
||||
IsFrontLayer( std::get<1>( layers ) ) ? "TOP" : "BOTTOM" );
|
||||
}
|
||||
else
|
||||
{
|
||||
addAttribute(
|
||||
node, "name",
|
||||
genLayersString( std::get<1>( layers ), std::get<2>( layers ), name ) );
|
||||
|
||||
const bool first_external =
|
||||
std::get<1>( layers ) == F_Cu || std::get<1>( layers ) == B_Cu;
|
||||
const bool second_external =
|
||||
std::get<2>( layers ) == F_Cu || std::get<2>( layers ) == B_Cu;
|
||||
|
||||
if( first_external )
|
||||
{
|
||||
if( second_external )
|
||||
addAttribute( node, "side", "ALL" );
|
||||
else
|
||||
addAttribute( node, "side", "FRONT" );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( second_external )
|
||||
addAttribute( node, "side", "BACK" );
|
||||
else
|
||||
addAttribute( node, "side", "INTERNAL" );
|
||||
}
|
||||
|
||||
wxXmlNode* spanNode = appendNode( node, "SPAN" );
|
||||
addAttribute( spanNode, "fromLayer",
|
||||
genLayerString( std::get<1>( layers ), "LAYER" ) );
|
||||
addAttribute( spanNode, "toLayer",
|
||||
genLayerString( std::get<2>( layers ), "LAYER" ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PCB_IO_IPC2581::generateStepSection( wxXmlNode* aCadNode )
|
||||
{
|
||||
wxXmlNode* stepNode = appendNode( aCadNode, "Step" );
|
||||
@ -1780,6 +1911,7 @@ void PCB_IO_IPC2581::generateStepSection( wxXmlNode* aCadNode )
|
||||
|
||||
generateLayerFeatures( stepNode );
|
||||
generateLayerSetDrill( stepNode );
|
||||
generateLayerSetAuxilliary( stepNode );
|
||||
}
|
||||
|
||||
|
||||
@ -1930,21 +2062,51 @@ void PCB_IO_IPC2581::addPadStack( wxXmlNode* aContentNode, const PCB_VIA* aVia )
|
||||
|
||||
LSEQ layer_seq = aVia->GetLayerSet().Seq();
|
||||
|
||||
auto addPadShape{ [&]( PCB_LAYER_ID layer, const PCB_VIA* aVia, const wxString& name,
|
||||
bool drill ) -> void
|
||||
{
|
||||
PCB_SHAPE shape( nullptr, SHAPE_T::CIRCLE );
|
||||
|
||||
if( drill )
|
||||
shape.SetEnd( { KiROUND( aVia->GetDrillValue() / 2.0 ), 0 } );
|
||||
else
|
||||
shape.SetEnd( { KiROUND( aVia->GetWidth( layer ) / 2.0 ), 0 } );
|
||||
|
||||
wxXmlNode* padStackPadDefNode =
|
||||
appendNode( padStackDefNode, "PadstackPadDef" );
|
||||
addAttribute( padStackPadDefNode, "layerRef", name );
|
||||
addAttribute( padStackPadDefNode, "padUse", "REGULAR" );
|
||||
|
||||
addLocationNode( padStackPadDefNode, 0.0, 0.0 );
|
||||
addShape( padStackPadDefNode, shape );
|
||||
} };
|
||||
|
||||
for( PCB_LAYER_ID layer : layer_seq )
|
||||
{
|
||||
if( !aVia->FlashLayer( layer ) || !m_board->IsLayerEnabled( layer ) )
|
||||
continue;
|
||||
|
||||
PCB_SHAPE shape( nullptr, SHAPE_T::CIRCLE );
|
||||
addPadShape( layer, aVia, m_layer_name_map[layer], false );
|
||||
}
|
||||
|
||||
shape.SetEnd( { KiROUND( aVia->GetWidth( layer ) / 2.0 ), 0 } );
|
||||
if( aVia->Padstack().IsFilled().value_or( false ) )
|
||||
addPadShape( UNDEFINED_LAYER, aVia,
|
||||
genLayersString( aVia->TopLayer(), aVia->BottomLayer(), "FILLING" ), true );
|
||||
|
||||
wxXmlNode* padStackPadDefNode = appendNode( padStackDefNode, "PadstackPadDef" );
|
||||
addAttribute( padStackPadDefNode, "layerRef", m_layer_name_map[layer] );
|
||||
addAttribute( padStackPadDefNode, "padUse", "REGULAR" );
|
||||
if( aVia->Padstack().IsCapped().value_or( false ) )
|
||||
addPadShape( UNDEFINED_LAYER, aVia,
|
||||
genLayersString( aVia->TopLayer(), aVia->BottomLayer(), "CAPPING" ), true );
|
||||
|
||||
addLocationNode( padStackPadDefNode, 0.0, 0.0 );
|
||||
addShape( padStackPadDefNode, shape );
|
||||
for( PCB_LAYER_ID layer : { aVia->TopLayer(), aVia->BottomLayer() } )
|
||||
{
|
||||
if( aVia->Padstack().IsPlugged( layer ).value_or( false ) )
|
||||
addPadShape( layer, aVia, genLayerString( layer, "PLUGGING" ), true );
|
||||
|
||||
if( aVia->Padstack().IsCovered( layer ).value_or( false ) )
|
||||
addPadShape( layer, aVia, genLayerString( layer, "COVERING" ), false );
|
||||
|
||||
if( aVia->Padstack().IsTented( layer ).value_or( false ) )
|
||||
addPadShape( layer, aVia, genLayerString( layer, "TENTING" ), false );
|
||||
}
|
||||
}
|
||||
|
||||
@ -3002,6 +3164,78 @@ void PCB_IO_IPC2581::generateLayerSetNet( wxXmlNode* aLayerNode, PCB_LAYER_ID aL
|
||||
}
|
||||
}
|
||||
|
||||
void PCB_IO_IPC2581::generateLayerSetAuxilliary( wxXmlNode* aStepNode )
|
||||
{
|
||||
int hole_count = 1;
|
||||
|
||||
for( const auto& [layers, vec] : m_auxilliary_Layers )
|
||||
{
|
||||
hole_count = 1;
|
||||
bool add_node = true;
|
||||
|
||||
wxString name;
|
||||
bool hole = false;
|
||||
|
||||
// clang-format off: suggestion is inconsitent
|
||||
switch( std::get<0>(layers) )
|
||||
{
|
||||
case auxLayerType::COVERING:
|
||||
name = "COVERING";
|
||||
break;
|
||||
case auxLayerType::PLUGGING:
|
||||
name = "PLUGGING";
|
||||
hole = true;
|
||||
break;
|
||||
case auxLayerType::TENTING:
|
||||
name = "TENTING";
|
||||
break;
|
||||
case auxLayerType::FILLING:
|
||||
name = "FILLING";
|
||||
hole = true;
|
||||
break;
|
||||
case auxLayerType::CAPPING:
|
||||
name = "CAPPING";
|
||||
hole = true;
|
||||
break;
|
||||
default:
|
||||
add_node = false;
|
||||
break;
|
||||
}
|
||||
// clang-format on: suggestion is inconsitent
|
||||
|
||||
if( !add_node )
|
||||
continue;
|
||||
|
||||
wxXmlNode* layerNode = appendNode( aStepNode, "LayerFeature" );
|
||||
if( std::get<2>( layers ) == UNDEFINED_LAYER )
|
||||
layerNode->AddAttribute( "layerRef", genLayerString( std::get<1>( layers ), name ) );
|
||||
else
|
||||
layerNode->AddAttribute( "layerRef", genLayersString( std::get<1>( layers ),
|
||||
std::get<2>( layers ), name ) );
|
||||
|
||||
for( BOARD_ITEM* item : vec )
|
||||
{
|
||||
if( item->Type() == PCB_VIA_T )
|
||||
{
|
||||
PCB_VIA* via = static_cast<PCB_VIA*>( item );
|
||||
|
||||
PCB_SHAPE shape( nullptr, SHAPE_T::CIRCLE );
|
||||
|
||||
if( hole )
|
||||
shape.SetEnd( { KiROUND( via->GetDrillValue() / 2.0 ), 0 } );
|
||||
else
|
||||
shape.SetEnd( { KiROUND( via->GetWidth( std::get<1>( layers ) ) / 2.0 ), 0 } );
|
||||
|
||||
wxXmlNode* padNode = appendNode( layerNode, "Pad" );
|
||||
addPadStack( padNode, via );
|
||||
|
||||
addLocationNode( padNode, 0.0, 0.0 );
|
||||
addShape( padNode, shape );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
wxXmlNode* PCB_IO_IPC2581::generateAvlSection()
|
||||
{
|
||||
|
@ -24,6 +24,8 @@
|
||||
#include <pcb_io/pcb_io_mgr.h>
|
||||
#include <pcb_io/common/plugin_common_layer_mapping.h>
|
||||
|
||||
#include "ipc2581_types.h"
|
||||
|
||||
#include <eda_shape.h>
|
||||
#include <layer_ids.h> // PCB_LAYER_ID
|
||||
#include <font/font.h>
|
||||
@ -172,6 +174,8 @@ private:
|
||||
|
||||
void generateDrillLayers( wxXmlNode* aCadLayerNode );
|
||||
|
||||
void generateAuxilliaryLayers( wxXmlNode* aCadLayerNode );
|
||||
|
||||
void generateStepSection( wxXmlNode* aCadNode );
|
||||
|
||||
void generateProfile( wxXmlNode* aStepNode );
|
||||
@ -186,6 +190,8 @@ private:
|
||||
|
||||
void generateLayerSetNet( wxXmlNode* aLayerNode, PCB_LAYER_ID aLayer, std::vector<BOARD_ITEM*>& aItems );
|
||||
|
||||
void generateLayerSetAuxilliary( wxXmlNode* aStepNode );
|
||||
|
||||
wxXmlNode* generateContentStackup( wxXmlNode* aContentNode );
|
||||
|
||||
void generateComponents( wxXmlNode* aStepNode );
|
||||
@ -326,6 +332,9 @@ private:
|
||||
std::map<std::pair<PCB_LAYER_ID, PCB_LAYER_ID>, std::vector<PAD*>>
|
||||
m_slot_holes; //<! Storage vector of slotted holes that need to be output as cutouts
|
||||
|
||||
std::map<std::tuple<auxLayerType, PCB_LAYER_ID, PCB_LAYER_ID>, std::vector<BOARD_ITEM*>>
|
||||
m_auxilliary_Layers;
|
||||
|
||||
PROGRESS_REPORTER* m_progress_reporter;
|
||||
|
||||
std::set<wxUniChar> m_acceptable_chars; //<! IPC2581B and C have differing sets of allowed characters in names
|
||||
|
@ -587,16 +587,24 @@ void PCB_IO_KICAD_SEXPR::formatSetup( const BOARD* aBoard ) const
|
||||
KICAD_FORMAT::FormatBool( m_out, "allow_soldermask_bridges_in_footprints",
|
||||
dsnSettings.m_AllowSoldermaskBridgesInFPs );
|
||||
|
||||
if( dsnSettings.m_TentViasFront || dsnSettings.m_TentViasBack )
|
||||
{
|
||||
m_out->Print( "(tenting %s %s)",
|
||||
dsnSettings.m_TentViasFront ? "front" : "",
|
||||
dsnSettings.m_TentViasBack ? "back" : "" );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_out->Print( "(tenting none)" );
|
||||
}
|
||||
m_out->Print( 0, " (tenting " );
|
||||
KICAD_FORMAT::FormatBool( m_out, "front", dsnSettings.m_TentViasFront );
|
||||
KICAD_FORMAT::FormatBool( m_out, "back", dsnSettings.m_TentViasBack );
|
||||
m_out->Print( 0, ")" );
|
||||
|
||||
m_out->Print( 0, " (covering " );
|
||||
KICAD_FORMAT::FormatBool( m_out, "front", dsnSettings.m_CoverViasFront );
|
||||
KICAD_FORMAT::FormatBool( m_out, "back", dsnSettings.m_CoverViasBack );
|
||||
m_out->Print( 0, ")" );
|
||||
|
||||
m_out->Print( 0, " (plugging " );
|
||||
KICAD_FORMAT::FormatBool( m_out, "front", dsnSettings.m_PlugViasFront );
|
||||
KICAD_FORMAT::FormatBool( m_out, "back", dsnSettings.m_PlugViasBack );
|
||||
m_out->Print( 0, ")" );
|
||||
|
||||
KICAD_FORMAT::FormatBool( m_out, "capping", dsnSettings.m_CapVias );
|
||||
|
||||
KICAD_FORMAT::FormatBool( m_out, "filling", dsnSettings.m_FillVias );
|
||||
|
||||
VECTOR2I origin = dsnSettings.GetAuxOrigin();
|
||||
|
||||
@ -1836,7 +1844,12 @@ void PCB_IO_KICAD_SEXPR::format( const PAD* aPad ) const
|
||||
if( !isDefaultTeardropParameters( aPad->GetTeardropParams() ) )
|
||||
formatTeardropParameters( aPad->GetTeardropParams() );
|
||||
|
||||
formatTenting( aPad->Padstack() );
|
||||
m_out->Print( 0, " (tenting " );
|
||||
KICAD_FORMAT::FormatOptBool( m_out, "front",
|
||||
aPad->Padstack().FrontOuterLayers().has_solder_mask );
|
||||
KICAD_FORMAT::FormatOptBool( m_out, "back",
|
||||
aPad->Padstack().BackOuterLayers().has_solder_mask );
|
||||
m_out->Print( 0, ")" );
|
||||
|
||||
KICAD_FORMAT::FormatUuid( m_out, aPad->m_Uuid );
|
||||
|
||||
@ -1954,27 +1967,6 @@ void PCB_IO_KICAD_SEXPR::format( const PAD* aPad ) const
|
||||
}
|
||||
|
||||
|
||||
void PCB_IO_KICAD_SEXPR::formatTenting( const PADSTACK& aPadstack ) const
|
||||
{
|
||||
std::optional<bool> front = aPadstack.FrontOuterLayers().has_solder_mask;
|
||||
std::optional<bool> back = aPadstack.BackOuterLayers().has_solder_mask;
|
||||
|
||||
if( front.has_value() || back.has_value() )
|
||||
{
|
||||
if( front.value_or( false ) || back.value_or( false ) )
|
||||
{
|
||||
m_out->Print( "(tenting %s %s)",
|
||||
front.value_or( false ) ? "front" : "",
|
||||
back.value_or( false ) ? "back" : "" );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_out->Print( "(tenting none)" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PCB_IO_KICAD_SEXPR::format( const PCB_TEXT* aText ) const
|
||||
{
|
||||
FOOTPRINT* parentFP = aText->GetParentFootprint();
|
||||
@ -2379,7 +2371,24 @@ void PCB_IO_KICAD_SEXPR::format( const PCB_TRACK* aTrack ) const
|
||||
|
||||
const PADSTACK& padstack = via->Padstack();
|
||||
|
||||
formatTenting( padstack );
|
||||
m_out->Print( 0, " (tenting " );
|
||||
KICAD_FORMAT::FormatOptBool( m_out, "front", padstack.FrontOuterLayers().has_solder_mask );
|
||||
KICAD_FORMAT::FormatOptBool( m_out, "back", padstack.BackOuterLayers().has_solder_mask );
|
||||
m_out->Print( 0, ")" );
|
||||
|
||||
KICAD_FORMAT::FormatOptBool( m_out, "capping", padstack.Drill().is_capped );
|
||||
|
||||
m_out->Print( 0, " (covering " );
|
||||
KICAD_FORMAT::FormatOptBool( m_out, "front", padstack.FrontOuterLayers().has_covering );
|
||||
KICAD_FORMAT::FormatOptBool( m_out, "back", padstack.BackOuterLayers().has_covering );
|
||||
m_out->Print( 0, ")" );
|
||||
|
||||
m_out->Print( 0, " (plugging " );
|
||||
KICAD_FORMAT::FormatOptBool( m_out, "front", padstack.FrontOuterLayers().has_plugging );
|
||||
KICAD_FORMAT::FormatOptBool( m_out, "back", padstack.BackOuterLayers().has_plugging );
|
||||
m_out->Print( 0, ")" );
|
||||
|
||||
KICAD_FORMAT::FormatOptBool( m_out, "filling", padstack.Drill().is_filled );
|
||||
|
||||
if( padstack.Mode() != PADSTACK::MODE::NORMAL )
|
||||
{
|
||||
|
@ -31,6 +31,7 @@
|
||||
|
||||
#include <richio.h>
|
||||
#include <string>
|
||||
#include <optional>
|
||||
#include <layer_ids.h>
|
||||
#include <lset.h>
|
||||
#include <boost/ptr_container/ptr_map.hpp>
|
||||
@ -175,7 +176,8 @@ class PCB_IO_KICAD_SEXPR; // forward decl
|
||||
//#define SEXPR_BOARD_FILE_VERSION 20241229 // Expand User layers to arbitrary count
|
||||
//----------------- Start of 10.0 development -----------------
|
||||
//#define SEXPR_BOARD_FILE_VERSION 20250210 // Knockout for textboxes
|
||||
#define SEXPR_BOARD_FILE_VERSION 20250222 // Hatching for PCB shapes
|
||||
//#define SEXPR_BOARD_FILE_VERSION 20250222 // Hatching for PCB shapes
|
||||
#define SEXPR_BOARD_FILE_VERSION 20250228 // ipc-4761 via protection features
|
||||
|
||||
|
||||
#define BOARD_FILE_HOST_VERSION 20200825 ///< Earlier files than this include the host tag
|
||||
@ -460,8 +462,6 @@ private:
|
||||
|
||||
void formatLayers( LSET aLayerMask, bool aEnumerateLayers ) const;
|
||||
|
||||
void formatTenting( const PADSTACK& aPadstack ) const;
|
||||
|
||||
friend class FP_CACHE;
|
||||
|
||||
protected:
|
||||
|
@ -235,6 +235,23 @@ bool PCB_IO_KICAD_SEXPR_PARSER::parseBool()
|
||||
}
|
||||
|
||||
|
||||
std::optional<bool> PCB_IO_KICAD_SEXPR_PARSER::parseOptBool()
|
||||
{
|
||||
T token = NextTok();
|
||||
|
||||
if( token == T_yes )
|
||||
return true;
|
||||
else if( token == T_no )
|
||||
return false;
|
||||
else if( token == T_none )
|
||||
return std::nullopt;
|
||||
else
|
||||
Expecting( "yes, no or none" );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* e.g. "hide", "hide)", "(hide yes)"
|
||||
*/
|
||||
@ -2423,17 +2440,39 @@ void PCB_IO_KICAD_SEXPR_PARSER::parseSetup()
|
||||
|
||||
case T_tenting:
|
||||
{
|
||||
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
|
||||
{
|
||||
if( token == T_front )
|
||||
bds.m_TentViasFront = true;
|
||||
else if( token == T_back )
|
||||
bds.m_TentViasBack = true;
|
||||
else if( token == T_none )
|
||||
bds.m_TentViasFront = bds.m_TentViasBack = false;
|
||||
else
|
||||
Expecting( "front, back, or none" );
|
||||
}
|
||||
auto [front, back] = parseFrontBackOptBool( true );
|
||||
bds.m_TentViasFront = front.value_or( false );
|
||||
bds.m_TentViasBack = back.value_or( false );
|
||||
break;
|
||||
}
|
||||
|
||||
case T_covering:
|
||||
{
|
||||
auto [front, back] = parseFrontBackOptBool();
|
||||
bds.m_CoverViasFront = front.value_or( false );
|
||||
bds.m_CoverViasBack = back.value_or( false );
|
||||
break;
|
||||
}
|
||||
|
||||
case T_plugging:
|
||||
{
|
||||
auto [front, back] = parseFrontBackOptBool();
|
||||
bds.m_PlugViasFront = front.value_or( false );
|
||||
bds.m_PlugViasBack = back.value_or( false );
|
||||
break;
|
||||
}
|
||||
|
||||
case T_capping:
|
||||
{
|
||||
bds.m_CapVias = parseBool();
|
||||
NeedRIGHT();
|
||||
break;
|
||||
}
|
||||
|
||||
case T_filling:
|
||||
{
|
||||
bds.m_FillVias = parseBool();
|
||||
NeedRIGHT();
|
||||
break;
|
||||
}
|
||||
|
||||
@ -5437,8 +5476,12 @@ PAD* PCB_IO_KICAD_SEXPR_PARSER::parsePAD( FOOTPRINT* aParent )
|
||||
}
|
||||
|
||||
case T_tenting:
|
||||
parseTenting( pad->Padstack() );
|
||||
{
|
||||
auto [front, back] = parseFrontBackOptBool( true );
|
||||
pad->Padstack().FrontOuterLayers().has_solder_mask = front;
|
||||
pad->Padstack().BackOuterLayers().has_solder_mask = back;
|
||||
break;
|
||||
}
|
||||
|
||||
case T_zone_layer_connections:
|
||||
{
|
||||
@ -5836,8 +5879,12 @@ void PCB_IO_KICAD_SEXPR_PARSER::parsePadstack( PAD* aPad )
|
||||
break;
|
||||
|
||||
case T_tenting:
|
||||
parseTenting( padstack );
|
||||
{
|
||||
auto [front, back] = parseFrontBackOptBool( true );
|
||||
padstack.FrontOuterLayers().has_solder_mask = front;
|
||||
padstack.BackOuterLayers().has_solder_mask = back;
|
||||
break;
|
||||
}
|
||||
|
||||
// TODO: refactor parsePAD_options to work on padstacks too
|
||||
case T_options:
|
||||
@ -6488,8 +6535,38 @@ PCB_VIA* PCB_IO_KICAD_SEXPR_PARSER::parsePCB_VIA()
|
||||
break;
|
||||
|
||||
case T_tenting:
|
||||
parseTenting( via->Padstack() );
|
||||
{
|
||||
auto [front, back] = parseFrontBackOptBool( true );
|
||||
via->Padstack().FrontOuterLayers().has_solder_mask = front;
|
||||
via->Padstack().BackOuterLayers().has_solder_mask = back;
|
||||
break;
|
||||
}
|
||||
case T_covering:
|
||||
{
|
||||
auto [front, back] = parseFrontBackOptBool();
|
||||
via->Padstack().FrontOuterLayers().has_covering = front;
|
||||
via->Padstack().BackOuterLayers().has_covering = back;
|
||||
break;
|
||||
}
|
||||
case T_plugging:
|
||||
{
|
||||
auto [front, back] = parseFrontBackOptBool();
|
||||
via->Padstack().FrontOuterLayers().has_plugging = front;
|
||||
via->Padstack().BackOuterLayers().has_plugging = back;
|
||||
break;
|
||||
}
|
||||
case T_filling:
|
||||
{
|
||||
via->Padstack().Drill().is_filled = parseOptBool();
|
||||
NeedRIGHT();
|
||||
break;
|
||||
}
|
||||
case T_capping:
|
||||
{
|
||||
via->Padstack().Drill().is_capped = parseOptBool();
|
||||
NeedRIGHT();
|
||||
break;
|
||||
}
|
||||
|
||||
case T_tstamp:
|
||||
case T_uuid:
|
||||
@ -6522,24 +6599,66 @@ PCB_VIA* PCB_IO_KICAD_SEXPR_PARSER::parsePCB_VIA()
|
||||
}
|
||||
|
||||
|
||||
void PCB_IO_KICAD_SEXPR_PARSER::parseTenting( PADSTACK& aPadstack )
|
||||
std::pair<std::optional<bool>, std::optional<bool>>
|
||||
PCB_IO_KICAD_SEXPR_PARSER::parseFrontBackOptBool( bool aLegacy )
|
||||
{
|
||||
bool front = false;
|
||||
bool back = false;
|
||||
T token = NextTok();
|
||||
|
||||
// If there is a tenting token, it means this individual pad/via has a tenting override
|
||||
for( T token = NextTok(); token != T_RIGHT; token = NextTok() )
|
||||
std::optional<bool> front{ std::nullopt };
|
||||
std::optional<bool> back{ std::nullopt };
|
||||
|
||||
if( token != T_LEFT && aLegacy )
|
||||
{
|
||||
if( token == T_front )
|
||||
front = true;
|
||||
else if( token == T_back )
|
||||
back = true;
|
||||
else if( token != T_none )
|
||||
Expecting( "front, back, or none" );
|
||||
// legacy format for tenting.
|
||||
if( token == T_front || token == T_back || token == T_none )
|
||||
{
|
||||
while( token != T_RIGHT )
|
||||
{
|
||||
if( token == T_front )
|
||||
{
|
||||
front = true;
|
||||
}
|
||||
else if( token == T_back )
|
||||
{
|
||||
back = true;
|
||||
}
|
||||
else if( token == T_none )
|
||||
{
|
||||
front.reset();
|
||||
back.reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
Expecting( "front, back or none" );
|
||||
}
|
||||
|
||||
token = NextTok();
|
||||
}
|
||||
|
||||
return { front, back };
|
||||
}
|
||||
}
|
||||
|
||||
aPadstack.FrontOuterLayers().has_solder_mask = front;
|
||||
aPadstack.BackOuterLayers().has_solder_mask = back;
|
||||
while( token != T_RIGHT )
|
||||
{
|
||||
if( token != T_LEFT )
|
||||
Expecting( "(" );
|
||||
|
||||
token = NextTok();
|
||||
|
||||
if( token == T_front )
|
||||
front = parseOptBool();
|
||||
else if( token == T_back )
|
||||
back = parseOptBool();
|
||||
else
|
||||
Expecting( "front or back" );
|
||||
|
||||
NeedRIGHT();
|
||||
|
||||
token = NextTok();
|
||||
}
|
||||
|
||||
return { front, back };
|
||||
}
|
||||
|
||||
|
||||
|
@ -330,8 +330,6 @@ private:
|
||||
*/
|
||||
void parseRenderCache( EDA_TEXT* text );
|
||||
|
||||
void parseTenting( PADSTACK& aPadstack );
|
||||
|
||||
FP_3DMODEL* parse3DModel();
|
||||
|
||||
/**
|
||||
@ -370,6 +368,8 @@ private:
|
||||
|
||||
bool parseBool();
|
||||
|
||||
std::optional<bool> parseOptBool();
|
||||
|
||||
/**
|
||||
* Parses a boolean flag inside a list that existed before boolean normalization.
|
||||
*
|
||||
@ -382,6 +382,9 @@ private:
|
||||
*/
|
||||
bool parseMaybeAbsentBool( bool aDefaultValue );
|
||||
|
||||
std::pair<std::optional<bool>, std::optional<bool>>
|
||||
parseFrontBackOptBool( bool aLegacy = false );
|
||||
|
||||
/*
|
||||
* @return if m_appendToExisting, returns new KIID(), otherwise returns CurStr() as KIID.
|
||||
*/
|
||||
|
@ -183,6 +183,8 @@ void ODB_MATRIX_ENTITY::InitMatrixLayerData()
|
||||
|
||||
AddDrillMatrixLayer();
|
||||
|
||||
AddAuxilliaryMatrixLayer();
|
||||
|
||||
AddCOMPMatrixLayer( B_Cu );
|
||||
}
|
||||
|
||||
@ -384,6 +386,121 @@ void ODB_MATRIX_ENTITY::AddCOMPMatrixLayer( PCB_LAYER_ID aCompSide )
|
||||
}
|
||||
}
|
||||
|
||||
void ODB_MATRIX_ENTITY::AddAuxilliaryMatrixLayer()
|
||||
{
|
||||
auto& auxilliary_layers = m_plugin->GetAuxilliaryLayerItemsMap();
|
||||
|
||||
for( BOARD_ITEM* item : m_board->Tracks() )
|
||||
{
|
||||
if( item->Type() == PCB_VIA_T )
|
||||
{
|
||||
PCB_VIA* via = static_cast<PCB_VIA*>( item );
|
||||
|
||||
if( via->Padstack().IsFilled().value_or( false ) )
|
||||
{
|
||||
auxilliary_layers[std::make_tuple( ODB_AUX_LAYER_TYPE::FILLING, via->TopLayer(),
|
||||
via->BottomLayer() )]
|
||||
.push_back( via );
|
||||
}
|
||||
|
||||
if( via->Padstack().IsCapped().value_or( false ) )
|
||||
{
|
||||
auxilliary_layers[std::make_tuple( ODB_AUX_LAYER_TYPE::CAPPING, via->TopLayer(),
|
||||
via->BottomLayer() )]
|
||||
.push_back( via );
|
||||
}
|
||||
|
||||
for( PCB_LAYER_ID layer : { via->TopLayer(), via->BottomLayer() } )
|
||||
{
|
||||
if( via->Padstack().IsPlugged( layer ).value_or( false ) )
|
||||
{
|
||||
auxilliary_layers[std::make_tuple( ODB_AUX_LAYER_TYPE::PLUGGING, layer,
|
||||
PCB_LAYER_ID::UNDEFINED_LAYER )]
|
||||
.push_back( via );
|
||||
}
|
||||
|
||||
if( via->Padstack().IsCovered( layer ).value_or( false ) )
|
||||
{
|
||||
auxilliary_layers[std::make_tuple( ODB_AUX_LAYER_TYPE::COVERING, layer,
|
||||
PCB_LAYER_ID::UNDEFINED_LAYER )]
|
||||
.push_back( via );
|
||||
}
|
||||
|
||||
if( via->Padstack().IsTented( layer ).value_or( false ) )
|
||||
{
|
||||
auxilliary_layers[std::make_tuple( ODB_AUX_LAYER_TYPE::TENTING, layer,
|
||||
PCB_LAYER_ID::UNDEFINED_LAYER )]
|
||||
.push_back( via );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto InitAuxMatrix =
|
||||
[&]( std::tuple<ODB_AUX_LAYER_TYPE, PCB_LAYER_ID, PCB_LAYER_ID> aLayerPair )
|
||||
{
|
||||
wxString featureName = "";
|
||||
switch( std::get<0>( aLayerPair ) )
|
||||
{
|
||||
case ODB_AUX_LAYER_TYPE::TENTING: featureName = "tenting"; break;
|
||||
case ODB_AUX_LAYER_TYPE::COVERING: featureName = "covering"; break;
|
||||
case ODB_AUX_LAYER_TYPE::PLUGGING: featureName = "plugging"; break;
|
||||
case ODB_AUX_LAYER_TYPE::FILLING: featureName = "filling"; break;
|
||||
case ODB_AUX_LAYER_TYPE::CAPPING: featureName = "capping"; break;
|
||||
default: return;
|
||||
}
|
||||
|
||||
wxString dLayerName;
|
||||
|
||||
if( std::get<2>( aLayerPair ) != PCB_LAYER_ID::UNDEFINED_LAYER )
|
||||
{
|
||||
dLayerName = wxString::Format( "%s_%s-%s", featureName,
|
||||
m_board->GetLayerName( std::get<1>( aLayerPair ) ),
|
||||
m_board->GetLayerName( std::get<2>( aLayerPair ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( IsFrontLayer( std::get<1>( aLayerPair ) ) )
|
||||
dLayerName = wxString::Format( "%s_front", featureName );
|
||||
else if( IsBackLayer( std::get<1>( aLayerPair ) ) )
|
||||
dLayerName = wxString::Format( "%s_back", featureName );
|
||||
else
|
||||
return;
|
||||
}
|
||||
MATRIX_LAYER matrix( m_row++, dLayerName );
|
||||
|
||||
matrix.m_type = ODB_TYPE::DOCUMENT;
|
||||
matrix.m_context = ODB_CONTEXT::BOARD;
|
||||
matrix.m_polarity = ODB_POLARITY::POSITIVE;
|
||||
|
||||
if( std::get<2>( aLayerPair ) != PCB_LAYER_ID::UNDEFINED_LAYER )
|
||||
{
|
||||
matrix.m_span.emplace( std::make_pair(
|
||||
ODB::GenLegalEntityName( m_board->GetLayerName( std::get<1>( aLayerPair ) ) ),
|
||||
ODB::GenLegalEntityName(
|
||||
m_board->GetLayerName( std::get<2>( aLayerPair ) ) ) ) );
|
||||
}
|
||||
|
||||
m_matrixLayers.push_back( matrix );
|
||||
|
||||
if( std::get<2>( aLayerPair ) != PCB_LAYER_ID::UNDEFINED_LAYER )
|
||||
{
|
||||
m_plugin->GetLayerNameList().emplace_back(
|
||||
std::make_pair( PCB_LAYER_ID::UNDEFINED_LAYER, matrix.m_layerName ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_plugin->GetLayerNameList().emplace_back(
|
||||
std::make_pair( std::get<1>( aLayerPair ), matrix.m_layerName ) );
|
||||
}
|
||||
};
|
||||
|
||||
for( const auto& [layer_pair, vec] : auxilliary_layers )
|
||||
{
|
||||
InitAuxMatrix( layer_pair );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ODB_MATRIX_ENTITY::GenerateFiles( ODB_TREE_WRITER& writer )
|
||||
{
|
||||
@ -457,6 +574,15 @@ void ODB_LAYER_ENTITY::InitEntityData()
|
||||
return;
|
||||
}
|
||||
|
||||
if( m_matrixLayerName.Contains( "filling" ) || m_matrixLayerName.Contains( "capping" )
|
||||
|| m_matrixLayerName.Contains( "covering" ) || m_matrixLayerName.Contains( "plugging" )
|
||||
|| m_matrixLayerName.Contains( "tenting" ) )
|
||||
{
|
||||
InitAuxilliaryData();
|
||||
InitFeatureData();
|
||||
return;
|
||||
}
|
||||
|
||||
if( m_layerID != PCB_LAYER_ID::UNDEFINED_LAYER )
|
||||
{
|
||||
InitFeatureData();
|
||||
@ -617,6 +743,64 @@ void ODB_LAYER_ENTITY::InitDrillData()
|
||||
}
|
||||
}
|
||||
|
||||
void ODB_LAYER_ENTITY::InitAuxilliaryData()
|
||||
{
|
||||
auto& auxilliary_layers = m_plugin->GetAuxilliaryLayerItemsMap();
|
||||
|
||||
if( !m_layerItems.empty() )
|
||||
{
|
||||
m_layerItems.clear();
|
||||
}
|
||||
|
||||
for( const auto& [layer_pair, vec] : auxilliary_layers )
|
||||
{
|
||||
wxString featureName = "";
|
||||
switch( std::get<0>( layer_pair ) )
|
||||
{
|
||||
case ODB_AUX_LAYER_TYPE::TENTING: featureName = "tenting"; break;
|
||||
case ODB_AUX_LAYER_TYPE::COVERING: featureName = "covering"; break;
|
||||
case ODB_AUX_LAYER_TYPE::PLUGGING: featureName = "plugging"; break;
|
||||
case ODB_AUX_LAYER_TYPE::FILLING: featureName = "filling"; break;
|
||||
case ODB_AUX_LAYER_TYPE::CAPPING: featureName = "capping"; break;
|
||||
default: return;
|
||||
}
|
||||
|
||||
wxString dLayerName;
|
||||
bool drill_value = false;
|
||||
|
||||
if( std::get<2>( layer_pair ) != PCB_LAYER_ID::UNDEFINED_LAYER )
|
||||
{
|
||||
drill_value = true;
|
||||
dLayerName = wxString::Format( "%s_%s-%s", featureName,
|
||||
m_board->GetLayerName( std::get<1>( layer_pair ) ),
|
||||
m_board->GetLayerName( std::get<2>( layer_pair ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( IsFrontLayer( std::get<1>( layer_pair ) ) )
|
||||
dLayerName = wxString::Format( "%s_front", featureName );
|
||||
else if( IsBackLayer( std::get<1>( layer_pair ) ) )
|
||||
dLayerName = wxString::Format( "%s_back", featureName );
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
if( ODB::GenLegalEntityName( dLayerName ) == m_matrixLayerName )
|
||||
{
|
||||
for( BOARD_ITEM* item : vec )
|
||||
{
|
||||
if( item->Type() == PCB_VIA_T )
|
||||
{
|
||||
PCB_VIA* via = static_cast<PCB_VIA*>( item );
|
||||
|
||||
m_layerItems[via->GetNetCode()].push_back( item );
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ODB_STEP_ENTITY::InitEntityData()
|
||||
{
|
||||
|
@ -102,6 +102,7 @@ public:
|
||||
void AddStep( const wxString& aStepName );
|
||||
void AddMatrixLayerField( MATRIX_LAYER& aMLayer, PCB_LAYER_ID aLayer );
|
||||
void AddDrillMatrixLayer();
|
||||
void AddAuxilliaryMatrixLayer();
|
||||
void AddCOMPMatrixLayer( PCB_LAYER_ID aCompSide );
|
||||
|
||||
private:
|
||||
@ -185,8 +186,10 @@ public:
|
||||
inline virtual std::string GetEntityName() override { return "layers"; }
|
||||
virtual void InitEntityData() override;
|
||||
void InitFeatureData();
|
||||
void InitDrillData();
|
||||
void InitAuxilliaryData();
|
||||
|
||||
ODB_COMPONENT& InitComponentData( const FOOTPRINT* aFp, const EDA_DATA::PACKAGE& aPkg );
|
||||
void InitDrillData();
|
||||
|
||||
void AddLayerFeatures();
|
||||
|
||||
|
@ -406,7 +406,37 @@ void FEATURES_MANAGER::InitFeatureList( PCB_LAYER_ID aLayer, std::vector<BOARD_I
|
||||
// add via
|
||||
PCB_VIA* via = static_cast<PCB_VIA*>( track );
|
||||
|
||||
bool hole = false;
|
||||
|
||||
if( aLayer != PCB_LAYER_ID::UNDEFINED_LAYER )
|
||||
{
|
||||
hole = m_layerName.Contains( "plugging" );
|
||||
}
|
||||
else
|
||||
{
|
||||
hole = m_layerName.Contains( "drill" ) || m_layerName.Contains( "filling" )
|
||||
|| m_layerName.Contains( "capping" );
|
||||
}
|
||||
|
||||
if( hole )
|
||||
{
|
||||
AddViaDrillHole( via, aLayer );
|
||||
subnet->AddFeatureID( EDA_DATA::FEATURE_ID::TYPE::HOLE, m_layerName,
|
||||
m_featuresList.size() - 1 );
|
||||
|
||||
// TODO: confirm TOOLING_HOLE
|
||||
// AddSystemAttribute( *m_featuresList.back(), ODB_ATTR::PAD_USAGE::TOOLING_HOLE );
|
||||
|
||||
if( !m_featuresList.empty() )
|
||||
{
|
||||
AddSystemAttribute( *m_featuresList.back(), ODB_ATTR::DRILL::VIA );
|
||||
AddSystemAttribute(
|
||||
*m_featuresList.back(),
|
||||
ODB_ATTR::GEOMETRY{ "VIA_RoundD"
|
||||
+ std::to_string( via->GetWidth( aLayer ) ) } );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// to draw via copper shape on copper layer
|
||||
AddVia( via, aLayer );
|
||||
@ -422,29 +452,6 @@ void FEATURES_MANAGER::InitFeatureList( PCB_LAYER_ID aLayer, std::vector<BOARD_I
|
||||
+ std::to_string( via->GetWidth( aLayer ) ) } );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// to draw via drill hole on drill layer
|
||||
|
||||
if( m_layerName.Contains( "drill" ) )
|
||||
{
|
||||
AddViaDrillHole( via, aLayer );
|
||||
subnet->AddFeatureID( EDA_DATA::FEATURE_ID::TYPE::HOLE, m_layerName,
|
||||
m_featuresList.size() - 1 );
|
||||
|
||||
// TODO: confirm TOOLING_HOLE
|
||||
// AddSystemAttribute( *m_featuresList.back(), ODB_ATTR::PAD_USAGE::TOOLING_HOLE );
|
||||
|
||||
if( !m_featuresList.empty() )
|
||||
{
|
||||
AddSystemAttribute( *m_featuresList.back(), ODB_ATTR::DRILL::VIA );
|
||||
AddSystemAttribute(
|
||||
*m_featuresList.back(),
|
||||
ODB_ATTR::GEOMETRY{ "VIA_RoundD"
|
||||
+ std::to_string( via->GetWidth( aLayer ) ) } );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -77,6 +77,8 @@ public:
|
||||
|
||||
void AddViaDrillHole( const PCB_VIA* aVia, PCB_LAYER_ID aLayer );
|
||||
|
||||
void AddViaProtection( const PCB_VIA* aVia, bool drill, PCB_LAYER_ID aLayer );
|
||||
|
||||
bool AddContour( const SHAPE_POLY_SET& aPolySet, int aOutline = 0,
|
||||
FILL_T aFillType = FILL_T::FILLED_SHAPE );
|
||||
|
||||
|
@ -69,6 +69,15 @@ enum class ODB_FID_TYPE
|
||||
HOLE
|
||||
};
|
||||
|
||||
enum class ODB_AUX_LAYER_TYPE
|
||||
{
|
||||
COVERING,
|
||||
PLUGGING,
|
||||
TENTING,
|
||||
FILLING,
|
||||
CAPPING,
|
||||
};
|
||||
|
||||
|
||||
namespace ODB
|
||||
{
|
||||
|
@ -105,6 +105,13 @@ public:
|
||||
return m_drill_layers;
|
||||
}
|
||||
|
||||
inline std::map<std::tuple<ODB_AUX_LAYER_TYPE, PCB_LAYER_ID, PCB_LAYER_ID>,
|
||||
std::vector<BOARD_ITEM*>>&
|
||||
GetAuxilliaryLayerItemsMap()
|
||||
{
|
||||
return m_auxilliary_layers;
|
||||
}
|
||||
|
||||
inline std::map<std::pair<PCB_LAYER_ID, PCB_LAYER_ID>, std::vector<BOARD_ITEM*>>&
|
||||
GetSlotHolesMap()
|
||||
{
|
||||
@ -164,6 +171,9 @@ private:
|
||||
std::map<std::pair<PCB_LAYER_ID, PCB_LAYER_ID>, std::vector<BOARD_ITEM*>>
|
||||
m_drill_layers; //<! Drill sets are output as layers (to/from pairs)
|
||||
|
||||
std::map<std::tuple<ODB_AUX_LAYER_TYPE, PCB_LAYER_ID, PCB_LAYER_ID>, std::vector<BOARD_ITEM*>>
|
||||
m_auxilliary_layers; //<! Auxilliary layers, from/to pairs or simple (depending on type)
|
||||
|
||||
std::map<std::pair<PCB_LAYER_ID, PCB_LAYER_ID>, std::vector<BOARD_ITEM*>>
|
||||
m_slot_holes; //<! Storage vector of slotted holes that need to be output as cutouts
|
||||
|
||||
|
@ -855,7 +855,7 @@ std::shared_ptr<SHAPE_SEGMENT> PCB_VIA::GetEffectiveHoleShape() const
|
||||
return std::make_shared<SHAPE_SEGMENT>( SEG( m_Start, m_Start ), Padstack().Drill().size.x );
|
||||
}
|
||||
|
||||
|
||||
// clang-format off: the suggestion is slightly less readable
|
||||
void PCB_VIA::SetFrontTentingMode( TENTING_MODE aMode )
|
||||
{
|
||||
switch( aMode )
|
||||
@ -872,7 +872,7 @@ TENTING_MODE PCB_VIA::GetFrontTentingMode() const
|
||||
if( m_padStack.FrontOuterLayers().has_solder_mask.has_value() )
|
||||
{
|
||||
return *m_padStack.FrontOuterLayers().has_solder_mask ?
|
||||
TENTING_MODE::TENTED : TENTING_MODE::NOT_TENTED;
|
||||
TENTING_MODE::TENTED : TENTING_MODE::NOT_TENTED;
|
||||
}
|
||||
|
||||
return TENTING_MODE::FROM_RULES;
|
||||
@ -895,13 +895,152 @@ TENTING_MODE PCB_VIA::GetBackTentingMode() const
|
||||
if( m_padStack.BackOuterLayers().has_solder_mask.has_value() )
|
||||
{
|
||||
return *m_padStack.BackOuterLayers().has_solder_mask ?
|
||||
TENTING_MODE::TENTED : TENTING_MODE::NOT_TENTED;
|
||||
TENTING_MODE::TENTED : TENTING_MODE::NOT_TENTED;
|
||||
}
|
||||
|
||||
return TENTING_MODE::FROM_RULES;
|
||||
}
|
||||
|
||||
|
||||
void PCB_VIA::SetFrontCoveringMode( COVERING_MODE aMode )
|
||||
{
|
||||
switch( aMode )
|
||||
{
|
||||
case COVERING_MODE::FROM_RULES: m_padStack.FrontOuterLayers().has_covering.reset(); break;
|
||||
case COVERING_MODE::COVERED: m_padStack.FrontOuterLayers().has_covering = true; break;
|
||||
case COVERING_MODE::NOT_COVERED: m_padStack.FrontOuterLayers().has_covering = false; break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
COVERING_MODE PCB_VIA::GetFrontCoveringMode() const
|
||||
{
|
||||
if( m_padStack.FrontOuterLayers().has_covering.has_value() )
|
||||
{
|
||||
return *m_padStack.FrontOuterLayers().has_covering ?
|
||||
COVERING_MODE::COVERED : COVERING_MODE::NOT_COVERED;
|
||||
}
|
||||
|
||||
return COVERING_MODE::FROM_RULES;
|
||||
}
|
||||
|
||||
|
||||
void PCB_VIA::SetBackCoveringMode( COVERING_MODE aMode )
|
||||
{
|
||||
switch( aMode )
|
||||
{
|
||||
case COVERING_MODE::FROM_RULES: m_padStack.BackOuterLayers().has_covering.reset(); break;
|
||||
case COVERING_MODE::COVERED: m_padStack.BackOuterLayers().has_covering = true; break;
|
||||
case COVERING_MODE::NOT_COVERED: m_padStack.BackOuterLayers().has_covering = false; break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
COVERING_MODE PCB_VIA::GetBackCoveringMode() const
|
||||
{
|
||||
if( m_padStack.BackOuterLayers().has_covering.has_value() )
|
||||
{
|
||||
return *m_padStack.BackOuterLayers().has_covering ?
|
||||
COVERING_MODE::COVERED : COVERING_MODE::NOT_COVERED;
|
||||
}
|
||||
|
||||
return COVERING_MODE::FROM_RULES;
|
||||
}
|
||||
|
||||
|
||||
void PCB_VIA::SetFrontPluggingMode( PLUGGING_MODE aMode )
|
||||
{
|
||||
switch( aMode )
|
||||
{
|
||||
case PLUGGING_MODE::FROM_RULES: m_padStack.FrontOuterLayers().has_plugging.reset(); break;
|
||||
case PLUGGING_MODE::PLUGGED: m_padStack.FrontOuterLayers().has_plugging = true; break;
|
||||
case PLUGGING_MODE::NOT_PLUGGED: m_padStack.FrontOuterLayers().has_plugging = false; break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PLUGGING_MODE PCB_VIA::GetFrontPluggingMode() const
|
||||
{
|
||||
if( m_padStack.FrontOuterLayers().has_plugging.has_value() )
|
||||
{
|
||||
return *m_padStack.FrontOuterLayers().has_plugging ?
|
||||
PLUGGING_MODE::PLUGGED : PLUGGING_MODE::NOT_PLUGGED;
|
||||
}
|
||||
|
||||
return PLUGGING_MODE::FROM_RULES;
|
||||
}
|
||||
|
||||
|
||||
void PCB_VIA::SetBackPluggingMode( PLUGGING_MODE aMode )
|
||||
{
|
||||
switch( aMode )
|
||||
{
|
||||
case PLUGGING_MODE::FROM_RULES: m_padStack.BackOuterLayers().has_plugging.reset(); break;
|
||||
case PLUGGING_MODE::PLUGGED: m_padStack.BackOuterLayers().has_plugging = true; break;
|
||||
case PLUGGING_MODE::NOT_PLUGGED: m_padStack.BackOuterLayers().has_plugging = false; break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PLUGGING_MODE PCB_VIA::GetBackPluggingMode() const
|
||||
{
|
||||
if( m_padStack.BackOuterLayers().has_plugging.has_value() )
|
||||
{
|
||||
return *m_padStack.BackOuterLayers().has_plugging ?
|
||||
PLUGGING_MODE::PLUGGED : PLUGGING_MODE::NOT_PLUGGED;
|
||||
}
|
||||
|
||||
return PLUGGING_MODE::FROM_RULES;
|
||||
}
|
||||
|
||||
|
||||
void PCB_VIA::SetCappingMode( CAPPING_MODE aMode )
|
||||
{
|
||||
switch( aMode )
|
||||
{
|
||||
case CAPPING_MODE::FROM_RULES: m_padStack.Drill().is_capped.reset(); break;
|
||||
case CAPPING_MODE::CAPPED: m_padStack.Drill().is_capped = true; break;
|
||||
case CAPPING_MODE::NOT_CAPPED: m_padStack.Drill().is_capped = false; break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CAPPING_MODE PCB_VIA::GetCappingMode() const
|
||||
{
|
||||
if( m_padStack.Drill().is_capped.has_value() )
|
||||
{
|
||||
return *m_padStack.Drill().is_capped ?
|
||||
CAPPING_MODE::CAPPED : CAPPING_MODE::NOT_CAPPED;
|
||||
}
|
||||
|
||||
return CAPPING_MODE::FROM_RULES;
|
||||
}
|
||||
|
||||
|
||||
void PCB_VIA::SetFillingMode( FILLING_MODE aMode )
|
||||
{
|
||||
switch( aMode )
|
||||
{
|
||||
case FILLING_MODE::FROM_RULES: m_padStack.Drill().is_filled.reset(); break;
|
||||
case FILLING_MODE::FILLED: m_padStack.Drill().is_filled = true; break;
|
||||
case FILLING_MODE::NOT_FILLED: m_padStack.Drill().is_filled = false; break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FILLING_MODE PCB_VIA::GetFillingMode() const
|
||||
{
|
||||
if( m_padStack.Drill().is_filled.has_value() )
|
||||
{
|
||||
return *m_padStack.Drill().is_filled ?
|
||||
FILLING_MODE::FILLED : FILLING_MODE::NOT_FILLED;
|
||||
}
|
||||
|
||||
return FILLING_MODE::FROM_RULES;
|
||||
}
|
||||
// clang-format on: the suggestion is slightly less readable
|
||||
|
||||
|
||||
bool PCB_VIA::IsTented( PCB_LAYER_ID aLayer ) const
|
||||
{
|
||||
wxCHECK_MSG( IsFrontLayer( aLayer ) || IsBackLayer( aLayer ), true,
|
||||
@ -2041,17 +2180,43 @@ static struct TRACK_VIA_DESC
|
||||
{
|
||||
TRACK_VIA_DESC()
|
||||
{
|
||||
// clang-format off: the suggestion is less readable
|
||||
ENUM_MAP<VIATYPE>::Instance()
|
||||
.Undefined( VIATYPE::NOT_DEFINED )
|
||||
.Map( VIATYPE::THROUGH, _HKI( "Through" ) )
|
||||
.Map( VIATYPE::BLIND_BURIED, _HKI( "Blind/buried" ) )
|
||||
.Map( VIATYPE::MICROVIA, _HKI( "Micro" ) );
|
||||
.Undefined( VIATYPE::NOT_DEFINED )
|
||||
.Map( VIATYPE::THROUGH, _HKI( "Through" ) )
|
||||
.Map( VIATYPE::BLIND_BURIED, _HKI( "Blind/buried" ) )
|
||||
.Map( VIATYPE::MICROVIA, _HKI( "Micro" ) );
|
||||
|
||||
ENUM_MAP<TENTING_MODE>::Instance()
|
||||
.Undefined( TENTING_MODE::FROM_RULES )
|
||||
.Map( TENTING_MODE::FROM_RULES, _HKI( "From design rules" ) )
|
||||
.Map( TENTING_MODE::TENTED, _HKI( "Tented" ) )
|
||||
.Map( TENTING_MODE::NOT_TENTED, _HKI( "Not tented" ) );
|
||||
.Undefined( TENTING_MODE::FROM_RULES )
|
||||
.Map( TENTING_MODE::FROM_RULES, _HKI( "From design rules" ) )
|
||||
.Map( TENTING_MODE::TENTED, _HKI( "Tented" ) )
|
||||
.Map( TENTING_MODE::NOT_TENTED, _HKI( "Not tented" ) );
|
||||
|
||||
ENUM_MAP<COVERING_MODE>::Instance()
|
||||
.Undefined( COVERING_MODE::FROM_RULES )
|
||||
.Map( COVERING_MODE::FROM_RULES, _HKI( "From design rules" ) )
|
||||
.Map( COVERING_MODE::COVERED, _HKI( "Covered" ) )
|
||||
.Map( COVERING_MODE::NOT_COVERED, _HKI( "Not covered" ) );
|
||||
|
||||
ENUM_MAP<PLUGGING_MODE>::Instance()
|
||||
.Undefined( PLUGGING_MODE::FROM_RULES )
|
||||
.Map( PLUGGING_MODE::FROM_RULES, _HKI( "From design rules" ) )
|
||||
.Map( PLUGGING_MODE::PLUGGED, _HKI( "Plugged" ) )
|
||||
.Map( PLUGGING_MODE::NOT_PLUGGED, _HKI( "Not plugged" ) );
|
||||
|
||||
ENUM_MAP<CAPPING_MODE>::Instance()
|
||||
.Undefined( CAPPING_MODE::FROM_RULES )
|
||||
.Map( CAPPING_MODE::FROM_RULES, _HKI( "From design rules" ) )
|
||||
.Map( CAPPING_MODE::CAPPED, _HKI( "Capped" ) )
|
||||
.Map( CAPPING_MODE::NOT_CAPPED, _HKI( "Not capped" ) );
|
||||
|
||||
ENUM_MAP<FILLING_MODE>::Instance()
|
||||
.Undefined( FILLING_MODE::FROM_RULES )
|
||||
.Map( FILLING_MODE::FROM_RULES, _HKI( "From design rules" ) )
|
||||
.Map( FILLING_MODE::FILLED, _HKI( "Filled" ) )
|
||||
.Map( FILLING_MODE::NOT_FILLED, _HKI( "Not filled" ) );
|
||||
// clang-format on: the suggestion is less readable
|
||||
|
||||
ENUM_MAP<PCB_LAYER_ID>& layerEnum = ENUM_MAP<PCB_LAYER_ID>::Instance();
|
||||
|
||||
@ -2118,6 +2283,7 @@ static struct TRACK_VIA_DESC
|
||||
|
||||
propMgr.Mask( TYPE_HASH( PCB_VIA ), TYPE_HASH( BOARD_CONNECTED_ITEM ), _HKI( "Layer" ) );
|
||||
|
||||
// clang-format off: the suggestion is less readable
|
||||
propMgr.AddProperty( new PROPERTY<PCB_VIA, int>( _HKI( "Diameter" ),
|
||||
&PCB_VIA::SetFrontWidth, &PCB_VIA::GetFrontWidth, PROPERTY_DISPLAY::PT_SIZE ), groupVia );
|
||||
propMgr.AddProperty( new PROPERTY<PCB_VIA, int>( _HKI( "Hole" ),
|
||||
@ -2132,8 +2298,25 @@ static struct TRACK_VIA_DESC
|
||||
&PCB_VIA::SetFrontTentingMode, &PCB_VIA::GetFrontTentingMode ), groupVia );
|
||||
propMgr.AddProperty( new PROPERTY_ENUM<PCB_VIA, TENTING_MODE>( _HKI( "Back tenting" ),
|
||||
&PCB_VIA::SetBackTentingMode, &PCB_VIA::GetBackTentingMode ), groupVia );
|
||||
propMgr.AddProperty( new PROPERTY_ENUM<PCB_VIA, COVERING_MODE>( _HKI( "Front covering" ),
|
||||
&PCB_VIA::SetFrontCoveringMode, &PCB_VIA::GetFrontCoveringMode ), groupVia );
|
||||
propMgr.AddProperty( new PROPERTY_ENUM<PCB_VIA, COVERING_MODE>( _HKI( "Back covering" ),
|
||||
&PCB_VIA::SetBackCoveringMode, &PCB_VIA::GetBackCoveringMode ), groupVia );
|
||||
propMgr.AddProperty( new PROPERTY_ENUM<PCB_VIA, PLUGGING_MODE>( _HKI( "Front plugging" ),
|
||||
&PCB_VIA::SetFrontPluggingMode, &PCB_VIA::GetFrontPluggingMode ), groupVia );
|
||||
propMgr.AddProperty( new PROPERTY_ENUM<PCB_VIA, PLUGGING_MODE>( _HKI( "Back plugging" ),
|
||||
&PCB_VIA::SetBackPluggingMode, &PCB_VIA::GetBackPluggingMode ), groupVia );
|
||||
propMgr.AddProperty( new PROPERTY_ENUM<PCB_VIA, CAPPING_MODE>( _HKI( "Capping" ),
|
||||
&PCB_VIA::SetCappingMode, &PCB_VIA::GetCappingMode ), groupVia );
|
||||
propMgr.AddProperty( new PROPERTY_ENUM<PCB_VIA, FILLING_MODE>( _HKI( "Filling" ),
|
||||
&PCB_VIA::SetFillingMode, &PCB_VIA::GetFillingMode ), groupVia );
|
||||
// clang-format on: the suggestion is less readable
|
||||
}
|
||||
} _TRACK_VIA_DESC;
|
||||
|
||||
ENUM_TO_WXANY( VIATYPE );
|
||||
ENUM_TO_WXANY( TENTING_MODE );
|
||||
ENUM_TO_WXANY( COVERING_MODE );
|
||||
ENUM_TO_WXANY( PLUGGING_MODE );
|
||||
ENUM_TO_WXANY( CAPPING_MODE );
|
||||
ENUM_TO_WXANY( FILLING_MODE );
|
||||
|
@ -78,6 +78,34 @@ enum class TENTING_MODE
|
||||
NOT_TENTED = 2
|
||||
};
|
||||
|
||||
enum class COVERING_MODE
|
||||
{
|
||||
FROM_RULES = 0,
|
||||
COVERED = 1,
|
||||
NOT_COVERED = 2
|
||||
};
|
||||
|
||||
enum class PLUGGING_MODE
|
||||
{
|
||||
FROM_RULES = 0,
|
||||
PLUGGED = 1,
|
||||
NOT_PLUGGED = 2
|
||||
};
|
||||
|
||||
enum class CAPPING_MODE
|
||||
{
|
||||
FROM_RULES = 0,
|
||||
CAPPED = 1,
|
||||
NOT_CAPPED = 2
|
||||
};
|
||||
|
||||
enum class FILLING_MODE
|
||||
{
|
||||
FROM_RULES = 0,
|
||||
FILLED = 1,
|
||||
NOT_FILLED = 2
|
||||
};
|
||||
|
||||
#define UNDEFINED_DRILL_DIAMETER -1 //< Undefined via drill diameter.
|
||||
|
||||
// Used for tracks and vias for algorithmic safety, not to enforce constraints
|
||||
@ -440,11 +468,27 @@ public:
|
||||
MINOPTMAX<int> GetWidthConstraint( wxString* aSource = nullptr ) const override;
|
||||
MINOPTMAX<int> GetDrillConstraint( wxString* aSource = nullptr ) const;
|
||||
|
||||
void SetFrontTentingMode( TENTING_MODE aMode );
|
||||
void SetFrontTentingMode( TENTING_MODE aMode );
|
||||
TENTING_MODE GetFrontTentingMode() const;
|
||||
void SetBackTentingMode( TENTING_MODE aMode );
|
||||
void SetBackTentingMode( TENTING_MODE aMode );
|
||||
TENTING_MODE GetBackTentingMode() const;
|
||||
|
||||
void SetFrontCoveringMode( COVERING_MODE aMode );
|
||||
COVERING_MODE GetFrontCoveringMode() const;
|
||||
void SetBackCoveringMode( COVERING_MODE aMode );
|
||||
COVERING_MODE GetBackCoveringMode() const;
|
||||
|
||||
void SetFrontPluggingMode( PLUGGING_MODE aMode );
|
||||
PLUGGING_MODE GetFrontPluggingMode() const;
|
||||
void SetBackPluggingMode( PLUGGING_MODE aMode );
|
||||
PLUGGING_MODE GetBackPluggingMode() const;
|
||||
|
||||
void SetCappingMode( CAPPING_MODE aMode );
|
||||
CAPPING_MODE GetCappingMode() const;
|
||||
|
||||
void SetFillingMode( FILLING_MODE aMode );
|
||||
FILLING_MODE GetFillingMode() const;
|
||||
|
||||
bool IsTented( PCB_LAYER_ID aLayer ) const override;
|
||||
int GetSolderMaskExpansion() const;
|
||||
|
||||
|
@ -1365,7 +1365,7 @@ int PCBNEW_JOBS_HANDLER::JobExportDrill( JOB* aJob )
|
||||
gerberWriter->SetMapFileFormat( mapFormat );
|
||||
|
||||
if( !gerberWriter->CreateDrillandMapFilesSet( outPath, true, aDrillJob->m_generateMap,
|
||||
m_reporter ) )
|
||||
aDrillJob->m_generateTenting, m_reporter ) )
|
||||
{
|
||||
return CLI::EXIT_CODES::ERR_INVALID_OUTPUT_CONFLICT;
|
||||
}
|
||||
|
@ -347,6 +347,9 @@ PCBNEW_SETTINGS::PCBNEW_SETTINGS()
|
||||
m_params.emplace_back( new PARAM<bool>( "gen_drill.generate_map",
|
||||
&m_GenDrill.generate_map, false ) );
|
||||
|
||||
m_params.emplace_back( new PARAM<bool>( "gen_drill.generate_tenting",
|
||||
&m_GenDrill.generate_tenting, false ) );
|
||||
|
||||
m_params.emplace_back( new PARAM<int>( "export_2581.units",
|
||||
&m_Export2581.units, 0 ) );
|
||||
|
||||
|
@ -258,6 +258,7 @@ public:
|
||||
int map_file_type;
|
||||
int zeros_format;
|
||||
bool generate_map;
|
||||
bool generate_tenting;
|
||||
};
|
||||
|
||||
struct DIALOG_IMPORT_GRAPHICS
|
||||
|
@ -806,6 +806,72 @@
|
||||
)
|
||||
)
|
||||
)
|
||||
(via
|
||||
(at 120 102)
|
||||
(size 0.6)
|
||||
(drill 0.3)
|
||||
(layers "F.Cu" "B.Cu")
|
||||
(tenting
|
||||
(front yes)
|
||||
(back yes)
|
||||
)
|
||||
(capping no)
|
||||
(covering
|
||||
(front no)
|
||||
(back no)
|
||||
)
|
||||
(plugging
|
||||
(front no)
|
||||
(back no)
|
||||
)
|
||||
(filling no)
|
||||
(net 0)
|
||||
(uuid "1960d56a-6a04-4e66-966f-9a4deaf28ebf")
|
||||
)
|
||||
(via
|
||||
(at 118 102)
|
||||
(size 0.6)
|
||||
(drill 0.3)
|
||||
(layers "F.Cu" "B.Cu")
|
||||
(tenting
|
||||
(front no)
|
||||
(back no)
|
||||
)
|
||||
(capping yes)
|
||||
(covering
|
||||
(front no)
|
||||
(back no)
|
||||
)
|
||||
(plugging
|
||||
(front no)
|
||||
(back no)
|
||||
)
|
||||
(filling yes)
|
||||
(net 0)
|
||||
(uuid "697fcc5c-9cf0-474e-bfab-8afc0fb18c62")
|
||||
)
|
||||
(via
|
||||
(at 120 103.5)
|
||||
(size 0.6)
|
||||
(drill 0.3)
|
||||
(layers "F.Cu" "B.Cu")
|
||||
(tenting
|
||||
(front yes)
|
||||
(back no)
|
||||
)
|
||||
(capping no)
|
||||
(covering
|
||||
(front no)
|
||||
(back no)
|
||||
)
|
||||
(plugging
|
||||
(front yes)
|
||||
(back no)
|
||||
)
|
||||
(filling no)
|
||||
(net 0)
|
||||
(uuid "beec9209-4c19-4ad5-ac29-5a2a547cb37b")
|
||||
)
|
||||
(segment
|
||||
(start 88.3 63.2)
|
||||
(end 90.65 60.85)
|
||||
|
@ -104,14 +104,16 @@ BOOST_FIXTURE_TEST_CASE( BoardTypes, PROTO_TEST_FIXTURE )
|
||||
break;
|
||||
|
||||
case PCB_ARC_T:
|
||||
testProtoFromKiCadObject<kiapi::board::types::Arc>( track, m_board.get() );
|
||||
testProtoFromKiCadObject<kiapi::board::types::Arc>( static_cast<PCB_ARC*>( track ),
|
||||
m_board.get() );
|
||||
break;
|
||||
|
||||
case PCB_VIA_T:
|
||||
// Vias are not strict-checked at the moment because m_zoneLayerOverrides is not
|
||||
// currently exposed to the API
|
||||
// TODO(JE) enable strict when fixed
|
||||
testProtoFromKiCadObject<kiapi::board::types::Via>( track, m_board.get(), false );
|
||||
testProtoFromKiCadObject<kiapi::board::types::Via>( static_cast<PCB_VIA*>( track ),
|
||||
m_board.get(), false );
|
||||
break;
|
||||
|
||||
default:
|
||||
|
Loading…
x
Reference in New Issue
Block a user