Fix a crash bug in DRC, and equate Margin to Edge.Cuts.
This commit is contained in:
parent
b123318cf6
commit
ff3bd7e72a
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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() ),
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue