Pcbnew: fix chamfered rectangular pad definitions in GenCAD exporter.
The pad comparison function was never updated when chamfered rectangular and custom pads were added so if more that one variant of either of those pad types existed in a design, only the first one would get generated and assign to every pad of that type. The custom pad primitive comparison has not be implemented so the exported designs may be broken for custom pads.
This commit is contained in:
parent
c0fdac2774
commit
06f206104d
|
@ -63,8 +63,8 @@ static void CreateShapesSection( FILE* aFile, BOARD* aPcb );
|
|||
static void CreatePadsShapesSection( FILE* aFile, BOARD* aPcb );
|
||||
static void FootprintWriteShape( FILE* File, FOOTPRINT* aFootprint, const wxString& aShapeName );
|
||||
|
||||
// layer names for Gencad export
|
||||
|
||||
// layer names for Gencad export
|
||||
static std::string GenCADLayerName( int aCuCount, PCB_LAYER_ID aId )
|
||||
{
|
||||
if( IsCopperLayer( aId ) )
|
||||
|
@ -179,6 +179,7 @@ static std::string fmt_mask( LSET aSet )
|
|||
return StrPrintf( "%08x", (unsigned) ( aSet & LSET::AllCuMask() ).to_ulong() );
|
||||
}
|
||||
|
||||
|
||||
// Export options
|
||||
static bool flipBottomPads;
|
||||
static bool uniquePins;
|
||||
|
@ -192,6 +193,7 @@ static int GencadOffsetX, GencadOffsetY;
|
|||
static std::map<FOOTPRINT*, int> componentShapes;
|
||||
static std::map<int, wxString> shapeNames;
|
||||
|
||||
|
||||
static const wxString getShapeName( FOOTPRINT* aFootprint )
|
||||
{
|
||||
static const wxString invalid( "invalid" );
|
||||
|
@ -208,9 +210,11 @@ static const wxString getShapeName( FOOTPRINT* aFootprint )
|
|||
return itName->second;
|
||||
}
|
||||
|
||||
|
||||
// GerbTool chokes on units different than INCH so this is the conversion factor
|
||||
const static double SCALE_FACTOR = 1000.0 * IU_PER_MILS;
|
||||
|
||||
|
||||
/* Two helper functions to calculate coordinates of footprints in gencad values
|
||||
* (GenCAD Y axis from bottom to top)
|
||||
*/
|
||||
|
@ -398,7 +402,6 @@ static void CreatePadsShapesSection( FILE* aFile, BOARD* aPcb )
|
|||
vias.end() );
|
||||
|
||||
// Emit vias pads
|
||||
|
||||
for( PCB_VIA* via : vias )
|
||||
{
|
||||
viastacks.push_back( via );
|
||||
|
@ -420,8 +423,10 @@ static void CreatePadsShapesSection( FILE* aFile, BOARD* aPcb )
|
|||
|
||||
pad->SetSubRatsnest( pad_name_number );
|
||||
|
||||
// @warning: This code is not 100% correct. The #PAD::Compare function does not test
|
||||
// custom pad primitives so there may be duplicate custom pads in the export.
|
||||
if( old_pad && 0 == PAD::Compare( old_pad, pad ) )
|
||||
continue; // already created
|
||||
continue;
|
||||
|
||||
old_pad = pad;
|
||||
|
||||
|
@ -443,6 +448,7 @@ static void CreatePadsShapesSection( FILE* aFile, BOARD* aPcb )
|
|||
case PAD_SHAPE::CIRCLE:
|
||||
fprintf( aFile, " ROUND %g\n",
|
||||
pad->GetDrillSize().x / SCALE_FACTOR );
|
||||
|
||||
/* Circle is center, radius */
|
||||
fprintf( aFile, "CIRCLE %g %g %g\n",
|
||||
off.x / SCALE_FACTOR,
|
||||
|
@ -582,21 +588,14 @@ static void CreatePadsShapesSection( FILE* aFile, BOARD* aPcb )
|
|||
|
||||
SHAPE_POLY_SET outline;
|
||||
int maxError = aPcb->GetDesignSettings().m_MaxError;
|
||||
wxPoint padOffset( 0, 0 );
|
||||
|
||||
TransformRoundChamferedRectToPolygon( outline, pad->GetPosition(), pad->GetSize(),
|
||||
pad->GetOrientation(), pad->GetRoundRectCornerRadius(),
|
||||
pad->GetChamferRectRatio(), pad->GetChamferPositions(), 0, maxError,
|
||||
ERROR_INSIDE );
|
||||
|
||||
// The chamfered rectangle polygon code calculates the absolute board position so
|
||||
// the footprint position has to be subtracted off polygon points to get the
|
||||
// pad position relative to the footprint.
|
||||
FOOTPRINT* parent = pad->GetParent();
|
||||
|
||||
wxPoint parentPos( 0, 0 );
|
||||
|
||||
if( parent )
|
||||
parentPos = parent->GetPosition();
|
||||
TransformRoundChamferedRectToPolygon( outline, padOffset, pad->GetSize(),
|
||||
pad->GetOrientation(),
|
||||
pad->GetRoundRectCornerRadius(),
|
||||
pad->GetChamferRectRatio(),
|
||||
pad->GetChamferPositions(), 0, maxError,
|
||||
ERROR_INSIDE );
|
||||
|
||||
for( int jj = 0; jj < outline.OutlineCount(); ++jj )
|
||||
{
|
||||
|
@ -607,10 +606,10 @@ static void CreatePadsShapesSection( FILE* aFile, BOARD* aPcb )
|
|||
{
|
||||
int next = ( ii + 1 ) % pointCount;
|
||||
fprintf( aFile, "LINE %g %g %g %g\n",
|
||||
( -parentPos.x + off.x + poly.CPoint( ii ).x ) / SCALE_FACTOR,
|
||||
( parentPos.y - off.y - poly.CPoint( ii ).y ) / SCALE_FACTOR,
|
||||
( -parentPos.x + off.x + poly.CPoint( next ).x ) / SCALE_FACTOR,
|
||||
( parentPos.y - off.y - poly.CPoint( next ).y ) / SCALE_FACTOR );
|
||||
poly.CPoint( ii ).x / SCALE_FACTOR,
|
||||
-poly.CPoint( ii ).y / SCALE_FACTOR,
|
||||
poly.CPoint( next ).x / SCALE_FACTOR,
|
||||
-poly.CPoint( next ).y / SCALE_FACTOR );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1032,48 +1032,67 @@ bool PAD::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
|
|||
}
|
||||
|
||||
|
||||
int PAD::Compare( const PAD* padref, const PAD* padcmp )
|
||||
int PAD::Compare( const PAD* aPadRef, const PAD* aPadCmp )
|
||||
{
|
||||
int diff;
|
||||
|
||||
if( ( diff = static_cast<int>( padref->GetShape() ) -
|
||||
static_cast<int>( padcmp->GetShape() ) ) != 0 )
|
||||
if( ( diff = static_cast<int>( aPadRef->GetShape() ) -
|
||||
static_cast<int>( aPadCmp->GetShape() ) ) != 0 )
|
||||
return diff;
|
||||
|
||||
if( ( diff = padref->GetDrillShape() - padcmp->GetDrillShape() ) != 0)
|
||||
if( ( diff = static_cast<int>( aPadRef->m_attribute ) -
|
||||
static_cast<int>( aPadCmp->m_attribute ) ) != 0 )
|
||||
return diff;
|
||||
|
||||
if( ( diff = padref->m_drill.x - padcmp->m_drill.x ) != 0 )
|
||||
if( ( diff = aPadRef->m_drillShape - aPadCmp->m_drillShape ) != 0 )
|
||||
return diff;
|
||||
|
||||
if( ( diff = padref->m_drill.y - padcmp->m_drill.y ) != 0 )
|
||||
if( ( diff = aPadRef->m_drill.x - aPadCmp->m_drill.x ) != 0 )
|
||||
return diff;
|
||||
|
||||
if( ( diff = padref->m_size.x - padcmp->m_size.x ) != 0 )
|
||||
if( ( diff = aPadRef->m_drill.y - aPadCmp->m_drill.y ) != 0 )
|
||||
return diff;
|
||||
|
||||
if( ( diff = padref->m_size.y - padcmp->m_size.y ) != 0 )
|
||||
if( ( diff = aPadRef->m_size.x - aPadCmp->m_size.x ) != 0 )
|
||||
return diff;
|
||||
|
||||
if( ( diff = padref->m_offset.x - padcmp->m_offset.x ) != 0 )
|
||||
if( ( diff = aPadRef->m_size.y - aPadCmp->m_size.y ) != 0 )
|
||||
return diff;
|
||||
|
||||
if( ( diff = padref->m_offset.y - padcmp->m_offset.y ) != 0 )
|
||||
if( ( diff = aPadRef->m_offset.x - aPadCmp->m_offset.x ) != 0 )
|
||||
return diff;
|
||||
|
||||
if( ( diff = padref->m_deltaSize.x - padcmp->m_deltaSize.x ) != 0 )
|
||||
if( ( diff = aPadRef->m_offset.y - aPadCmp->m_offset.y ) != 0 )
|
||||
return diff;
|
||||
|
||||
if( ( diff = padref->m_deltaSize.y - padcmp->m_deltaSize.y ) != 0 )
|
||||
if( ( diff = aPadRef->m_deltaSize.x - aPadCmp->m_deltaSize.x ) != 0 )
|
||||
return diff;
|
||||
|
||||
// TODO: test custom shapes
|
||||
if( ( diff = aPadRef->m_deltaSize.y - aPadCmp->m_deltaSize.y ) != 0 )
|
||||
return diff;
|
||||
|
||||
if( ( diff = aPadRef->m_roundedCornerScale - aPadCmp->m_roundedCornerScale ) != 0 )
|
||||
return diff;
|
||||
|
||||
if( ( diff = aPadRef->m_chamferPositions - aPadCmp->m_chamferPositions ) != 0 )
|
||||
return diff;
|
||||
|
||||
if( ( diff = aPadRef->m_chamferScale - aPadCmp->m_chamferScale ) != 0 )
|
||||
return diff;
|
||||
|
||||
if( ( diff = static_cast<int>( aPadRef->m_editPrimitives.size() ) -
|
||||
static_cast<int>( aPadCmp->m_editPrimitives.size() ) ) != 0 )
|
||||
return diff;
|
||||
|
||||
// @todo: Compare custom pad primitives for pads that have the same number of primitives
|
||||
// here. Currently there is no compare function for PCB_SHAPE objects.
|
||||
|
||||
// Dick: specctra_export needs this
|
||||
// Lorenzo: gencad also needs it to implement padstacks!
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
long long d = padref->m_layerMask.to_ullong() - padcmp->m_layerMask.to_ullong();
|
||||
long long d = aPadRef->m_layerMask.to_ullong() - aPadCmp->m_layerMask.to_ullong();
|
||||
|
||||
if( d < 0 )
|
||||
return -1;
|
||||
else if( d > 0 )
|
||||
|
@ -1082,8 +1101,8 @@ int PAD::Compare( const PAD* padref, const PAD* padcmp )
|
|||
return 0;
|
||||
#else
|
||||
// these strings are not typically constructed, since we don't get here often.
|
||||
std::string s1 = padref->m_layerMask.to_string();
|
||||
std::string s2 = padcmp->m_layerMask.to_string();
|
||||
std::string s1 = aPadRef->m_layerMask.to_string();
|
||||
std::string s2 = aPadCmp->m_layerMask.to_string();
|
||||
return s1.compare( s2 );
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -612,7 +612,7 @@ public:
|
|||
* @return less than 0 if left less than right, 0 if equal, or greater than 0 if left
|
||||
* greater than right.
|
||||
*/
|
||||
static int Compare( const PAD* padref, const PAD* padcmp );
|
||||
static int Compare( const PAD* aPadRef, const PAD* aPadCmp );
|
||||
|
||||
void Move( const wxPoint& aMoveVector ) override
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue