Honour couryard_clearance rules when checking for courtyard overlaps.

This commit is contained in:
Jeff Young 2020-12-23 17:33:39 +00:00
parent 55bb407256
commit 17800b926f
2 changed files with 64 additions and 36 deletions

View File

@ -68,7 +68,7 @@ public:
private: private:
void testFootprintCourtyardDefinitions(); void testFootprintCourtyardDefinitions();
void testOverlappingComponentCourtyards(); void testCourtyardClearances();
}; };
@ -123,7 +123,7 @@ void DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::testFootprintCourtyardDefinitions()
} }
void DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::testOverlappingComponentCourtyards() void DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::testCourtyardClearances()
{ {
const int delta = 100; // This is the number of tests between 2 calls to the progress bar const int delta = 100; // This is the number of tests between 2 calls to the progress bar
@ -147,52 +147,74 @@ void DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::testOverlappingComponentCourtyards()
if( footprintFront.OutlineCount() == 0 && footprintBack.OutlineCount() == 0 ) if( footprintFront.OutlineCount() == 0 && footprintBack.OutlineCount() == 0 )
continue; // No courtyards defined continue; // No courtyards defined
BOX2I frontBBox = footprintFront.BBoxFromCaches();
BOX2I backBBox = footprintBack.BBoxFromCaches();
frontBBox.Inflate( m_largestClearance );
backBBox.Inflate( m_largestClearance );
for( auto it2 = it1 + 1; it2 != m_board->Footprints().end(); it2++ ) for( auto it2 = it1 + 1; it2 != m_board->Footprints().end(); it2++ )
{ {
FOOTPRINT* test = *it2; FOOTPRINT* test = *it2;
SHAPE_POLY_SET& testFront = test->GetPolyCourtyardFront(); SHAPE_POLY_SET& testFront = test->GetPolyCourtyardFront();
SHAPE_POLY_SET& testBack = test->GetPolyCourtyardBack(); SHAPE_POLY_SET& testBack = test->GetPolyCourtyardBack();
SHAPE_POLY_SET intersection; DRC_CONSTRAINT constraint;
bool overlap = false; int clearance;
wxPoint pos; int actual;
VECTOR2I pos;
if( footprintFront.OutlineCount() > 0 && testFront.OutlineCount() > 0 if( footprintFront.OutlineCount() > 0 && testFront.OutlineCount() > 0
&& footprintFront.BBoxFromCaches().Intersects( testFront.BBoxFromCaches() ) ) && frontBBox.Intersects( testFront.BBoxFromCaches() ) )
{ {
intersection.RemoveAllContours(); constraint = m_drcEngine->EvalRulesForItems( COURTYARD_CLEARANCE_CONSTRAINT,
intersection.Append( footprintFront ); footprint, test, F_Cu );
clearance = constraint.GetValue().Min();
// Build the common area between footprint and the test: if( footprintFront.Collide( &testFront, clearance, &actual, &pos ) )
intersection.BooleanIntersection( testFront, SHAPE_POLY_SET::PM_FAST );
// If the intersection exists then they overlap
if( intersection.OutlineCount() > 0 )
{ {
overlap = true; std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_OVERLAPPING_FOOTPRINTS );
pos = (wxPoint) intersection.CVertex( 0, 0, -1 );
if( clearance > 0 )
{
m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
constraint.GetName(),
MessageTextFromValue( userUnits(), clearance ),
MessageTextFromValue( userUnits(), actual ) );
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
drce->SetViolatingRule( constraint.GetParentRule() );
}
drce->SetItems( footprint, test );
reportViolation( drce, (wxPoint) pos );
} }
} }
if( footprintBack.OutlineCount() > 0 && testBack.OutlineCount() > 0 if( footprintBack.OutlineCount() > 0 && testBack.OutlineCount() > 0
&& footprintBack.BBoxFromCaches().Intersects( testBack.BBoxFromCaches() ) ) && backBBox.Intersects( testBack.BBoxFromCaches() ) )
{ {
intersection.RemoveAllContours(); constraint = m_drcEngine->EvalRulesForItems( COURTYARD_CLEARANCE_CONSTRAINT,
intersection.Append( footprintBack ); footprint, test, B_Cu );
clearance = constraint.GetValue().Min();
intersection.BooleanIntersection( testBack, SHAPE_POLY_SET::PM_FAST ); if( footprintBack.Collide( &testBack, clearance, &actual, &pos ) )
if( intersection.OutlineCount() > 0 )
{ {
overlap = true; std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_OVERLAPPING_FOOTPRINTS );
pos = (wxPoint) intersection.CVertex( 0, 0, -1 );
}
}
if( overlap ) if( clearance > 0 )
{ {
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_OVERLAPPING_FOOTPRINTS ); m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
drcItem->SetItems( footprint, test ); constraint.GetName(),
reportViolation( drcItem, pos ); MessageTextFromValue( userUnits(), clearance ),
MessageTextFromValue( userUnits(), actual ) );
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
drce->SetViolatingRule( constraint.GetParentRule() );
}
drce->SetItems( footprint, test );
reportViolation( drce, (wxPoint) pos );
}
} }
} }
} }
@ -202,14 +224,16 @@ void DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::testOverlappingComponentCourtyards()
bool DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::Run() bool DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::Run()
{ {
m_board = m_drcEngine->GetBoard(); m_board = m_drcEngine->GetBoard();
DRC_CONSTRAINT constraint;
// fixme: don't use polygon intersection but distance for clearance tests if( m_drcEngine->QueryWorstConstraint( COURTYARD_CLEARANCE_CONSTRAINT, constraint ) )
//m_largestClearance = 0; m_largestClearance = constraint.GetValue().Min();
//ReportAux( "Worst courtyard clearance : %d nm", m_largestClearance );
reportAux( "Worst courtyard clearance : %d nm", m_largestClearance );
testFootprintCourtyardDefinitions(); testFootprintCourtyardDefinitions();
testOverlappingComponentCourtyards(); testCourtyardClearances();
return true; return true;
} }

View File

@ -1803,10 +1803,14 @@ void FOOTPRINT::BuildPolyCourtyards( OUTLINE_ERROR_HANDLER* aErrorHandler )
constexpr int errorMax = Millimeter2iu( 0.02 ); /* error max for polygonization */ constexpr int errorMax = Millimeter2iu( 0.02 ); /* error max for polygonization */
if( !ConvertOutlineToPolygon( list_front, m_poly_courtyard_front, errorMax, aErrorHandler ) ) if( ConvertOutlineToPolygon( list_front, m_poly_courtyard_front, errorMax, aErrorHandler ) )
m_poly_courtyard_front.CacheTriangulation( false );
else
SetFlags( MALFORMED_F_COURTYARD ); SetFlags( MALFORMED_F_COURTYARD );
if( !ConvertOutlineToPolygon( list_back, m_poly_courtyard_back, errorMax, aErrorHandler ) ) if( ConvertOutlineToPolygon( list_back, m_poly_courtyard_back, errorMax, aErrorHandler ) )
m_poly_courtyard_back.CacheTriangulation( false );
else
SetFlags( MALFORMED_B_COURTYARD ); SetFlags( MALFORMED_B_COURTYARD );
} }