Fix a crash bug in DRC, and equate Margin to Edge.Cuts.

This commit is contained in:
Jeff Young 2020-11-20 21:22:27 +00:00
parent b123318cf6
commit ff3bd7e72a
6 changed files with 58 additions and 39 deletions

View File

@ -63,7 +63,7 @@ bool DRC_RULE_CONDITION::EvaluateFor( const BOARD_ITEM* aItemA, const BOARD_ITEM
} );
BOARD_ITEM* a = const_cast<BOARD_ITEM*>( aItemA );
BOARD_ITEM* b = aItemB ? const_cast<BOARD_ITEM*>( aItemB ) : DELETED_BOARD_ITEM::GetInstance();
BOARD_ITEM* b = const_cast<BOARD_ITEM*>( aItemB );
ctx.SetItems( a, b );

View File

@ -188,7 +188,7 @@ bool DRC_TEST_PROVIDER_EDGE_CLEARANCE::Run()
return true;
};
forEachGeometryItem( { PCB_SHAPE_T }, LSET( Edge_Cuts ), queryBoardOutlineItems );
forEachGeometryItem( { PCB_SHAPE_T }, LSET( 2, Edge_Cuts, Margin ), queryBoardOutlineItems );
forEachGeometryItem( s_allBasicItemsButZones, LSET::AllCuMask(), queryBoardGeometryItems );
for( const std::unique_ptr<PCB_SHAPE>& edge : edges )

View File

@ -199,11 +199,15 @@ bool DRC_TEST_PROVIDER_SILK_CLEARANCE::Run()
};
forEachGeometryItem( s_allBasicItems, LSET( 2, F_SilkS, B_SilkS ), addToSilkTree );
forEachGeometryItem( s_allBasicItems, LSET::FrontMask() | LSET::BackMask(), countTargets );
forEachGeometryItem( s_allBasicItems,
LSET::FrontMask() | LSET::BackMask() | LSET( 2, Edge_Cuts, Margin ),
countTargets );
targets *= 2; // One for adding to RTree; one for testing
forEachGeometryItem( s_allBasicItems, LSET::FrontMask() | LSET::BackMask(), addToTargetTree );
forEachGeometryItem( s_allBasicItems,
LSET::FrontMask() | LSET::BackMask() | LSET( 2, Edge_Cuts, Margin ),
addToTargetTree );
reportAux( _("Testing %d silkscreen features against %d board items."),
silkTree.size(),
@ -219,6 +223,7 @@ bool DRC_TEST_PROVIDER_SILK_CLEARANCE::Run()
DRC_RTREE::LAYER_PAIR( F_SilkS, F_Fab ),
DRC_RTREE::LAYER_PAIR( F_SilkS, F_Cu ),
DRC_RTREE::LAYER_PAIR( F_SilkS, Edge_Cuts ),
DRC_RTREE::LAYER_PAIR( F_SilkS, Margin ),
DRC_RTREE::LAYER_PAIR( B_SilkS, B_SilkS ),
DRC_RTREE::LAYER_PAIR( B_SilkS, B_Mask ),
DRC_RTREE::LAYER_PAIR( B_SilkS, B_Adhes ),
@ -226,7 +231,8 @@ bool DRC_TEST_PROVIDER_SILK_CLEARANCE::Run()
DRC_RTREE::LAYER_PAIR( B_SilkS, B_CrtYd ),
DRC_RTREE::LAYER_PAIR( B_SilkS, B_Fab ),
DRC_RTREE::LAYER_PAIR( B_SilkS, B_Cu ),
DRC_RTREE::LAYER_PAIR( B_SilkS, Edge_Cuts )
DRC_RTREE::LAYER_PAIR( B_SilkS, Edge_Cuts ),
DRC_RTREE::LAYER_PAIR( B_SilkS, Margin )
};
targetTree.QueryCollidingPairs( &silkTree, layerPairs, checkClearance, m_largestClearance,

View File

@ -1039,31 +1039,35 @@ bool PNS_KICAD_IFACE_BASE::syncTextItem( PNS::NODE* aWorld, EDA_TEXT* aText, PCB
bool PNS_KICAD_IFACE_BASE::syncGraphicalItem( PNS::NODE* aWorld, PCB_SHAPE* aItem )
{
if( aItem->GetLayer() != Edge_Cuts && !IsCopperLayer( aItem->GetLayer() ) )
return false;
// TODO: where do we handle filled polygons on copper layers?
if( aItem->GetShape() == S_POLYGON && aItem->IsFilled() )
return false;
for( SHAPE* shape : aItem->MakeEffectiveShapes() )
if( aItem->GetLayer() == Edge_Cuts
|| aItem->GetLayer() == Margin
|| IsCopperLayer( aItem->GetLayer() ) )
{
std::unique_ptr<PNS::SOLID> solid = std::make_unique<PNS::SOLID>();
// TODO: where do we handle filled polygons on copper layers?
if( aItem->GetShape() == S_POLYGON && aItem->IsFilled() )
return false;
if( aItem->GetLayer() == Edge_Cuts )
solid->SetLayers( LAYER_RANGE( F_Cu, B_Cu ) );
else
solid->SetLayer( aItem->GetLayer() );
for( SHAPE* shape : aItem->MakeEffectiveShapes() )
{
std::unique_ptr<PNS::SOLID> solid = std::make_unique<PNS::SOLID>();
solid->SetNet( -1 );
solid->SetParent( aItem );
solid->SetShape( shape );
solid->SetRoutable( false );
if( aItem->GetLayer() == Edge_Cuts || aItem->GetLayer() == Margin )
solid->SetLayers( LAYER_RANGE( F_Cu, B_Cu ) );
else
solid->SetLayer( aItem->GetLayer() );
aWorld->Add( std::move( solid ) );
solid->SetNet( -1 );
solid->SetParent( aItem );
solid->SetShape( shape );
solid->SetRoutable( false );
aWorld->Add( std::move( solid ) );
}
return true;
}
return true;
return false;
}

View File

@ -216,7 +216,8 @@ void PCB_INSPECTION_TOOL::reportClearance( DRC_CONSTRAINT_TYPE_T aClearanceType,
if( aClearanceType == CLEARANCE_CONSTRAINT )
{
if( ( aA && aA->GetLayer() == Edge_Cuts ) || ( aB && aB->GetLayer() == Edge_Cuts ) )
if( ( aA && ( aA->GetLayerSet() & LSET( 2, Edge_Cuts, Margin ) ).any() )
|| ( aB && ( aB->GetLayerSet() & LSET( 2, Edge_Cuts, Margin ) ).any() ) )
{
auto edgeConstraint = drcEngine.EvalRulesForItems( EDGE_CLEARANCE_CONSTRAINT, aA, aB,
aLayer, r );
@ -321,13 +322,13 @@ int PCB_INSPECTION_TOOL::InspectClearance( const TOOL_EVENT& aEvent )
reportClearance( SILK_CLEARANCE_CONSTRAINT, layer, a, b, r );
}
else if( !( a->GetLayerSet() & LSET( 2, layer, Edge_Cuts ) ).any() )
else if( !( a->GetLayerSet() & LSET( 3, layer, Edge_Cuts, Margin ) ).any() )
{
r->Report( wxString::Format( _( "%s not present on layer %s. No clearance defined." ),
a->GetSelectMenuText( r->GetUnits() ),
m_frame->GetBoard()->GetLayerName( layer ) ) );
}
else if( !( b->GetLayerSet() & LSET( 2, layer, Edge_Cuts ) ).any() )
else if( !( b->GetLayerSet() & LSET( 3, layer, Edge_Cuts, Margin ) ).any() )
{
r->Report( wxString::Format( _( "%s not present on layer %s. No clearance defined." ),
b->GetSelectMenuText( r->GetUnits() ),

View File

@ -796,21 +796,29 @@ void ZONE_FILLER::buildCopperItemClearances( const ZONE* aZone, PCB_LAYER_ID aLa
auto knockoutGraphicClearance =
[&]( BOARD_ITEM* aItem )
{
// A item on the Edge_Cuts is always seen as on any layer:
if( !aItem->IsOnLayer( aLayer ) && !aItem->IsOnLayer( Edge_Cuts ) )
return;
if( aItem->GetBoundingBox().Intersects( zone_boundingbox ) )
// A item on the Edge_Cuts or Margin is always seen as on any layer:
if( aItem->IsOnLayer( aLayer )
|| aItem->IsOnLayer( Edge_Cuts )
|| aItem->IsOnLayer( Margin ) )
{
int gap = evalRulesForItems( CLEARANCE_CONSTRAINT, aZone, aItem, aLayer );
if( aItem->IsOnLayer( Edge_Cuts ) )
if( aItem->GetBoundingBox().Intersects( zone_boundingbox ) )
{
gap = std::max( gap, evalRulesForItems( EDGE_CLEARANCE_CONSTRAINT, aZone,
aItem, Edge_Cuts ) );
}
int gap = evalRulesForItems( CLEARANCE_CONSTRAINT, aZone, aItem, aLayer );
addKnockout( aItem, aLayer, gap, aItem->IsOnLayer( Edge_Cuts ), aHoles );
if( aItem->IsOnLayer( Edge_Cuts ) )
{
gap = std::max( gap, evalRulesForItems( EDGE_CLEARANCE_CONSTRAINT,
aZone, aItem, Edge_Cuts ) );
}
if( aItem->IsOnLayer( Margin ) )
{
gap = std::max( gap, evalRulesForItems( EDGE_CLEARANCE_CONSTRAINT,
aZone, aItem, Margin ) );
}
addKnockout( aItem, aLayer, gap, aItem->IsOnLayer( Edge_Cuts ), aHoles );
}
}
};