Allow custom pads with 0-sized anchor pads.
(Surprisingly we used to in 5.1, so this is a regression.) Also had to go back to the nag dialog as on a small screen the infobar comes up behind the dialog. A lot of the errors have also been turned into warnings, so the overall effect should still be to reduce nagging. Fixes https://gitlab.com/kicad/code/kicad/issues/6992
This commit is contained in:
parent
3467e643e5
commit
8fffb75347
|
@ -1196,7 +1196,6 @@ void DIALOG_PAD_PROPERTIES::OnSetLayers( wxCommandEvent& event )
|
|||
bool DIALOG_PAD_PROPERTIES::padValuesOK()
|
||||
{
|
||||
bool error = transferDataToPad( m_dummyPad );
|
||||
bool skip_tstoffset = false; // the offset prm is not always tested
|
||||
|
||||
wxArrayString error_msgs;
|
||||
wxArrayString warning_msgs;
|
||||
|
@ -1204,10 +1203,19 @@ bool DIALOG_PAD_PROPERTIES::padValuesOK()
|
|||
wxSize pad_size = m_dummyPad->GetSize();
|
||||
wxSize drill_size = m_dummyPad->GetDrillSize();
|
||||
|
||||
// Test for incorrect values
|
||||
if( pad_size.x <= 0 || ( pad_size.y <= 0 && m_dummyPad->GetShape() != PAD_SHAPE_CIRCLE ) )
|
||||
if( m_dummyPad->GetShape() == PAD_SHAPE_CUSTOM )
|
||||
{
|
||||
error_msgs.Add( _( "Warning: Pad size is less than zero." ) );
|
||||
// allow 0-sized anchor pads
|
||||
}
|
||||
else if( m_dummyPad->GetShape() == PAD_SHAPE_CIRCLE )
|
||||
{
|
||||
if( pad_size.x <= 0 )
|
||||
warning_msgs.Add( _( "Warning: Pad size is less than zero." ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( pad_size.x <= 0 || pad_size.y <= 0 )
|
||||
warning_msgs.Add( _( "Warning: Pad size is less than zero." ) );
|
||||
}
|
||||
|
||||
// Test hole size against pad size
|
||||
|
@ -1230,18 +1238,15 @@ bool DIALOG_PAD_PROPERTIES::padValuesOK()
|
|||
|
||||
drillOutline.BooleanSubtract( padOutline, SHAPE_POLY_SET::POLYGON_MODE::PM_FAST );
|
||||
|
||||
if( ( drillOutline.BBox().GetWidth() > 0 ) || ( drillOutline.BBox().GetHeight() > 0 ) )
|
||||
if( drillOutline.BBox().GetWidth() > 0 || drillOutline.BBox().GetHeight() > 0 )
|
||||
{
|
||||
warning_msgs.Add( _( "Warning: Pad drill will leave no copper or drill shape and "
|
||||
"pad shape do not overlap." ) );
|
||||
skip_tstoffset = true; // offset parameter will be not tested because if the drill
|
||||
// value is incorrect the offset parameter is always seen as
|
||||
// incorrect, even if it is 0
|
||||
}
|
||||
}
|
||||
|
||||
if( m_dummyPad->GetLocalClearance() < 0 )
|
||||
error_msgs.Add( _( "Error: Negative local clearance values will have no effect." ) );
|
||||
warning_msgs.Add( _( "Warning: Negative local clearance values will have no effect." ) );
|
||||
|
||||
// Some pads need a negative solder mask clearance (mainly for BGA with small pads)
|
||||
// However the negative solder mask clearance must not create negative mask size
|
||||
|
@ -1250,8 +1255,8 @@ bool DIALOG_PAD_PROPERTIES::padValuesOK()
|
|||
// allowed for custom pad shape
|
||||
if( m_dummyPad->GetLocalSolderMaskMargin() < 0 && m_dummyPad->GetShape() == PAD_SHAPE_CUSTOM )
|
||||
{
|
||||
error_msgs.Add( _( "Error: Negative solder mask clearances are not supported for custom "
|
||||
"pad shapes." ) );
|
||||
warning_msgs.Add( _( "Warning: Negative solder mask clearances are not supported for "
|
||||
"custom pad shapes." ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1263,8 +1268,8 @@ bool DIALOG_PAD_PROPERTIES::padValuesOK()
|
|||
|
||||
if( solder_size.x <= 0 || solder_size.y <= 0 )
|
||||
{
|
||||
error_msgs.Add( _( "Warning: Negative solder mask clearance larger than pad. No "
|
||||
"solder mask will be generated." ) );
|
||||
warning_msgs.Add( _( "Warning: Negative solder mask clearance larger than pad. No "
|
||||
"solder mask will be generated." ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1282,8 +1287,8 @@ bool DIALOG_PAD_PROPERTIES::padValuesOK()
|
|||
|
||||
if( paste_size.x <= 0 || paste_size.y <= 0 )
|
||||
{
|
||||
error_msgs.Add( _( "Warning: Negative solder paste margins larger than pad. No solder "
|
||||
"paste mask will be generated." ) );
|
||||
warning_msgs.Add( _( "Warning: Negative solder paste margins larger than pad. No solder "
|
||||
"paste mask will be generated." ) );
|
||||
}
|
||||
|
||||
LSET padlayers_mask = m_dummyPad->GetLayerSet();
|
||||
|
@ -1300,22 +1305,6 @@ bool DIALOG_PAD_PROPERTIES::padValuesOK()
|
|||
}
|
||||
}
|
||||
|
||||
//Note: the below test might be unnecessary
|
||||
if( !skip_tstoffset && m_dummyPad->GetShape() != PAD_SHAPE_CUSTOM )
|
||||
{
|
||||
wxPoint max_size;
|
||||
max_size.x = std::abs( m_dummyPad->GetOffset().x );
|
||||
max_size.y = std::abs( m_dummyPad->GetOffset().y );
|
||||
max_size.x += m_dummyPad->GetDrillSize().x / 2;
|
||||
max_size.y += m_dummyPad->GetDrillSize().y / 2;
|
||||
|
||||
if( ( m_dummyPad->GetSize().x / 2 < max_size.x ) ||
|
||||
( m_dummyPad->GetSize().y / 2 < max_size.y ) )
|
||||
{
|
||||
error_msgs.Add( _( "Incorrect value for pad offset." ) );
|
||||
}
|
||||
}
|
||||
|
||||
if( error )
|
||||
error_msgs.Add( _( "Too large value for pad delta size." ) );
|
||||
|
||||
|
@ -1326,15 +1315,15 @@ bool DIALOG_PAD_PROPERTIES::padValuesOK()
|
|||
if( drill_size.x <= 0
|
||||
|| ( drill_size.y <= 0 && m_dummyPad->GetDrillShape() == PAD_DRILL_SHAPE_OBLONG ) )
|
||||
{
|
||||
error_msgs.Add( _( "Error: Through hole pad has no hole." ) );
|
||||
warning_msgs.Add( _( "Warning: Through hole pad has no hole." ) );
|
||||
}
|
||||
break;
|
||||
|
||||
case PAD_ATTRIB_CONN: // Connector pads are smd pads, just they do not have solder paste.
|
||||
if( padlayers_mask[B_Paste] || padlayers_mask[F_Paste] )
|
||||
{
|
||||
error_msgs.Add( _( "Error: Connector pads have no solder paste. Use an SMD pad "
|
||||
"instead." ) );
|
||||
warning_msgs.Add( _( "Warning: Connector pads normally have no solder paste. Use an "
|
||||
"SMD pad instead." ) );
|
||||
}
|
||||
KI_FALLTHROUGH;
|
||||
|
||||
|
@ -1342,44 +1331,41 @@ bool DIALOG_PAD_PROPERTIES::padValuesOK()
|
|||
{
|
||||
LSET innerlayers_mask = padlayers_mask & LSET::InternalCuMask();
|
||||
|
||||
if( ( padlayers_mask[F_Cu] && padlayers_mask[B_Cu] ) ||
|
||||
innerlayers_mask.count() != 0 )
|
||||
{
|
||||
if( ( padlayers_mask[F_Cu] && padlayers_mask[B_Cu] ) || innerlayers_mask.count() != 0 )
|
||||
warning_msgs.Add( _( "Warning: SMD pad has no outer layers." ) );
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if( ( m_dummyPad->GetProperty() == PAD_PROP_FIDUCIAL_GLBL
|
||||
|| m_dummyPad->GetProperty() == PAD_PROP_FIDUCIAL_LOCAL )
|
||||
&& m_dummyPad->GetAttribute() == PAD_ATTRIB_NPTH )
|
||||
if( ( m_dummyPad->GetProperty() == PAD_PROP_FIDUCIAL_GLBL ||
|
||||
m_dummyPad->GetProperty() == PAD_PROP_FIDUCIAL_LOCAL ) &&
|
||||
m_dummyPad->GetAttribute() == PAD_ATTRIB_NPTH )
|
||||
{
|
||||
error_msgs.Add( _( "Warning: Fiducial property cannot be set on NPTH pads." ) );
|
||||
warning_msgs.Add( _( "Warning: Fiducial property makes no sense on NPTH pads." ) );
|
||||
}
|
||||
|
||||
if( m_dummyPad->GetProperty() == PAD_PROP_TESTPOINT &&
|
||||
m_dummyPad->GetAttribute() == PAD_ATTRIB_NPTH )
|
||||
{
|
||||
error_msgs.Add( _( "Warning: Testpoint property cannot be set on NPTH pads." ) );
|
||||
warning_msgs.Add( _( "Warning: Testpoint property makes no sense on NPTH pads." ) );
|
||||
}
|
||||
|
||||
if( m_dummyPad->GetProperty() == PAD_PROP_HEATSINK &&
|
||||
m_dummyPad->GetAttribute() == PAD_ATTRIB_NPTH )
|
||||
{
|
||||
error_msgs.Add( _( "Warning: Heatsink property cannot be set on NPTH pads." ) );
|
||||
warning_msgs.Add( _( "Warning: Heatsink property makes no sense of NPTH pads." ) );
|
||||
}
|
||||
|
||||
if( m_dummyPad->GetProperty() == PAD_PROP_CASTELLATED &&
|
||||
m_dummyPad->GetAttribute() != PAD_ATTRIB_PTH )
|
||||
{
|
||||
error_msgs.Add( _( "Warning: Castellated property can be set only on PTH pads." ) );
|
||||
warning_msgs.Add( _( "Warning: Castellated property is for PTH pads." ) );
|
||||
}
|
||||
|
||||
if( m_dummyPad->GetProperty() == PAD_PROP_BGA &&
|
||||
m_dummyPad->GetAttribute() != PAD_ATTRIB_SMD )
|
||||
{
|
||||
error_msgs.Add( _( "Warning: BGA property can be set only on SMD pads." ) );
|
||||
warning_msgs.Add( _( "Warning: BGA property is for SMD pads." ) );
|
||||
}
|
||||
|
||||
if( m_dummyPad->GetShape() == PAD_SHAPE_ROUNDRECT ||
|
||||
|
@ -1398,7 +1384,7 @@ bool DIALOG_PAD_PROPERTIES::padValuesOK()
|
|||
if( rrRadiusRatioPercent < 0.0 )
|
||||
error_msgs.Add( _( "Error: Negative corner size." ) );
|
||||
else if( rrRadiusRatioPercent > 50.0 )
|
||||
error_msgs.Add( _( "Warning: Corner size will make pad circular." ) );
|
||||
warning_msgs.Add( _( "Warning: Corner size will make pad circular." ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1413,9 +1399,12 @@ bool DIALOG_PAD_PROPERTIES::padValuesOK()
|
|||
}
|
||||
|
||||
|
||||
if( error_msgs.GetCount() )
|
||||
if( error_msgs.GetCount() || warning_msgs.GetCount() )
|
||||
{
|
||||
HTML_MESSAGE_BOX dlg( this, _( "Pad setup errors list" ) );
|
||||
wxString title = error_msgs.GetCount() ? _( "Pad Properties Errors" )
|
||||
: _( "Pad Properties Warnings" );
|
||||
HTML_MESSAGE_BOX dlg( this, title );
|
||||
|
||||
dlg.ListSet( error_msgs );
|
||||
|
||||
if( warning_msgs.GetCount() )
|
||||
|
@ -1423,11 +1412,6 @@ bool DIALOG_PAD_PROPERTIES::padValuesOK()
|
|||
|
||||
dlg.ShowModal();
|
||||
}
|
||||
else
|
||||
{
|
||||
for( size_t i = 0; i < warning_msgs.GetCount(); ++i )
|
||||
m_parent->ShowInfoBarWarning( warning_msgs[i] );
|
||||
}
|
||||
|
||||
return error_msgs.GetCount() == 0;
|
||||
}
|
||||
|
|
|
@ -928,6 +928,7 @@ void PCB_PAINTER::draw( const PAD* aPad, int aLayer )
|
|||
m_gal->DrawSegment( seg->GetSeg().A, seg->GetSeg().B, seg->GetWidth() );
|
||||
}
|
||||
else if( aLayer == LAYER_PADS_TH
|
||||
&& aPad->GetShape() != PAD_SHAPE_CUSTOM
|
||||
&& aPad->GetSizeX() <= aPad->GetDrillSizeX()
|
||||
&& aPad->GetSizeY() <= aPad->GetDrillSizeY() )
|
||||
{
|
||||
|
@ -955,18 +956,19 @@ void PCB_PAINTER::draw( const PAD* aPad, int aLayer )
|
|||
break;
|
||||
}
|
||||
|
||||
if( pad_size.x + margin.x <= 0 || pad_size.y + margin.y <= 0 )
|
||||
return;
|
||||
|
||||
std::unique_ptr<PAD> dummyPad;
|
||||
std::shared_ptr<SHAPE_COMPOUND> shapes;
|
||||
bool simpleShapes = true;
|
||||
|
||||
if( margin.x != margin.y )
|
||||
if( margin.x != margin.y && aPad->GetShape() != PAD_SHAPE_CUSTOM )
|
||||
{
|
||||
// Our algorithms below (polygon inflation in particular) can't handle differential
|
||||
// inflation along separate axes. So for those cases we build a dummy pad instead,
|
||||
// and inflate it.
|
||||
|
||||
if( pad_size.x + margin.x <= 0 || pad_size.y + margin.y <= 0 )
|
||||
return;
|
||||
|
||||
dummyPad.reset( static_cast<PAD*>( aPad->Duplicate() ) );
|
||||
dummyPad->SetSize( pad_size + margin + margin );
|
||||
shapes = std::dynamic_pointer_cast<SHAPE_COMPOUND>( dummyPad->GetEffectiveShape() );
|
||||
|
@ -1011,43 +1013,55 @@ void PCB_PAINTER::draw( const PAD* aPad, int aLayer )
|
|||
case SH_SEGMENT:
|
||||
{
|
||||
const SHAPE_SEGMENT* seg = (SHAPE_SEGMENT*) shape;
|
||||
m_gal->DrawSegment( seg->GetSeg().A, seg->GetSeg().B,
|
||||
seg->GetWidth() + 2 * margin.x );
|
||||
int effectiveWidth = seg->GetWidth() + 2 * margin.x;
|
||||
|
||||
if( effectiveWidth > 0 )
|
||||
m_gal->DrawSegment( seg->GetSeg().A, seg->GetSeg().B, effectiveWidth );
|
||||
}
|
||||
break;
|
||||
|
||||
case SH_CIRCLE:
|
||||
{
|
||||
const SHAPE_CIRCLE* circle = (SHAPE_CIRCLE*) shape;
|
||||
m_gal->DrawCircle( circle->GetCenter(), circle->GetRadius() + margin.x );
|
||||
int effectiveRadius = circle->GetRadius() + margin.x;
|
||||
|
||||
if( effectiveRadius > 0 )
|
||||
m_gal->DrawCircle( circle->GetCenter(), effectiveRadius );
|
||||
}
|
||||
break;
|
||||
|
||||
case SH_RECT:
|
||||
{
|
||||
const SHAPE_RECT* r = (SHAPE_RECT*) shape;
|
||||
VECTOR2I position = r->GetPosition();
|
||||
VECTOR2I effectiveSize = r->GetSize() + margin;
|
||||
|
||||
// At this point, if margin.x < 0 the actual rectangle size is
|
||||
// smaller than SHAPE_RECT r (the pad size was not modifed)
|
||||
if( margin.x < 0 )
|
||||
m_gal->DrawRectangle( r->GetPosition() - margin,
|
||||
r->GetPosition() + r->GetSize() + margin );
|
||||
else
|
||||
m_gal->DrawRectangle( r->GetPosition(), r->GetPosition() + r->GetSize() );
|
||||
|
||||
if( margin.x > 0 ) // We draw a roudned rect shape
|
||||
{
|
||||
m_gal->DrawSegment( r->GetPosition(),
|
||||
r->GetPosition() + VECTOR2I( r->GetWidth(), 0 ),
|
||||
if( effectiveSize.x > 0 && effectiveSize.y > 0 )
|
||||
m_gal->DrawRectangle( position - margin, position + effectiveSize );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_gal->DrawRectangle( r->GetPosition(), r->GetPosition() + r->GetSize() );
|
||||
}
|
||||
|
||||
// Now add on a rounded margin (using segments) if the margin > 0
|
||||
if( margin.x > 0 )
|
||||
{
|
||||
m_gal->DrawSegment( position,
|
||||
position + VECTOR2I( r->GetWidth(), 0 ),
|
||||
margin.x * 2 );
|
||||
m_gal->DrawSegment( r->GetPosition() + VECTOR2I( r->GetWidth(), 0 ),
|
||||
r->GetPosition() + r->GetSize(),
|
||||
m_gal->DrawSegment( position + VECTOR2I( r->GetWidth(), 0 ),
|
||||
position + r->GetSize(),
|
||||
margin.x * 2 );
|
||||
m_gal->DrawSegment( r->GetPosition() + r->GetSize(),
|
||||
r->GetPosition() + VECTOR2I( 0, r->GetHeight() ),
|
||||
m_gal->DrawSegment( position + r->GetSize(),
|
||||
position + VECTOR2I( 0, r->GetHeight() ),
|
||||
margin.x * 2 );
|
||||
m_gal->DrawSegment( r->GetPosition() + VECTOR2I( 0, r->GetHeight() ),
|
||||
r->GetPosition(),
|
||||
m_gal->DrawSegment( position + VECTOR2I( 0, r->GetHeight() ),
|
||||
position,
|
||||
margin.x * 2 );
|
||||
}
|
||||
}
|
||||
|
@ -1058,6 +1072,7 @@ void PCB_PAINTER::draw( const PAD* aPad, int aLayer )
|
|||
const SHAPE_SIMPLE* poly = static_cast<const SHAPE_SIMPLE*>( shape );
|
||||
m_gal->DrawPolygon( poly->Vertices() );
|
||||
|
||||
// Now add on a rounded margin (using segments) if the margin > 0
|
||||
if( margin.x > 0 )
|
||||
{
|
||||
for( size_t ii = 0; ii < poly->GetSegmentCount(); ++ii )
|
||||
|
|
Loading…
Reference in New Issue