3D viewer: fix incorrect calculation of pad shapes with clearance (i.e. pad shapes on solder paste and solder mask layers)

Fixes: lp:1767209
https://bugs.launchpad.net/kicad/+bug/1767209
This commit is contained in:
jean-pierre charras 2018-04-28 12:41:24 +02:00
parent 91cfecaa12
commit 458f9f5c97
2 changed files with 25 additions and 23 deletions

View File

@ -427,11 +427,11 @@ class CINFO3D_VISU
void createNewPad( const D_PAD* aPad, void createNewPad( const D_PAD* aPad,
CGENERICCONTAINER2D *aDstContainer, CGENERICCONTAINER2D *aDstContainer,
const wxSize &aInflateValue ) const; wxSize aInflateValue ) const;
void createNewPadWithClearance( const D_PAD *aPad, void createNewPadWithClearance( const D_PAD *aPad,
CGENERICCONTAINER2D *aDstContainer, CGENERICCONTAINER2D *aDstContainer,
int aClearanceValue ) const; wxSize aClearanceValue ) const;
COBJECT2D *createNewPadDrill( const D_PAD* aPad, int aInflateValue ); COBJECT2D *createNewPadDrill( const D_PAD* aPad, int aInflateValue );

View File

@ -297,10 +297,14 @@ COBJECT2D *CINFO3D_VISU::createNewTrack( const TRACK* aTrack,
// board_items_to_polygon_shape_transform.cpp // board_items_to_polygon_shape_transform.cpp
void CINFO3D_VISU::createNewPadWithClearance( const D_PAD* aPad, void CINFO3D_VISU::createNewPadWithClearance( const D_PAD* aPad,
CGENERICCONTAINER2D *aDstContainer, CGENERICCONTAINER2D *aDstContainer,
int aClearanceValue ) const wxSize aClearanceValue ) const
{ {
const int dx = (aPad->GetSize().x / 2) + aClearanceValue; // note: for most of shapes, aClearanceValue.x = aClearanceValue.y
const int dy = (aPad->GetSize().y / 2) + aClearanceValue; // only rectangular and oval shapes can have different values
// when drawn on the solder paste layer, because we can have a margin that is a
// percent of pad size
const int dx = (aPad->GetSize().x / 2) + aClearanceValue.x;
const int dy = (aPad->GetSize().y / 2) + aClearanceValue.y;
if( !dx || !dy ) if( !dx || !dy )
{ {
@ -328,7 +332,7 @@ void CINFO3D_VISU::createNewPadWithClearance( const D_PAD* aPad,
case PAD_SHAPE_OVAL: case PAD_SHAPE_OVAL:
{ {
if( abs( dx - dy ) == 0 ) if( dx == dy )
{ {
// The segment object cannot store start and end the same position, // The segment object cannot store start and end the same position,
// so add a circle instead // so add a circle instead
@ -351,7 +355,7 @@ void CINFO3D_VISU::createNewPadWithClearance( const D_PAD* aPad,
shape_offset.y = dy - dx; shape_offset.y = dy - dx;
iwidth = dx * 2; iwidth = dx * 2;
} }
else //if( dy <= dx ) else //if( dy < dx )
{ {
shape_offset.x = dy - dx; shape_offset.x = dy - dx;
iwidth = dy * 2; iwidth = dy * 2;
@ -374,8 +378,7 @@ void CINFO3D_VISU::createNewPadWithClearance( const D_PAD* aPad,
} }
else else
{ {
aDstContainer->Add( new CROUNDSEGMENT2D( start3DU, aDstContainer->Add( new CROUNDSEGMENT2D( start3DU, end3DU,
end3DU,
iwidth * m_biuTo3Dunits, iwidth * m_biuTo3Dunits,
*aPad ) ); *aPad ) );
} }
@ -386,7 +389,7 @@ void CINFO3D_VISU::createNewPadWithClearance( const D_PAD* aPad,
case PAD_SHAPE_TRAPEZOID: case PAD_SHAPE_TRAPEZOID:
case PAD_SHAPE_RECT: case PAD_SHAPE_RECT:
{ {
// https://github.com/KiCad/kicad-source-mirror/blob/0cab3e47ad8097db7b898b3cef2cf9b235318ca3/pcbnew/board_items_to_polygon_shape_transform.cpp#L613 // see pcbnew/board_items_to_polygon_shape_transform.cpp
wxPoint corners[4]; wxPoint corners[4];
aPad->BuildPadPolygon( corners, wxSize( 0, 0), aPad->GetOrientation() ); aPad->BuildPadPolygon( corners, wxSize( 0, 0), aPad->GetOrientation() );
@ -419,34 +422,33 @@ void CINFO3D_VISU::createNewPadWithClearance( const D_PAD* aPad,
// roundsegments that are in the same start and end position // roundsegments that are in the same start and end position
aDstContainer->Add( new CROUNDSEGMENT2D( corners3DU[0], aDstContainer->Add( new CROUNDSEGMENT2D( corners3DU[0],
corners3DU[1], corners3DU[1],
aClearanceValue * 2.0f * m_biuTo3Dunits, aClearanceValue.x * 2.0f * m_biuTo3Dunits,
*aPad ) ); *aPad ) );
aDstContainer->Add( new CROUNDSEGMENT2D( corners3DU[1], aDstContainer->Add( new CROUNDSEGMENT2D( corners3DU[1],
corners3DU[2], corners3DU[2],
aClearanceValue * 2.0f * m_biuTo3Dunits, aClearanceValue.x * 2.0f * m_biuTo3Dunits,
*aPad ) ); *aPad ) );
aDstContainer->Add( new CROUNDSEGMENT2D( corners3DU[2], aDstContainer->Add( new CROUNDSEGMENT2D( corners3DU[2],
corners3DU[3], corners3DU[3],
aClearanceValue * 2.0f * m_biuTo3Dunits, aClearanceValue.x * 2.0f * m_biuTo3Dunits,
*aPad ) ); *aPad ) );
aDstContainer->Add( new CROUNDSEGMENT2D( corners3DU[3], aDstContainer->Add( new CROUNDSEGMENT2D( corners3DU[3],
corners3DU[0], corners3DU[0],
aClearanceValue * 2.0f * m_biuTo3Dunits, aClearanceValue.x * 2.0f * m_biuTo3Dunits,
*aPad ) ); *aPad ) );
} }
break; break;
case PAD_SHAPE_ROUNDRECT: case PAD_SHAPE_ROUNDRECT:
{ {
const int pad_radius = aPad->GetRoundRectCornerRadius();
const int rounding_radius = pad_radius + aClearanceValue;
wxSize shapesize( aPad->GetSize() ); wxSize shapesize( aPad->GetSize() );
shapesize.x += aClearanceValue * 2; shapesize.x += aClearanceValue.x * 2;
shapesize.y += aClearanceValue * 2; shapesize.y += aClearanceValue.y * 2;
int rounding_radius = aPad->GetRoundRectCornerRadius( shapesize );
wxPoint corners[4]; wxPoint corners[4];
@ -501,8 +503,8 @@ void CINFO3D_VISU::createNewPadWithClearance( const D_PAD* aPad,
polyList.Append( aPad->GetCustomShapeAsPolygon() ); polyList.Append( aPad->GetCustomShapeAsPolygon() );
aPad->CustomShapeAsPolygonToBoardPosition( &polyList, aPad->ShapePos(), aPad->GetOrientation() ); aPad->CustomShapeAsPolygonToBoardPosition( &polyList, aPad->ShapePos(), aPad->GetOrientation() );
if( aClearanceValue ) if( aClearanceValue.x )
polyList.Inflate( aClearanceValue, 32 ); polyList.Inflate( aClearanceValue.x, 32 );
// This convert the poly in outline and holes // This convert the poly in outline and holes
polyList.Simplify( SHAPE_POLY_SET::PM_FAST ); polyList.Simplify( SHAPE_POLY_SET::PM_FAST );
@ -576,7 +578,7 @@ COBJECT2D *CINFO3D_VISU::createNewPadDrill( const D_PAD* aPad, int aInflateValue
// board_items_to_polygon_shape_transform.cpp // board_items_to_polygon_shape_transform.cpp
void CINFO3D_VISU::createNewPad( const D_PAD* aPad, void CINFO3D_VISU::createNewPad( const D_PAD* aPad,
CGENERICCONTAINER2D *aDstContainer, CGENERICCONTAINER2D *aDstContainer,
const wxSize &aInflateValue ) const wxSize aInflateValue ) const
{ {
switch( aPad->GetShape() ) switch( aPad->GetShape() )
{ {
@ -584,7 +586,7 @@ void CINFO3D_VISU::createNewPad( const D_PAD* aPad,
case PAD_SHAPE_OVAL: case PAD_SHAPE_OVAL:
case PAD_SHAPE_ROUNDRECT: case PAD_SHAPE_ROUNDRECT:
case PAD_SHAPE_CUSTOM: case PAD_SHAPE_CUSTOM:
createNewPadWithClearance( aPad, aDstContainer, aInflateValue.x ); createNewPadWithClearance( aPad, aDstContainer, aInflateValue );
break; break;
case PAD_SHAPE_TRAPEZOID: case PAD_SHAPE_TRAPEZOID: