Gerber plot: better handling of polygonal pad shapes plotting
update GBR_CMP_PNP_METADATA.
This commit is contained in:
parent
36253450e7
commit
47f9c505c5
|
@ -590,6 +590,12 @@ wxString GBR_CMP_PNP_METADATA::FormatCmpPnPMetadata()
|
|||
if( !m_Value.IsEmpty() )
|
||||
text << start_of_line << "CVal," << m_Value << end_of_line;
|
||||
|
||||
if( !m_LibraryName.IsEmpty() )
|
||||
text << start_of_line << "CLbN," << m_LibraryName << end_of_line;
|
||||
|
||||
if( !m_LibraryDescr.IsEmpty() )
|
||||
text << start_of_line << "CLbD," << m_LibraryDescr << end_of_line;
|
||||
|
||||
text << start_of_line << "CMnt," << mounType[m_MountType] << end_of_line;
|
||||
text << start_of_line << "CRot," << m_Orientation << end_of_line;
|
||||
|
||||
|
|
|
@ -105,6 +105,17 @@ void GERBER_PLOTTER::emitDcode( const DPOINT& pt, int dcode )
|
|||
KiROUND( pt.x ), KiROUND( pt.y ), dcode );
|
||||
}
|
||||
|
||||
void GERBER_PLOTTER::ClearAllAttributes()
|
||||
{
|
||||
// Remove all attributes from object attributes dictionary (TO. and TA commands)
|
||||
if( m_useX2format )
|
||||
fputs( "%TD*%\n", outputFile );
|
||||
else
|
||||
fputs( "G04 #@! TD*\n", outputFile );
|
||||
|
||||
m_objectAttributesDictionnary.clear();
|
||||
}
|
||||
|
||||
|
||||
void GERBER_PLOTTER::clearNetAttribute()
|
||||
{
|
||||
|
@ -535,6 +546,43 @@ void GERBER_PLOTTER::Arc( const wxPoint& aCenter, double aStAngle, double aEndAn
|
|||
}
|
||||
|
||||
|
||||
void GERBER_PLOTTER::PlotGerberRegion( const std::vector< wxPoint >& aCornerList,
|
||||
void * aData )
|
||||
{
|
||||
if( aCornerList.size() <= 2 )
|
||||
return;
|
||||
|
||||
GBR_METADATA* gbr_metadata = static_cast<GBR_METADATA*>( aData );
|
||||
|
||||
bool clearTA_AperFunction = false; // true if a TA.AperFunction is used
|
||||
|
||||
if( gbr_metadata )
|
||||
{
|
||||
std::string attrib = gbr_metadata->m_ApertureMetadata.FormatAttribute( !m_useX2format );
|
||||
|
||||
if( !attrib.empty() )
|
||||
{
|
||||
fputs( attrib.c_str(), outputFile );
|
||||
clearTA_AperFunction = true;
|
||||
}
|
||||
}
|
||||
|
||||
PlotPoly( aCornerList, FILLED_SHAPE, 0 , gbr_metadata );
|
||||
|
||||
// Clear the TA attribute, to avoid the next item to inherit it:
|
||||
if( clearTA_AperFunction )
|
||||
{
|
||||
if( m_useX2format )
|
||||
{
|
||||
fputs( "%TD,.AperFunction*%\n", outputFile );
|
||||
}
|
||||
else
|
||||
{
|
||||
fputs( "G04 #@! TD,.AperFunction*\n", outputFile );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GERBER_PLOTTER::PlotPoly( const std::vector< wxPoint >& aCornerList,
|
||||
FILL_T aFill, int aWidth, void * aData )
|
||||
{
|
||||
|
@ -546,7 +594,8 @@ void GERBER_PLOTTER::PlotPoly( const std::vector< wxPoint >& aCornerList,
|
|||
// one should plot outline as thick segments
|
||||
GBR_METADATA* gbr_metadata = static_cast<GBR_METADATA*>( aData );
|
||||
|
||||
SetCurrentLineWidth( aWidth, gbr_metadata );
|
||||
if( !aFill )
|
||||
SetCurrentLineWidth( aWidth, gbr_metadata );
|
||||
|
||||
if( gbr_metadata )
|
||||
formatNetAttribute( &gbr_metadata->m_NetlistMetadata );
|
||||
|
@ -716,7 +765,7 @@ void GERBER_PLOTTER::FlashPadOval( const wxPoint& pos, const wxSize& aSize, doub
|
|||
wxSize size( aSize );
|
||||
GBR_METADATA* gbr_metadata = static_cast<GBR_METADATA*>( aData );
|
||||
|
||||
/* Plot a flashed shape. */
|
||||
// Flash a vertical or horizontal shape (this is a basic aperture).
|
||||
if( ( orient == 0 || orient == 900 || orient == 1800 || orient == 2700 )
|
||||
&& trace_mode == FILLED )
|
||||
{
|
||||
|
@ -732,7 +781,7 @@ void GERBER_PLOTTER::FlashPadOval( const wxPoint& pos, const wxSize& aSize, doub
|
|||
|
||||
emitDcode( pos_dev, 3 );
|
||||
}
|
||||
else /* Plot pad as a segment. */
|
||||
else // Plot pad as a segment.
|
||||
{
|
||||
if( size.x > size.y )
|
||||
{
|
||||
|
@ -747,10 +796,8 @@ void GERBER_PLOTTER::FlashPadOval( const wxPoint& pos, const wxSize& aSize, doub
|
|||
if( trace_mode == FILLED )
|
||||
{
|
||||
// TODO: use an aperture macro to declare the rotated pad
|
||||
|
||||
// Flash a pad anchor, if a netlist attribute is set
|
||||
if( aData )
|
||||
FlashPadCircle( pos, size.x, trace_mode, aData );
|
||||
// to be able to flash the shape
|
||||
// For now, the pad is painted.
|
||||
|
||||
// The pad is reduced to an segment with dy > dx
|
||||
int delta = size.y - size.x;
|
||||
|
@ -766,14 +813,12 @@ void GERBER_PLOTTER::FlashPadOval( const wxPoint& pos, const wxSize& aSize, doub
|
|||
{
|
||||
metadata = *gbr_metadata;
|
||||
|
||||
// If the pad is drawn on a copper layer,
|
||||
// set attribute to GBR_APERTURE_ATTRIB_CONDUCTOR
|
||||
if( metadata.IsCopper() )
|
||||
metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_CONDUCTOR );
|
||||
|
||||
#if 0 // See if one can use TO.P attribute in this case (only one segment to draw a pad)
|
||||
// Clear .P attribute, only allowed for flashed items
|
||||
// (not allowed for painted pads)
|
||||
wxString attrname( ".P" );
|
||||
metadata.m_NetlistMetadata.ClearAttribute( &attrname );
|
||||
#endif
|
||||
}
|
||||
|
||||
ThickSegment( wxPoint( pos.x + x0, pos.y + y0 ),
|
||||
|
@ -861,22 +906,10 @@ void GERBER_PLOTTER::FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aS
|
|||
EDA_DRAW_MODE_T aTraceMode, void* aData )
|
||||
|
||||
{
|
||||
GBR_METADATA gbr_metadata;
|
||||
GBR_METADATA* gbr_metadata;
|
||||
|
||||
if( aData )
|
||||
{
|
||||
gbr_metadata = *static_cast<GBR_METADATA*>( aData );
|
||||
// If the pad is drawn on a copper layer,
|
||||
// set attribute to GBR_APERTURE_ATTRIB_CONDUCTOR
|
||||
if( gbr_metadata.IsCopper() )
|
||||
gbr_metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_CONDUCTOR );
|
||||
|
||||
wxString attrname( ".P" );
|
||||
gbr_metadata.m_NetlistMetadata.ClearAttribute( &attrname ); // not allowed on inner layers
|
||||
}
|
||||
|
||||
if( aTraceMode != FILLED )
|
||||
SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH, &gbr_metadata );
|
||||
gbr_metadata = static_cast<GBR_METADATA*>( aData );
|
||||
|
||||
// Currently, a Pad RoundRect is plotted as polygon.
|
||||
// TODO: use Aperture macro and flash it
|
||||
|
@ -898,16 +931,10 @@ void GERBER_PLOTTER::FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aS
|
|||
// Close polygon
|
||||
cornerList.push_back( cornerList[0] );
|
||||
|
||||
PlotPoly( cornerList, aTraceMode == FILLED ? FILLED_SHAPE : NO_FILL,
|
||||
aTraceMode == FILLED ? 0 : GetCurrentLineWidth(), &gbr_metadata );
|
||||
|
||||
// Now, flash a pad anchor, if a netlist attribute is set
|
||||
// (remove me when a Aperture macro will be used)
|
||||
if( aData && aTraceMode == FILLED )
|
||||
{
|
||||
int diameter = std::min( aSize.x, aSize.y );
|
||||
FlashPadCircle( aPadPos, diameter, aTraceMode , aData );
|
||||
}
|
||||
if( aTraceMode == SKETCH )
|
||||
PlotPoly( cornerList, NO_FILL, GetCurrentLineWidth(), gbr_metadata );
|
||||
else
|
||||
PlotGerberRegion( cornerList, gbr_metadata );
|
||||
}
|
||||
|
||||
void GERBER_PLOTTER::FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize,
|
||||
|
@ -915,28 +942,12 @@ void GERBER_PLOTTER::FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize
|
|||
EDA_DRAW_MODE_T aTraceMode, void* aData )
|
||||
|
||||
{
|
||||
// A Pad custom is plotted as polygon.
|
||||
|
||||
// A flashed circle @aPadPos is added (anchor pad)
|
||||
// However, because the anchor pad can be circle or rect, we use only
|
||||
// a circle not bigger than the rect.
|
||||
// the main purpose is to print a flashed DCode as pad anchor
|
||||
if( aTraceMode == FILLED )
|
||||
FlashPadCircle( aPadPos, std::min( aSize.x, aSize.y ), aTraceMode, aData );
|
||||
// A Pad custom is plotted as polygon (a region in Gerber language).
|
||||
|
||||
GBR_METADATA gbr_metadata;
|
||||
|
||||
if( aData )
|
||||
{
|
||||
gbr_metadata = *static_cast<GBR_METADATA*>( aData );
|
||||
// If the pad is drawn on a copper layer,
|
||||
// set attribute to GBR_APERTURE_ATTRIB_CONDUCTOR
|
||||
if( gbr_metadata.IsCopper() )
|
||||
gbr_metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_CONDUCTOR );
|
||||
|
||||
wxString attrname( ".P" );
|
||||
gbr_metadata.m_NetlistMetadata.ClearAttribute( &attrname ); // not allowed on inner layers
|
||||
}
|
||||
|
||||
SHAPE_POLY_SET polyshape = *aPolygons;
|
||||
|
||||
|
@ -960,9 +971,10 @@ void GERBER_PLOTTER::FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize
|
|||
// Close polygon
|
||||
cornerList.push_back( cornerList[0] );
|
||||
|
||||
PlotPoly( cornerList,
|
||||
aTraceMode == FILLED ? FILLED_SHAPE : NO_FILL,
|
||||
aTraceMode == FILLED ? 0 : GetCurrentLineWidth(), &gbr_metadata );
|
||||
if( aTraceMode == SKETCH )
|
||||
PlotPoly( cornerList, NO_FILL, GetCurrentLineWidth(), &gbr_metadata );
|
||||
else
|
||||
PlotGerberRegion( cornerList, &gbr_metadata );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -971,7 +983,6 @@ void GERBER_PLOTTER::FlashPadTrapez( const wxPoint& aPadPos, const wxPoint* aCo
|
|||
double aPadOrient, EDA_DRAW_MODE_T aTrace_Mode, void* aData )
|
||||
|
||||
{
|
||||
// Currently, a Pad Trapezoid is plotted as polygon.
|
||||
// TODO: use Aperture macro and flash it
|
||||
|
||||
// polygon corners list
|
||||
|
@ -980,25 +991,6 @@ void GERBER_PLOTTER::FlashPadTrapez( const wxPoint& aPadPos, const wxPoint* aCo
|
|||
for( int ii = 0; ii < 4; ii++ )
|
||||
cornerList.push_back( aCorners[ii] );
|
||||
|
||||
// Now, flash a pad anchor, if a netlist attribute is set
|
||||
// (remove me when a Aperture macro will be used)
|
||||
if( aData && ( aTrace_Mode == FILLED ) )
|
||||
{
|
||||
// Calculate the radius of the circle inside the shape
|
||||
// It is the smaller dist from shape pos to edges
|
||||
int radius = INT_MAX;
|
||||
|
||||
for( unsigned ii = 0, jj = cornerList.size()-1; ii < cornerList.size();
|
||||
jj = ii, ii++ )
|
||||
{
|
||||
SEG segment( aCorners[ii], aCorners[jj] );
|
||||
int dist = segment.LineDistance( VECTOR2I( 0, 0) );
|
||||
radius = std::min( radius, dist );
|
||||
}
|
||||
|
||||
FlashPadCircle( aPadPos, radius*2, aTrace_Mode, aData );
|
||||
}
|
||||
|
||||
// Draw the polygon and fill the interior as required
|
||||
for( unsigned ii = 0; ii < 4; ii++ )
|
||||
{
|
||||
|
@ -1013,21 +1005,13 @@ void GERBER_PLOTTER::FlashPadTrapez( const wxPoint& aPadPos, const wxPoint* aCo
|
|||
GBR_METADATA metadata;
|
||||
|
||||
if( gbr_metadata )
|
||||
{
|
||||
metadata = *gbr_metadata;
|
||||
// If the pad is drawn on a copper layer,
|
||||
// set attribute to GBR_APERTURE_ATTRIB_CONDUCTOR
|
||||
if( metadata.IsCopper() )
|
||||
metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_CONDUCTOR );
|
||||
|
||||
wxString attrname( ".P" );
|
||||
metadata.m_NetlistMetadata.ClearAttribute( &attrname ); // not allowed on inner layers
|
||||
}
|
||||
|
||||
SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH, &metadata );
|
||||
PlotPoly( cornerList, aTrace_Mode == FILLED ? FILLED_SHAPE : NO_FILL,
|
||||
aTrace_Mode == FILLED ? 0 : GetCurrentLineWidth(),
|
||||
&metadata );
|
||||
if( aTrace_Mode == SKETCH )
|
||||
PlotPoly( cornerList, NO_FILL, USE_DEFAULT_LINE_WIDTH,
|
||||
&metadata );
|
||||
else
|
||||
PlotGerberRegion( cornerList, &metadata );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -40,11 +40,17 @@
|
|||
* %TO.CMfr,<string> Manufacturer
|
||||
* %TO.CMPN,<string> Manufacturer part number
|
||||
* %TO.Cpkg,<string> Package, as per IPC-7351
|
||||
* %TO.CVal,<string> Value, a string. E.g. 220nF
|
||||
* %TO.CMnt,<string> Mount type: (SMD|BGA|TH|Other)
|
||||
* %TO.CFtp,<string> Footprint name, a string. E.g. LQFP-100_14x14mm_P0.5mm
|
||||
This is the footprint name coming from the CAD tool libraries.
|
||||
* %TO.CVal,<string> Value, a string. E.g. 220nF
|
||||
* %TO.CMnt,<string> Mount type: (SMD|TH|Other)
|
||||
* %TO.CPgN,<string> Package name, like the JEDEC JEP95 standard.
|
||||
* %TO.CPgD,<string> Package description.
|
||||
* %TO.CHgt,<string> Height, a decimal, in the unit of the file.
|
||||
* %TO.CLbN,<string> Library name.
|
||||
* %TO.CLbD,<string> Library description.
|
||||
* %TO.Sup,<SN>,<SPN> SN is a field with the supppier name.
|
||||
* SPN is a field with the supppier part name
|
||||
*/
|
||||
class GBR_CMP_PNP_METADATA
|
||||
{
|
||||
|
@ -62,6 +68,8 @@ public:
|
|||
wxString m_MPN; // Manufacturer part number
|
||||
wxString m_Package; // Package, as per IPC-7351
|
||||
wxString m_Footprint; // Footprint name, from library
|
||||
wxString m_LibraryName; // Library name, containing the footprint
|
||||
wxString m_LibraryDescr; // Library description
|
||||
wxString m_Value; // Component value
|
||||
MOUNT_TYPE m_MountType; // SMD|TH|Other
|
||||
|
||||
|
|
|
@ -1174,7 +1174,7 @@ public:
|
|||
*/
|
||||
virtual void PlotPoly( const std::vector< wxPoint >& aCornerList,
|
||||
FILL_T aFill, int aWidth = USE_DEFAULT_LINE_WIDTH,
|
||||
void * aData = NULL ) override;
|
||||
void* aData = nullptr ) override;
|
||||
|
||||
virtual void PenTo( const wxPoint& pos, char plume ) override;
|
||||
|
||||
|
@ -1232,6 +1232,14 @@ public:
|
|||
virtual void FlashRegularPolygon( const wxPoint& aShapePos, int aDiameter, int aCornerCount,
|
||||
double aOrient, EDA_DRAW_MODE_T aTraceMode, void* aData ) override;
|
||||
|
||||
/**
|
||||
* Plot a Gerber region: similar to PlotPoly but plot only filled polygon,
|
||||
* and add the TA.AperFunction if aData contains this attribute, and clear it
|
||||
* after plotting
|
||||
*/
|
||||
void PlotGerberRegion( const std::vector< wxPoint >& aCornerList,
|
||||
void * aData = NULL );
|
||||
|
||||
/**
|
||||
* Change the plot polarity and begin a new layer
|
||||
* Used to 'scratch off' silk screen away from solder mask
|
||||
|
@ -1268,6 +1276,11 @@ public:
|
|||
*/
|
||||
virtual void EndBlock( void* aData ) override;
|
||||
|
||||
/** Remove (clear) all attributes from object attributes dictionary (TO. and TA commands)
|
||||
* similar to clearNetAttribute(), this is an unconditional reset of TO. and TA. attributes
|
||||
*/
|
||||
void ClearAllAttributes();
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Pick an existing aperture or create a new one, matching the
|
||||
|
@ -1304,9 +1317,11 @@ protected:
|
|||
/**
|
||||
* clear a Gerber net attribute record (clear object attribute dictionary)
|
||||
* and output the clear object attribute dictionary command to gerber file
|
||||
* has effect only if a net attribute is stored in m_objectAttributesDictionnary
|
||||
*/
|
||||
void clearNetAttribute();
|
||||
|
||||
// Remove all attributes from object attributes dictionary (TO. and TA commands)
|
||||
/**
|
||||
* Function getAperture returns a reference to the aperture which meets the size anf type of tool
|
||||
* if the aperture does not exist, it is created and entered in aperture list
|
||||
|
|
|
@ -49,10 +49,10 @@ PLACEFILE_GERBER_WRITER::PLACEFILE_GERBER_WRITER( BOARD* aPcb )
|
|||
{
|
||||
m_pcb = aPcb;
|
||||
/* Set conversion scale depending on drill file units */
|
||||
m_conversionUnits = 1.0 / IU_PER_MM; // Gerber units = mm
|
||||
m_conversionUnits = 1.0 / IU_PER_MM; // Gerber units = mm
|
||||
m_forceSmdItems = false;
|
||||
m_plotPad1Marker = true; // Place a marker to pin 1 (or A1) position
|
||||
m_plotOtherPadsMarker = false; // Place a marker to other pins position
|
||||
m_plotPad1Marker = true; // Place a marker to pin 1 (or A1) position
|
||||
m_plotOtherPadsMarker = true; // Place a marker to other pins position
|
||||
}
|
||||
|
||||
|
||||
|
@ -146,8 +146,12 @@ int PLACEFILE_GERBER_WRITER::CreatePlaceFile( wxString& aFullFilename,
|
|||
pnpAttrib.m_Value = FormatStringFromGerber( footprint->GetValue() );
|
||||
|
||||
// Add component footprint info:
|
||||
wxString fp_name = FROM_UTF8( footprint->GetFPID().GetLibItemName().c_str() );
|
||||
pnpAttrib.m_Footprint = FormatStringFromGerber( fp_name );
|
||||
wxString fp_info = FROM_UTF8( footprint->GetFPID().GetLibItemName().c_str() );
|
||||
pnpAttrib.m_Footprint = FormatStringFromGerber( fp_info );
|
||||
|
||||
// Add footprint lib name:
|
||||
fp_info = FROM_UTF8( footprint->GetFPID().GetLibNickname().c_str() );
|
||||
pnpAttrib.m_LibraryName = FormatStringFromGerber( fp_info );
|
||||
|
||||
gbr_metadata.m_NetlistMetadata.SetExtraData( pnpAttrib.FormatCmpPnPMetadata() );
|
||||
|
||||
|
@ -174,13 +178,13 @@ int PLACEFILE_GERBER_WRITER::CreatePlaceFile( wxString& aFullFilename,
|
|||
}
|
||||
}
|
||||
|
||||
D_PAD* pad1 = nullptr;
|
||||
std::vector<D_PAD*>pad_key_list;
|
||||
|
||||
if( m_plotPad1Marker )
|
||||
{
|
||||
pad1 = findPad1( footprint );
|
||||
findPads1( pad_key_list, footprint );
|
||||
|
||||
if( pad1 )
|
||||
for( D_PAD* pad1 : pad_key_list )
|
||||
{
|
||||
gbr_metadata.SetApertureAttrib(
|
||||
GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_PAD1_POSITION );
|
||||
|
@ -205,7 +209,18 @@ int PLACEFILE_GERBER_WRITER::CreatePlaceFile( wxString& aFullFilename,
|
|||
|
||||
for( D_PAD* pad: footprint->Pads() )
|
||||
{
|
||||
if( pad == pad1 ) // Already plotted
|
||||
bool skip_pad = false;
|
||||
|
||||
for( D_PAD* pad1 : pad_key_list )
|
||||
{
|
||||
if( pad == pad1 ) // Already plotted
|
||||
{
|
||||
skip_pad = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( skip_pad )
|
||||
continue;
|
||||
|
||||
// Skip also pads not on the current layer, like pads only
|
||||
|
@ -216,13 +231,13 @@ int PLACEFILE_GERBER_WRITER::CreatePlaceFile( wxString& aFullFilename,
|
|||
gbr_metadata.SetPadName( pad->GetName() );
|
||||
|
||||
// Flashes a round, 0 sized round shape at pad position
|
||||
int mark_size = Millimeter2iu( 0.1 );
|
||||
int mark_size = 0;
|
||||
plotter.FlashPadCircle( pad->GetPosition() + m_offset, mark_size,
|
||||
FILLED, &gbr_metadata );
|
||||
FILLED, &gbr_metadata );
|
||||
}
|
||||
}
|
||||
|
||||
plotter.EndBlock( nullptr ); // Close all .TO attributes
|
||||
plotter.ClearAllAttributes(); // Unconditionally close all .TO attributes
|
||||
|
||||
cmp_count++;
|
||||
}
|
||||
|
@ -241,27 +256,20 @@ double PLACEFILE_GERBER_WRITER::mapRotationAngle( double aAngle )
|
|||
}
|
||||
|
||||
|
||||
D_PAD* PLACEFILE_GERBER_WRITER::findPad1( MODULE* aFootprint )
|
||||
void PLACEFILE_GERBER_WRITER::findPads1( std::vector<D_PAD*>& aPadList, MODULE* aFootprint ) const
|
||||
{
|
||||
// Fint the pad "1" or pad "A1"
|
||||
// this is possible only if only one pad is found
|
||||
// Usefull to place a marker in this position
|
||||
|
||||
std::vector<D_PAD*> pad1_list;
|
||||
|
||||
for( D_PAD* pad : aFootprint->Pads() )
|
||||
{
|
||||
if( !pad->IsOnLayer( m_layer ) )
|
||||
continue;
|
||||
|
||||
if( pad->GetName() == "1" || pad->GetName() == "A1")
|
||||
pad1_list.push_back( pad );
|
||||
aPadList.push_back( pad );
|
||||
}
|
||||
|
||||
if( pad1_list.size() == 1 )
|
||||
return pad1_list[0];
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -93,10 +93,12 @@ private:
|
|||
*/
|
||||
double mapRotationAngle( double aAngle );
|
||||
|
||||
/** Find the pad 1 (or pad "A1") of a footprint
|
||||
* Usefull to plot a marker at this position
|
||||
/** Find the pad(s) 1 (or pad "A1") of a footprint
|
||||
* Usefull to plot a marker at this (these) position(s)
|
||||
* @param aPadList is the list to fill
|
||||
* @param aFootprint is the footprint to test
|
||||
*/
|
||||
D_PAD* findPad1( MODULE* aFootprint );
|
||||
void findPads1( std::vector<D_PAD*>& aPadList, MODULE* aFootprint ) const;
|
||||
};
|
||||
|
||||
#endif // #ifndef PLACEFILE_GERBER_WRITER_H
|
||||
|
|
Loading…
Reference in New Issue