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* 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 ); ctx.SetItems( a, b );

View File

@ -188,7 +188,7 @@ bool DRC_TEST_PROVIDER_EDGE_CLEARANCE::Run()
return true; 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 ); forEachGeometryItem( s_allBasicItemsButZones, LSET::AllCuMask(), queryBoardGeometryItems );
for( const std::unique_ptr<PCB_SHAPE>& edge : edges ) 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( 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 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."), reportAux( _("Testing %d silkscreen features against %d board items."),
silkTree.size(), 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_Fab ),
DRC_RTREE::LAYER_PAIR( F_SilkS, F_Cu ), DRC_RTREE::LAYER_PAIR( F_SilkS, F_Cu ),
DRC_RTREE::LAYER_PAIR( F_SilkS, Edge_Cuts ), 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_SilkS ),
DRC_RTREE::LAYER_PAIR( B_SilkS, B_Mask ), DRC_RTREE::LAYER_PAIR( B_SilkS, B_Mask ),
DRC_RTREE::LAYER_PAIR( B_SilkS, B_Adhes ), 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_CrtYd ),
DRC_RTREE::LAYER_PAIR( B_SilkS, B_Fab ), DRC_RTREE::LAYER_PAIR( B_SilkS, B_Fab ),
DRC_RTREE::LAYER_PAIR( B_SilkS, B_Cu ), 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, 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 ) bool PNS_KICAD_IFACE_BASE::syncGraphicalItem( PNS::NODE* aWorld, PCB_SHAPE* aItem )
{ {
if( aItem->GetLayer() != Edge_Cuts && !IsCopperLayer( aItem->GetLayer() ) ) if( aItem->GetLayer() == Edge_Cuts
return false; || aItem->GetLayer() == Margin
|| IsCopperLayer( aItem->GetLayer() ) )
// TODO: where do we handle filled polygons on copper layers?
if( aItem->GetShape() == S_POLYGON && aItem->IsFilled() )
return false;
for( SHAPE* shape : aItem->MakeEffectiveShapes() )
{ {
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 ) for( SHAPE* shape : aItem->MakeEffectiveShapes() )
solid->SetLayers( LAYER_RANGE( F_Cu, B_Cu ) ); {
else std::unique_ptr<PNS::SOLID> solid = std::make_unique<PNS::SOLID>();
solid->SetLayer( aItem->GetLayer() );
solid->SetNet( -1 ); if( aItem->GetLayer() == Edge_Cuts || aItem->GetLayer() == Margin )
solid->SetParent( aItem ); solid->SetLayers( LAYER_RANGE( F_Cu, B_Cu ) );
solid->SetShape( shape ); else
solid->SetRoutable( false ); 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( 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, auto edgeConstraint = drcEngine.EvalRulesForItems( EDGE_CLEARANCE_CONSTRAINT, aA, aB,
aLayer, r ); aLayer, r );
@ -321,13 +322,13 @@ int PCB_INSPECTION_TOOL::InspectClearance( const TOOL_EVENT& aEvent )
reportClearance( SILK_CLEARANCE_CONSTRAINT, layer, a, b, r ); 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." ), r->Report( wxString::Format( _( "%s not present on layer %s. No clearance defined." ),
a->GetSelectMenuText( r->GetUnits() ), a->GetSelectMenuText( r->GetUnits() ),
m_frame->GetBoard()->GetLayerName( layer ) ) ); 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." ), r->Report( wxString::Format( _( "%s not present on layer %s. No clearance defined." ),
b->GetSelectMenuText( r->GetUnits() ), b->GetSelectMenuText( r->GetUnits() ),

View File

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