ADDED allow physical_clearance between courtyards & zone fills.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/6966
This commit is contained in:
parent
58ddffe3dd
commit
6b797420d5
|
@ -1251,6 +1251,9 @@ int BOARD_DESIGN_SETTINGS::GetBiggestClearanceValue() const
|
|||
m_DRCEngine->QueryWorstConstraint( CLEARANCE_CONSTRAINT, constraint );
|
||||
biggest = std::max( biggest, constraint.Value().Min() );
|
||||
|
||||
m_DRCEngine->QueryWorstConstraint( PHYSICAL_CLEARANCE_CONSTRAINT, constraint );
|
||||
biggest = std::max( biggest, constraint.Value().Min() );
|
||||
|
||||
m_DRCEngine->QueryWorstConstraint( HOLE_CLEARANCE_CONSTRAINT, constraint );
|
||||
biggest = std::max( biggest, constraint.Value().Min() );
|
||||
|
||||
|
|
|
@ -263,6 +263,11 @@ For the latter use a `(layer "layer_name")` clause in the rule.
|
|||
(constraint thermal_spoke_width (min 12mil))
|
||||
(condition "A.Name == 'zone_GND' || A.Name == 'zone_PWR'"))
|
||||
|
||||
# Prevent copper fills under the courtyards of capacitors
|
||||
(rule no_copper_under_caps
|
||||
(constraint physical_clearance (min 0mm))
|
||||
(condition "A.Type == 'Zone' && B.Reference == 'C*'"))
|
||||
|
||||
|
||||
# Prevent solder wicking from SMD pads
|
||||
(rule holes_in_pads
|
||||
|
|
|
@ -717,34 +717,25 @@ int BOARD_INSPECTION_TOOL::InspectClearance( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
|
||||
// a or b could be null after group tests above.
|
||||
wxCHECK( a && b, 0 );
|
||||
if( !a || !b )
|
||||
return 0;
|
||||
|
||||
auto checkFootprint =
|
||||
[&]( FOOTPRINT* footprint ) -> BOARD_ITEM*
|
||||
{
|
||||
if( footprint->Pads().empty() )
|
||||
{
|
||||
m_frame->ShowInfoBarError( _( "Cannot generate clearance report on footprint "
|
||||
"with no pads." ) );
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PAD* foundPad = nullptr;
|
||||
|
||||
for( PAD* pad : footprint->Pads() )
|
||||
{
|
||||
if( !foundPad || pad->SameLogicalPadAs( foundPad ) )
|
||||
{
|
||||
foundPad = pad;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_frame->ShowInfoBarError( _( "Cannot generate clearance report on footprint "
|
||||
"with multiple pads. Select a single pad." ) );
|
||||
return nullptr;
|
||||
}
|
||||
return footprint;
|
||||
}
|
||||
|
||||
if( !foundPad )
|
||||
return footprint;
|
||||
|
||||
return foundPad;
|
||||
};
|
||||
|
||||
|
@ -755,7 +746,8 @@ int BOARD_INSPECTION_TOOL::InspectClearance( const TOOL_EVENT& aEvent )
|
|||
b = checkFootprint( static_cast<FOOTPRINT*>( b ) );
|
||||
|
||||
// a or b could be null after footprint tests above.
|
||||
wxCHECK( a && b, 0 );
|
||||
if( !a || !b )
|
||||
return 0;
|
||||
|
||||
DIALOG_BOOK_REPORTER* dialog = m_frame->GetInspectClearanceDialog();
|
||||
|
||||
|
|
|
@ -979,7 +979,7 @@ void ZONE_FILLER::knockoutThermalReliefs( const ZONE* aZone, PCB_LAYER_ID aLayer
|
|||
* not connected to it.
|
||||
*/
|
||||
void ZONE_FILLER::buildCopperItemClearances( const ZONE* aZone, PCB_LAYER_ID aLayer,
|
||||
const std::vector<PAD*> aNoConnectionPads,
|
||||
const std::vector<PAD*>& aNoConnectionPads,
|
||||
SHAPE_POLY_SET& aHoles )
|
||||
{
|
||||
BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings();
|
||||
|
@ -1006,7 +1006,11 @@ void ZONE_FILLER::buildCopperItemClearances( const ZONE* aZone, PCB_LAYER_ID aLa
|
|||
PCB_LAYER_ID aEvalLayer ) -> int
|
||||
{
|
||||
DRC_CONSTRAINT c = bds.m_DRCEngine->EvalRules( aConstraint, a, b, aEvalLayer );
|
||||
return c.GetValue().Min();
|
||||
|
||||
if( c.IsNull() )
|
||||
return -1;
|
||||
else
|
||||
return c.GetValue().Min();
|
||||
};
|
||||
|
||||
// Add non-connected pad clearances
|
||||
|
@ -1026,7 +1030,7 @@ void ZONE_FILLER::buildCopperItemClearances( const ZONE* aZone, PCB_LAYER_ID aLa
|
|||
aZone, aPad, aLayer ) );
|
||||
}
|
||||
|
||||
if( flashLayer && gap > 0 )
|
||||
if( flashLayer && gap >= 0 )
|
||||
addKnockout( aPad, aLayer, gap + extra_margin, aHoles );
|
||||
|
||||
if( hasHole )
|
||||
|
@ -1041,7 +1045,7 @@ void ZONE_FILLER::buildCopperItemClearances( const ZONE* aZone, PCB_LAYER_ID aLa
|
|||
gap = std::max( gap, evalRulesForItems( HOLE_CLEARANCE_CONSTRAINT,
|
||||
aZone, aPad, aLayer ) );
|
||||
|
||||
if( gap > 0 )
|
||||
if( gap >= 0 )
|
||||
addHoleKnockout( aPad, gap + extra_margin, aHoles );
|
||||
}
|
||||
};
|
||||
|
@ -1102,7 +1106,7 @@ void ZONE_FILLER::buildCopperItemClearances( const ZONE* aZone, PCB_LAYER_ID aLa
|
|||
aZone, via, aLayer ) );
|
||||
}
|
||||
|
||||
if( gap > 0 )
|
||||
if( gap >= 0 )
|
||||
{
|
||||
int radius = via->GetDrillValue() / 2;
|
||||
|
||||
|
@ -1113,7 +1117,7 @@ void ZONE_FILLER::buildCopperItemClearances( const ZONE* aZone, PCB_LAYER_ID aLa
|
|||
}
|
||||
else
|
||||
{
|
||||
if( gap > 0 )
|
||||
if( gap >= 0 )
|
||||
{
|
||||
aTrack->TransformShapeToPolygon( aHoles, aLayer, gap + extra_margin,
|
||||
m_maxError, ERROR_OUTSIDE );
|
||||
|
@ -1176,14 +1180,39 @@ void ZONE_FILLER::buildCopperItemClearances( const ZONE* aZone, PCB_LAYER_ID aLa
|
|||
aZone, aItem, aLayer ) );
|
||||
}
|
||||
|
||||
if( gap > 0 )
|
||||
addKnockout( aItem, aLayer, gap + extra_margin, ignoreLineWidths, aHoles );
|
||||
if( gap >= 0 )
|
||||
{
|
||||
gap += extra_margin;
|
||||
addKnockout( aItem, aLayer, gap, ignoreLineWidths, aHoles );
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
auto knockoutCourtyardClearance =
|
||||
[&]( FOOTPRINT* aFootprint )
|
||||
{
|
||||
if( aFootprint->GetBoundingBox().Intersects( zone_boundingbox ) )
|
||||
{
|
||||
int gap = evalRulesForItems( PHYSICAL_CLEARANCE_CONSTRAINT, aZone,
|
||||
aFootprint, aLayer );
|
||||
|
||||
if( gap == 0 )
|
||||
{
|
||||
aHoles.Append( aFootprint->GetCourtyard( aLayer ) );
|
||||
}
|
||||
else if( gap > 0 )
|
||||
{
|
||||
SHAPE_POLY_SET hole = aFootprint->GetCourtyard( aLayer );
|
||||
hole.Inflate( gap, CORNER_STRATEGY::ROUND_ALL_CORNERS, m_maxError );
|
||||
aHoles.Append( hole );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
for( FOOTPRINT* footprint : m_board->Footprints() )
|
||||
{
|
||||
knockoutCourtyardClearance( footprint );
|
||||
knockoutGraphicClearance( &footprint->Reference() );
|
||||
knockoutGraphicClearance( &footprint->Value() );
|
||||
|
||||
|
@ -1273,11 +1302,11 @@ void ZONE_FILLER::buildCopperItemClearances( const ZONE* aZone, PCB_LAYER_ID aLa
|
|||
}
|
||||
else
|
||||
{
|
||||
int gap = evalRulesForItems( PHYSICAL_CLEARANCE_CONSTRAINT, aZone,
|
||||
aKnockout, aLayer );
|
||||
int gap = std::max( 0, evalRulesForItems( PHYSICAL_CLEARANCE_CONSTRAINT,
|
||||
aZone, aKnockout, aLayer ) );
|
||||
|
||||
gap = std::max( gap, evalRulesForItems( CLEARANCE_CONSTRAINT, aZone,
|
||||
aKnockout, aLayer ) );
|
||||
gap = std::max( gap, evalRulesForItems( CLEARANCE_CONSTRAINT,
|
||||
aZone, aKnockout, aLayer ) );
|
||||
|
||||
SHAPE_POLY_SET poly;
|
||||
aKnockout->TransformShapeToPolygon( poly, aLayer, gap + extra_margin,
|
||||
|
|
|
@ -73,7 +73,7 @@ private:
|
|||
std::vector<PAD*>& aNoConnectionPads );
|
||||
|
||||
void buildCopperItemClearances( const ZONE* aZone, PCB_LAYER_ID aLayer,
|
||||
const std::vector<PAD*> aNoConnectionPads,
|
||||
const std::vector<PAD*>& aNoConnectionPads,
|
||||
SHAPE_POLY_SET& aHoles );
|
||||
|
||||
void subtractHigherPriorityZones( const ZONE* aZone, PCB_LAYER_ID aLayer,
|
||||
|
|
Loading…
Reference in New Issue