qa: clearance test works and reports. about to do board outline clearance test
This commit is contained in:
parent
9d0f5c7f94
commit
d57d5d73b2
|
@ -40,7 +40,10 @@ public:
|
||||||
private:
|
private:
|
||||||
void testPadClearances();
|
void testPadClearances();
|
||||||
void testTrackClearances();
|
void testTrackClearances();
|
||||||
|
void testCopperTextAndGraphics();
|
||||||
|
void testZones();
|
||||||
|
|
||||||
|
void testCopperDrawItem( BOARD_ITEM* aItem );
|
||||||
void doTrackDrc( TRACK* aRefSeg, TRACKS::iterator aStartIt,
|
void doTrackDrc( TRACK* aRefSeg, TRACKS::iterator aStartIt,
|
||||||
TRACKS::iterator aEndIt, bool aTestZones );
|
TRACKS::iterator aEndIt, bool aTestZones );
|
||||||
bool doPadToPadsDrc( D_PAD* aRefPad, D_PAD** aStart, D_PAD** aEnd, int x_limit );
|
bool doPadToPadsDrc( D_PAD* aRefPad, D_PAD** aStart, D_PAD** aEnd, int x_limit );
|
||||||
|
@ -54,19 +57,50 @@ private:
|
||||||
int aAllowedDist, int* actualDist );
|
int aAllowedDist, int* actualDist );
|
||||||
|
|
||||||
wxPoint getLocation( TRACK* aTrack, const SEG& aConflictSeg );
|
wxPoint getLocation( TRACK* aTrack, const SEG& aConflictSeg );
|
||||||
|
wxPoint getLocation( TRACK* aTrack, ZONE_CONTAINER* aConflictZone );
|
||||||
|
|
||||||
BOARD* m_board;
|
BOARD* m_board;
|
||||||
int m_largestClearance;
|
int m_largestClearance;
|
||||||
SHAPE_POLY_SET m_boardOutline; // The board outline including cutouts
|
SHAPE_POLY_SET m_boardOutline; // The board outline including cutouts
|
||||||
bool m_boardOutlineValid;
|
bool m_boardOutlineValid;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const int UI_EPSILON = Mils2iu( 5 );
|
const int UI_EPSILON = Mils2iu( 5 );
|
||||||
|
|
||||||
|
wxPoint test::DRC_TEST_PROVIDER_CLEARANCE::getLocation( TRACK* aTrack, ZONE_CONTAINER* aConflictZone )
|
||||||
|
{
|
||||||
|
SHAPE_POLY_SET* conflictOutline;
|
||||||
|
|
||||||
|
if( aConflictZone->IsFilled() )
|
||||||
|
conflictOutline = const_cast<SHAPE_POLY_SET*>( &aConflictZone->GetFilledPolysList() );
|
||||||
|
else
|
||||||
|
conflictOutline = aConflictZone->Outline();
|
||||||
|
|
||||||
|
wxPoint pt1 = aTrack->GetPosition();
|
||||||
|
wxPoint pt2 = aTrack->GetEnd();
|
||||||
|
|
||||||
|
// If the mid-point is in the zone, then that's a fine place for the marker
|
||||||
|
if( conflictOutline->SquaredDistance( ( pt1 + pt2 ) / 2 ) == 0 )
|
||||||
|
return ( pt1 + pt2 ) / 2;
|
||||||
|
|
||||||
|
// Otherwise do a binary search for a "good enough" marker location
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while( GetLineLength( pt1, pt2 ) > UI_EPSILON )
|
||||||
|
{
|
||||||
|
if( conflictOutline->SquaredDistance( pt1 ) < conflictOutline->SquaredDistance( pt2 ) )
|
||||||
|
pt2 = ( pt1 + pt2 ) / 2;
|
||||||
|
else
|
||||||
|
pt1 = ( pt1 + pt2 ) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Once we're within UI_EPSILON pt1 and pt2 are "equivalent"
|
||||||
|
return pt1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
wxPoint test::DRC_TEST_PROVIDER_CLEARANCE::getLocation( TRACK* aTrack, const SEG& aConflictSeg )
|
wxPoint test::DRC_TEST_PROVIDER_CLEARANCE::getLocation( TRACK* aTrack, const SEG& aConflictSeg )
|
||||||
{
|
{
|
||||||
wxPoint pt1 = aTrack->GetPosition();
|
wxPoint pt1 = aTrack->GetPosition();
|
||||||
|
@ -93,14 +127,267 @@ bool test::DRC_TEST_PROVIDER_CLEARANCE::Run()
|
||||||
m_board = m_drcEngine->GetBoard();
|
m_board = m_drcEngine->GetBoard();
|
||||||
m_largestClearance = bds->GetBiggestClearanceValue();
|
m_largestClearance = bds->GetBiggestClearanceValue();
|
||||||
|
|
||||||
ReportStage(_("Testing pad copper clerances"), 0, 2 );
|
ReportStage( ("Testing pad copper clerances"), 0, 2 );
|
||||||
testPadClearances();
|
testPadClearances();
|
||||||
ReportStage(_("Testing track/via copper clerances"), 0, 2 );
|
ReportStage( ("Testing track/via copper clerances"), 1, 2 );
|
||||||
testTrackClearances();
|
testTrackClearances();
|
||||||
|
ReportStage( ("Testing copper drawing/text clerances"), 1, 2 );
|
||||||
|
testCopperTextAndGraphics();
|
||||||
|
ReportStage( ("Testing copper zone clearances"), 1, 2 );
|
||||||
|
testZones();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test::DRC_TEST_PROVIDER_CLEARANCE::testCopperTextAndGraphics()
|
||||||
|
{
|
||||||
|
// Test copper items for clearance violations with vias, tracks and pads
|
||||||
|
|
||||||
|
for( BOARD_ITEM* brdItem : m_board->Drawings() )
|
||||||
|
{
|
||||||
|
if( IsCopperLayer( brdItem->GetLayer() ) )
|
||||||
|
testCopperDrawItem( brdItem );
|
||||||
|
}
|
||||||
|
|
||||||
|
for( MODULE* module : m_board->Modules() )
|
||||||
|
{
|
||||||
|
TEXTE_MODULE& ref = module->Reference();
|
||||||
|
TEXTE_MODULE& val = module->Value();
|
||||||
|
|
||||||
|
if( ref.IsVisible() && IsCopperLayer( ref.GetLayer() ) )
|
||||||
|
testCopperDrawItem( &ref );
|
||||||
|
|
||||||
|
if( val.IsVisible() && IsCopperLayer( val.GetLayer() ) )
|
||||||
|
testCopperDrawItem( &val );
|
||||||
|
|
||||||
|
if( module->IsNetTie() )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for( BOARD_ITEM* item : module->GraphicalItems() )
|
||||||
|
{
|
||||||
|
if( IsCopperLayer( item->GetLayer() ) )
|
||||||
|
{
|
||||||
|
if( item->Type() == PCB_MODULE_TEXT_T && ( (TEXTE_MODULE*) item )->IsVisible() )
|
||||||
|
testCopperDrawItem( item );
|
||||||
|
else if( item->Type() == PCB_MODULE_EDGE_T )
|
||||||
|
testCopperDrawItem( item );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void test::DRC_TEST_PROVIDER_CLEARANCE::testCopperDrawItem( BOARD_ITEM* aItem )
|
||||||
|
{
|
||||||
|
EDA_RECT bbox;
|
||||||
|
std::vector<SEG> itemShape;
|
||||||
|
int itemWidth;
|
||||||
|
DRAWSEGMENT* drawItem = dynamic_cast<DRAWSEGMENT*>( aItem );
|
||||||
|
EDA_TEXT* textItem = dynamic_cast<EDA_TEXT*>( aItem );
|
||||||
|
|
||||||
|
if( drawItem )
|
||||||
|
{
|
||||||
|
bbox = drawItem->GetBoundingBox();
|
||||||
|
itemWidth = drawItem->GetWidth();
|
||||||
|
|
||||||
|
switch( drawItem->GetShape() )
|
||||||
|
{
|
||||||
|
case S_ARC:
|
||||||
|
{
|
||||||
|
SHAPE_ARC arc( drawItem->GetCenter(), drawItem->GetArcStart(),
|
||||||
|
(double) drawItem->GetAngle() / 10.0 );
|
||||||
|
|
||||||
|
SHAPE_LINE_CHAIN l = arc.ConvertToPolyline();
|
||||||
|
|
||||||
|
for( int i = 0; i < l.SegmentCount(); i++ )
|
||||||
|
itemShape.push_back( l.Segment( i ) );
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case S_SEGMENT:
|
||||||
|
itemShape.emplace_back( SEG( drawItem->GetStart(), drawItem->GetEnd() ) );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case S_CIRCLE:
|
||||||
|
{
|
||||||
|
// SHAPE_CIRCLE has no ConvertToPolyline() method, so use a 360.0 SHAPE_ARC
|
||||||
|
SHAPE_ARC circle( drawItem->GetCenter(), drawItem->GetEnd(), 360.0 );
|
||||||
|
|
||||||
|
SHAPE_LINE_CHAIN l = circle.ConvertToPolyline();
|
||||||
|
|
||||||
|
for( int i = 0; i < l.SegmentCount(); i++ )
|
||||||
|
itemShape.push_back( l.Segment( i ) );
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case S_CURVE:
|
||||||
|
{
|
||||||
|
drawItem->RebuildBezierToSegmentsPointsList( drawItem->GetWidth() );
|
||||||
|
wxPoint start_pt = drawItem->GetBezierPoints()[0];
|
||||||
|
|
||||||
|
for( unsigned int jj = 1; jj < drawItem->GetBezierPoints().size(); jj++ )
|
||||||
|
{
|
||||||
|
wxPoint end_pt = drawItem->GetBezierPoints()[jj];
|
||||||
|
itemShape.emplace_back( SEG( start_pt, end_pt ) );
|
||||||
|
start_pt = end_pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case S_POLYGON:
|
||||||
|
{
|
||||||
|
SHAPE_LINE_CHAIN l = drawItem->GetPolyShape().Outline( 0 );
|
||||||
|
|
||||||
|
for( int i = 0; i < l.SegmentCount(); i++ )
|
||||||
|
itemShape.push_back( l.Segment( i ) );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
wxFAIL_MSG( "unknown shape type" );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( textItem )
|
||||||
|
{
|
||||||
|
bbox = textItem->GetTextBox();
|
||||||
|
itemWidth = textItem->GetEffectiveTextPenWidth();
|
||||||
|
|
||||||
|
std::vector<wxPoint> textShape;
|
||||||
|
textItem->TransformTextShapeToSegmentList( textShape );
|
||||||
|
|
||||||
|
for( unsigned jj = 0; jj < textShape.size(); jj += 2 )
|
||||||
|
itemShape.emplace_back( SEG( textShape[jj], textShape[jj+1] ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wxFAIL_MSG( "unknown item type in testCopperDrawItem()" );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHAPE_RECT rect_area( bbox.GetX(), bbox.GetY(), bbox.GetWidth(), bbox.GetHeight() );
|
||||||
|
|
||||||
|
if( itemShape.empty() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Test tracks and vias
|
||||||
|
for( auto track : m_board->Tracks() )
|
||||||
|
{
|
||||||
|
if( !track->IsOnLayer( aItem->GetLayer() ) )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto rule = m_drcEngine->EvalRulesForItems( test::DRC_RULE_ID_T::DRC_RULE_ID_CLEARANCE, aItem, track );
|
||||||
|
auto minClearance = rule->GetConstraint().GetValue().Min();
|
||||||
|
int widths = ( track->GetWidth() + itemWidth ) / 2;
|
||||||
|
int center2centerAllowed = minClearance + widths;
|
||||||
|
|
||||||
|
SEG trackSeg( track->GetStart(), track->GetEnd() );
|
||||||
|
|
||||||
|
// Fast test to detect a track segment candidate inside the text bounding box
|
||||||
|
if( !rect_area.Collide( trackSeg, center2centerAllowed ) )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
OPT<SEG> minSeg;
|
||||||
|
SEG::ecoord center2center_squared = 0;
|
||||||
|
|
||||||
|
for( const SEG& itemSeg : itemShape )
|
||||||
|
{
|
||||||
|
SEG::ecoord thisDist_squared = trackSeg.SquaredDistance( itemSeg );
|
||||||
|
|
||||||
|
if( !minSeg || thisDist_squared < center2center_squared )
|
||||||
|
{
|
||||||
|
minSeg = itemSeg;
|
||||||
|
center2center_squared = thisDist_squared;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( center2center_squared < SEG::Square( center2centerAllowed ) )
|
||||||
|
{
|
||||||
|
int actual = std::max( 0.0, sqrt( center2center_squared ) - widths );
|
||||||
|
int errorCode = ( track->Type() == PCB_VIA_T ) ? DRCE_VIA_NEAR_COPPER
|
||||||
|
: DRCE_TRACK_NEAR_COPPER;
|
||||||
|
DRC_ITEM* drcItem = new DRC_ITEM( errorCode );
|
||||||
|
wxString msg;
|
||||||
|
msg.Printf( drcItem->GetErrorText() + _( " (%s clearance %s; actual %s)" ),
|
||||||
|
rule->GetName(),
|
||||||
|
MessageTextFromValue( userUnits(), minClearance, true ),
|
||||||
|
MessageTextFromValue( userUnits(), actual, true ) );
|
||||||
|
|
||||||
|
drcItem->SetErrorMessage( msg );
|
||||||
|
drcItem->SetItems( track, aItem );
|
||||||
|
drcItem->SetViolatingRule( rule );
|
||||||
|
|
||||||
|
wxPoint pos = getLocation( track, minSeg.get() );
|
||||||
|
ReportWithMarker( drcItem, pos );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test pads
|
||||||
|
for( auto pad : m_board->GetPads() )
|
||||||
|
{
|
||||||
|
if( !pad->IsOnLayer( aItem->GetLayer() ) )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Graphic items are allowed to act as net-ties within their own footprint
|
||||||
|
if( drawItem && pad->GetParent() == drawItem->GetParent() )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto rule = m_drcEngine->EvalRulesForItems( test::DRC_RULE_ID_T::DRC_RULE_ID_CLEARANCE, aItem, pad );
|
||||||
|
auto minClearance = rule->GetConstraint().GetValue().Min();
|
||||||
|
|
||||||
|
int widths = itemWidth / 2;
|
||||||
|
int center2centerAllowed = minClearance + widths;
|
||||||
|
|
||||||
|
// Fast test to detect a pad candidate inside the text bounding box
|
||||||
|
// Finer test (time consumming) is made only for pads near the text.
|
||||||
|
int bb_radius = pad->GetBoundingRadius() + minClearance;
|
||||||
|
VECTOR2I shape_pos( pad->ShapePos() );
|
||||||
|
|
||||||
|
if( !rect_area.Collide( SEG( shape_pos, shape_pos ), bb_radius ) )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
SHAPE_POLY_SET padOutline;
|
||||||
|
pad->TransformShapeWithClearanceToPolygon( padOutline, 0 );
|
||||||
|
|
||||||
|
OPT<SEG> minSeg;
|
||||||
|
SEG::ecoord center2center_squared = 0;
|
||||||
|
|
||||||
|
for( const SEG& itemSeg : itemShape )
|
||||||
|
{
|
||||||
|
SEG::ecoord thisCenter2center_squared = padOutline.SquaredDistance( itemSeg );
|
||||||
|
|
||||||
|
if( !minSeg || thisCenter2center_squared < center2center_squared )
|
||||||
|
{
|
||||||
|
minSeg = itemSeg;
|
||||||
|
center2center_squared = thisCenter2center_squared;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( center2center_squared < SEG::Square( center2centerAllowed ) )
|
||||||
|
{
|
||||||
|
int actual = std::max( 0.0, sqrt( center2center_squared ) - widths );
|
||||||
|
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_PAD_NEAR_COPPER );
|
||||||
|
|
||||||
|
wxString msg;
|
||||||
|
|
||||||
|
msg.Printf( drcItem->GetErrorText() + _( " (%s clearance %s; actual %s)" ),
|
||||||
|
rule->GetName(),
|
||||||
|
MessageTextFromValue( userUnits(), minClearance, true ),
|
||||||
|
MessageTextFromValue( userUnits(), actual, true ) );
|
||||||
|
|
||||||
|
drcItem->SetErrorMessage( msg );
|
||||||
|
drcItem->SetItems( pad, aItem );
|
||||||
|
drcItem->SetViolatingRule( rule );
|
||||||
|
|
||||||
|
ReportWithMarker( drcItem, pad->GetPosition() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void test::DRC_TEST_PROVIDER_CLEARANCE::testTrackClearances()
|
void test::DRC_TEST_PROVIDER_CLEARANCE::testTrackClearances()
|
||||||
{
|
{
|
||||||
const int delta = 500; // This is the number of tests between 2 calls to the
|
const int delta = 500; // This is the number of tests between 2 calls to the
|
||||||
|
@ -109,6 +396,7 @@ void test::DRC_TEST_PROVIDER_CLEARANCE::testTrackClearances()
|
||||||
int deltamax = count/delta;
|
int deltamax = count/delta;
|
||||||
|
|
||||||
ReportProgress(0.0);
|
ReportProgress(0.0);
|
||||||
|
ReportAux("Testing %d tracks...", count );
|
||||||
|
|
||||||
int ii = 0;
|
int ii = 0;
|
||||||
count = 0;
|
count = 0;
|
||||||
|
@ -124,7 +412,7 @@ void test::DRC_TEST_PROVIDER_CLEARANCE::testTrackClearances()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test new segment against tracks and pads, optionally against copper zones
|
// Test new segment against tracks and pads, optionally against copper zones
|
||||||
doTrackDrc( *seg_it, seg_it + 1, m_board->Tracks().end(), true );
|
doTrackDrc( *seg_it, seg_it + 1, m_board->Tracks().end(), false /*fixme: control for copper zones*/ );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,8 +484,9 @@ void test::DRC_TEST_PROVIDER_CLEARANCE::doTrackDrc( TRACK* aRefSeg, TRACKS::iter
|
||||||
|
|
||||||
drcItem->SetErrorMessage( msg );
|
drcItem->SetErrorMessage( msg );
|
||||||
drcItem->SetItems( aRefSeg, pad );
|
drcItem->SetItems( aRefSeg, pad );
|
||||||
|
drcItem->SetViolatingRule( rule );
|
||||||
|
|
||||||
ReportWithMarker( drcItem, rule, getLocation( aRefSeg, padSeg ) );
|
ReportWithMarker( drcItem, getLocation( aRefSeg, padSeg ) );
|
||||||
|
|
||||||
if( isErrorLimitExceeded( DRCE_TRACK_NEAR_PAD ) )
|
if( isErrorLimitExceeded( DRCE_TRACK_NEAR_PAD ) )
|
||||||
return;
|
return;
|
||||||
|
@ -267,8 +556,9 @@ void test::DRC_TEST_PROVIDER_CLEARANCE::doTrackDrc( TRACK* aRefSeg, TRACKS::iter
|
||||||
// fixme
|
// fixme
|
||||||
drcItem->SetErrorMessage( "FIXME" );
|
drcItem->SetErrorMessage( "FIXME" );
|
||||||
drcItem->SetItems( aRefSeg, track );
|
drcItem->SetItems( aRefSeg, track );
|
||||||
|
drcItem->SetViolatingRule( rule );
|
||||||
|
|
||||||
ReportWithMarker( drcItem, rule, (wxPoint) intersection.get() );
|
ReportWithMarker( drcItem, (wxPoint) intersection.get() );
|
||||||
|
|
||||||
if( isErrorLimitExceeded( DRCE_TRACKS_CROSSING ) )
|
if( isErrorLimitExceeded( DRCE_TRACKS_CROSSING ) )
|
||||||
return;
|
return;
|
||||||
|
@ -295,16 +585,15 @@ void test::DRC_TEST_PROVIDER_CLEARANCE::doTrackDrc( TRACK* aRefSeg, TRACKS::iter
|
||||||
|
|
||||||
drcItem->SetErrorMessage( msg );
|
drcItem->SetErrorMessage( msg );
|
||||||
drcItem->SetItems( aRefSeg, track );
|
drcItem->SetItems( aRefSeg, track );
|
||||||
|
drcItem->SetViolatingRule( rule );
|
||||||
|
|
||||||
ReportWithMarker( drcItem, rule, getLocation( aRefSeg, trackSeg ) );
|
ReportWithMarker( drcItem, getLocation( aRefSeg, trackSeg ) );
|
||||||
|
|
||||||
if( isErrorLimitExceeded( errorCode ) )
|
if( isErrorLimitExceeded( errorCode ) )
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
/***************************************/
|
/***************************************/
|
||||||
/* Phase 3: test DRC with copper zones */
|
/* Phase 3: test DRC with copper zones */
|
||||||
/***************************************/
|
/***************************************/
|
||||||
|
@ -313,7 +602,7 @@ void test::DRC_TEST_PROVIDER_CLEARANCE::doTrackDrc( TRACK* aRefSeg, TRACKS::iter
|
||||||
{
|
{
|
||||||
SEG testSeg( aRefSeg->GetStart(), aRefSeg->GetEnd() );
|
SEG testSeg( aRefSeg->GetStart(), aRefSeg->GetEnd() );
|
||||||
|
|
||||||
for( ZONE_CONTAINER* zone : m_pcb->Zones() )
|
for( ZONE_CONTAINER* zone : m_board->Zones() )
|
||||||
{
|
{
|
||||||
if( zone->GetFilledPolysList().IsEmpty() || zone->GetIsKeepout() )
|
if( zone->GetFilledPolysList().IsEmpty() || zone->GetIsKeepout() )
|
||||||
continue;
|
continue;
|
||||||
|
@ -324,7 +613,9 @@ void test::DRC_TEST_PROVIDER_CLEARANCE::doTrackDrc( TRACK* aRefSeg, TRACKS::iter
|
||||||
if( zone->GetNetCode() && zone->GetNetCode() == aRefSeg->GetNetCode() )
|
if( zone->GetNetCode() && zone->GetNetCode() == aRefSeg->GetNetCode() )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
int minClearance = aRefSeg->GetClearance( zone, &m_clearanceSource );
|
auto rule = m_drcEngine->EvalRulesForItems( test::DRC_RULE_ID_T::DRC_RULE_ID_CLEARANCE, aRefSeg, zone );
|
||||||
|
auto minClearance = rule->GetConstraint().GetValue().Min();
|
||||||
|
|
||||||
int widths = refSegWidth / 2;
|
int widths = refSegWidth / 2;
|
||||||
int center2centerAllowed = minClearance + widths;
|
int center2centerAllowed = minClearance + widths;
|
||||||
SHAPE_POLY_SET* outline = const_cast<SHAPE_POLY_SET*>( &zone->GetFilledPolysList() );
|
SHAPE_POLY_SET* outline = const_cast<SHAPE_POLY_SET*>( &zone->GetFilledPolysList() );
|
||||||
|
@ -340,21 +631,21 @@ void test::DRC_TEST_PROVIDER_CLEARANCE::doTrackDrc( TRACK* aRefSeg, TRACKS::iter
|
||||||
{
|
{
|
||||||
int actual = std::max( 0.0, sqrt( center2center_squared ) - widths );
|
int actual = std::max( 0.0, sqrt( center2center_squared ) - widths );
|
||||||
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TRACK_NEAR_ZONE );
|
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TRACK_NEAR_ZONE );
|
||||||
|
wxString msg;
|
||||||
|
|
||||||
m_msg.Printf( drcItem->GetErrorText() + _( " (%s clearance %s; actual %s)" ),
|
msg.Printf( drcItem->GetErrorText() + _( " (%s clearance %s; actual %s)" ),
|
||||||
m_clearanceSource,
|
rule->GetName(),
|
||||||
MessageTextFromValue( userUnits(), minClearance, true ),
|
MessageTextFromValue( userUnits(), minClearance, true ),
|
||||||
MessageTextFromValue( userUnits(), actual, true ) );
|
MessageTextFromValue( userUnits(), actual, true ) );
|
||||||
|
|
||||||
drcItem->SetErrorMessage( m_msg );
|
drcItem->SetErrorMessage( msg );
|
||||||
drcItem->SetItems( aRefSeg, zone );
|
drcItem->SetItems( aRefSeg, zone );
|
||||||
|
drcItem->SetViolatingRule( rule );
|
||||||
|
|
||||||
MARKER_PCB* marker = new MARKER_PCB( drcItem, GetLocation( aRefSeg, zone ) );
|
ReportWithMarker( drcItem, getLocation( aRefSeg, zone ) );
|
||||||
addMarkerToPcb( aCommit, marker );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
// fixme: board edge clearance to another rule
|
// fixme: board edge clearance to another rule
|
||||||
}
|
}
|
||||||
|
@ -367,7 +658,7 @@ void test::DRC_TEST_PROVIDER_CLEARANCE::testPadClearances( )
|
||||||
|
|
||||||
m_board->GetSortedPadListByXthenYCoord( sortedPads );
|
m_board->GetSortedPadListByXthenYCoord( sortedPads );
|
||||||
|
|
||||||
//Report("testing pads: %d pads\n", sortedPads.size() );
|
ReportAux("Testing %d pads...", sortedPads.size() );
|
||||||
|
|
||||||
for( auto p : sortedPads )
|
for( auto p : sortedPads )
|
||||||
|
|
||||||
|
@ -628,8 +919,9 @@ bool test::DRC_TEST_PROVIDER_CLEARANCE::doPadToPadsDrc( D_PAD* aRefPad, D_PAD**
|
||||||
|
|
||||||
drcItem->SetErrorMessage( msg );
|
drcItem->SetErrorMessage( msg );
|
||||||
drcItem->SetItems( aRefPad, pad );
|
drcItem->SetItems( aRefPad, pad );
|
||||||
|
drcItem->SetViolatingRule( rule );
|
||||||
|
|
||||||
ReportWithMarker( drcItem, rule, aRefPad->GetPosition() );
|
ReportWithMarker( drcItem, aRefPad->GetPosition() );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1040,6 +1332,176 @@ bool test::DRC_TEST_PROVIDER_CLEARANCE::poly2polyDRC( wxPoint* aTref, int aTrefC
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void test::DRC_TEST_PROVIDER_CLEARANCE::testZones()
|
||||||
|
{
|
||||||
|
// Test copper areas for valid netcodes -> fixme, goes to connectivity checks
|
||||||
|
|
||||||
|
std::vector<SHAPE_POLY_SET> smoothed_polys;
|
||||||
|
smoothed_polys.resize( m_board->GetAreaCount() );
|
||||||
|
|
||||||
|
for( int ii = 0; ii < m_board->GetAreaCount(); ii++ )
|
||||||
|
{
|
||||||
|
ZONE_CONTAINER* zone = m_board->GetArea( ii );
|
||||||
|
ZONE_CONTAINER* zoneRef = m_board->GetArea( ii );
|
||||||
|
std::set<VECTOR2I> colinearCorners;
|
||||||
|
|
||||||
|
zoneRef->GetColinearCorners( m_board, colinearCorners );
|
||||||
|
zoneRef->BuildSmoothedPoly( smoothed_polys[ii], &colinearCorners );
|
||||||
|
}
|
||||||
|
|
||||||
|
// iterate through all areas
|
||||||
|
for( int ia = 0; ia < m_board->GetAreaCount(); ia++ )
|
||||||
|
{
|
||||||
|
ZONE_CONTAINER* zoneRef = m_board->GetArea( ia );
|
||||||
|
|
||||||
|
if( !zoneRef->IsOnCopperLayer() )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// If we are testing a single zone, then iterate through all other zones
|
||||||
|
// Otherwise, we have already tested the zone combination
|
||||||
|
for( int ia2 = ia + 1; ia2 < m_board->GetAreaCount(); ia2++ )
|
||||||
|
{
|
||||||
|
ZONE_CONTAINER* zoneToTest = m_board->GetArea( ia2 );
|
||||||
|
|
||||||
|
if( zoneRef == zoneToTest )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// test for same layer
|
||||||
|
if( zoneRef->GetLayer() != zoneToTest->GetLayer() )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Test for same net
|
||||||
|
if( zoneRef->GetNetCode() == zoneToTest->GetNetCode() && zoneRef->GetNetCode() >= 0 )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// test for different priorities
|
||||||
|
if( zoneRef->GetPriority() != zoneToTest->GetPriority() )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// test for different types
|
||||||
|
if( zoneRef->GetIsKeepout() != zoneToTest->GetIsKeepout() )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Examine a candidate zone: compare zoneToTest to zoneRef
|
||||||
|
|
||||||
|
// Get clearance used in zone to zone test.
|
||||||
|
auto rule = m_drcEngine->EvalRulesForItems( test::DRC_RULE_ID_T::DRC_RULE_ID_CLEARANCE, zoneRef, zoneToTest );
|
||||||
|
auto zone2zoneClearance = rule->GetConstraint().GetValue().Min();
|
||||||
|
|
||||||
|
// Keepout areas have no clearance, so set zone2zoneClearance to 1
|
||||||
|
// ( zone2zoneClearance = 0 can create problems in test functions)
|
||||||
|
if( zoneRef->GetIsKeepout() ) // fixme: really?
|
||||||
|
zone2zoneClearance = 1;
|
||||||
|
|
||||||
|
// test for some corners of zoneRef inside zoneToTest
|
||||||
|
for( auto iterator = smoothed_polys[ia].IterateWithHoles(); iterator; iterator++ )
|
||||||
|
{
|
||||||
|
VECTOR2I currentVertex = *iterator;
|
||||||
|
wxPoint pt( currentVertex.x, currentVertex.y );
|
||||||
|
|
||||||
|
if( smoothed_polys[ia2].Contains( currentVertex ) )
|
||||||
|
{
|
||||||
|
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_ZONES_INTERSECT );
|
||||||
|
drcItem->SetItems( zoneRef, zoneToTest );
|
||||||
|
drcItem->SetViolatingRule( rule );
|
||||||
|
|
||||||
|
ReportWithMarker( drcItem, pt );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// test for some corners of zoneToTest inside zoneRef
|
||||||
|
for( auto iterator = smoothed_polys[ia2].IterateWithHoles(); iterator; iterator++ )
|
||||||
|
{
|
||||||
|
VECTOR2I currentVertex = *iterator;
|
||||||
|
wxPoint pt( currentVertex.x, currentVertex.y );
|
||||||
|
|
||||||
|
if( smoothed_polys[ia].Contains( currentVertex ) )
|
||||||
|
{
|
||||||
|
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_ZONES_INTERSECT );
|
||||||
|
drcItem->SetItems( zoneToTest, zoneRef );
|
||||||
|
drcItem->SetViolatingRule( rule );
|
||||||
|
|
||||||
|
ReportWithMarker( drcItem, pt );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iterate through all the segments of refSmoothedPoly
|
||||||
|
std::map<wxPoint, int> conflictPoints;
|
||||||
|
|
||||||
|
for( auto refIt = smoothed_polys[ia].IterateSegmentsWithHoles(); refIt; refIt++ )
|
||||||
|
{
|
||||||
|
// Build ref segment
|
||||||
|
SEG refSegment = *refIt;
|
||||||
|
|
||||||
|
// Iterate through all the segments in smoothed_polys[ia2]
|
||||||
|
for( auto testIt = smoothed_polys[ia2].IterateSegmentsWithHoles(); testIt; testIt++ )
|
||||||
|
{
|
||||||
|
// Build test segment
|
||||||
|
SEG testSegment = *testIt;
|
||||||
|
wxPoint pt;
|
||||||
|
|
||||||
|
int ax1, ay1, ax2, ay2;
|
||||||
|
ax1 = refSegment.A.x;
|
||||||
|
ay1 = refSegment.A.y;
|
||||||
|
ax2 = refSegment.B.x;
|
||||||
|
ay2 = refSegment.B.y;
|
||||||
|
|
||||||
|
int bx1, by1, bx2, by2;
|
||||||
|
bx1 = testSegment.A.x;
|
||||||
|
by1 = testSegment.A.y;
|
||||||
|
bx2 = testSegment.B.x;
|
||||||
|
by2 = testSegment.B.y;
|
||||||
|
|
||||||
|
int d = GetClearanceBetweenSegments( bx1, by1, bx2, by2,
|
||||||
|
0,
|
||||||
|
ax1, ay1, ax2, ay2,
|
||||||
|
0,
|
||||||
|
zone2zoneClearance,
|
||||||
|
&pt.x, &pt.y );
|
||||||
|
|
||||||
|
if( d < zone2zoneClearance )
|
||||||
|
{
|
||||||
|
if( conflictPoints.count( pt ) )
|
||||||
|
conflictPoints[ pt ] = std::min( conflictPoints[ pt ], d );
|
||||||
|
else
|
||||||
|
conflictPoints[ pt ] = d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for( const std::pair<const wxPoint, int>& conflict : conflictPoints )
|
||||||
|
{
|
||||||
|
int actual = conflict.second;
|
||||||
|
DRC_ITEM* drcItem;
|
||||||
|
|
||||||
|
if( actual <= 0 )
|
||||||
|
{
|
||||||
|
drcItem = new DRC_ITEM( DRCE_ZONES_INTERSECT );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
drcItem = new DRC_ITEM( DRCE_ZONES_TOO_CLOSE );
|
||||||
|
wxString msg;
|
||||||
|
|
||||||
|
msg.Printf( drcItem->GetErrorText() + _( " (%s clearance %s; actual %s)" ),
|
||||||
|
/* fixme */"",
|
||||||
|
MessageTextFromValue( userUnits(), zone2zoneClearance, true ),
|
||||||
|
MessageTextFromValue( userUnits(), conflict.second, true ) );
|
||||||
|
|
||||||
|
drcItem->SetErrorMessage( msg );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
drcItem->SetViolatingRule( rule );
|
||||||
|
drcItem->SetItems( zoneRef, zoneToTest );
|
||||||
|
|
||||||
|
ReportWithMarker( drcItem, conflict.first );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
std::set<test::DRC_RULE_ID_T> test::DRC_TEST_PROVIDER_CLEARANCE::GetMatchingRuleIds() const
|
std::set<test::DRC_RULE_ID_T> test::DRC_TEST_PROVIDER_CLEARANCE::GetMatchingRuleIds() const
|
||||||
{
|
{
|
||||||
return { DRC_RULE_ID_T::DRC_RULE_ID_CLEARANCE };
|
return { DRC_RULE_ID_T::DRC_RULE_ID_CLEARANCE };
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -163,7 +163,15 @@ public:
|
||||||
DRC_ENGINE( BOARD* aBoard, BOARD_DESIGN_SETTINGS* aSettings );
|
DRC_ENGINE( BOARD* aBoard, BOARD_DESIGN_SETTINGS* aSettings );
|
||||||
~DRC_ENGINE();
|
~DRC_ENGINE();
|
||||||
|
|
||||||
void SetProgressReporter( PROGRESS_REPORTER* aProgRep );
|
void SetProgressReporter( PROGRESS_REPORTER* aProgRep )
|
||||||
|
{
|
||||||
|
m_progressReporter = aProgRep;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetLogReporter( REPORTER* aReporter )
|
||||||
|
{
|
||||||
|
m_reporter = aReporter;
|
||||||
|
}
|
||||||
|
|
||||||
bool LoadRules( wxFileName aPath );
|
bool LoadRules( wxFileName aPath );
|
||||||
void RunTests();
|
void RunTests();
|
||||||
|
@ -189,6 +197,11 @@ public:
|
||||||
|
|
||||||
bool CompileRules();
|
bool CompileRules();
|
||||||
|
|
||||||
|
void Report( DRC_ITEM* aItem, ::MARKER_PCB *Marker );
|
||||||
|
void ReportProgress( double aProgress );
|
||||||
|
void ReportStage ( const wxString& aStageName, int index, int total );
|
||||||
|
void ReportAux( const wxString& aStr );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
struct RULE_WITH_CONDITIONS
|
struct RULE_WITH_CONDITIONS
|
||||||
|
|
|
@ -34,9 +34,11 @@ namespace test {
|
||||||
#include <class_board.h>
|
#include <class_board.h>
|
||||||
#include <pcb_base_frame.h>
|
#include <pcb_base_frame.h>
|
||||||
|
|
||||||
#include "drc_engine.h"
|
#include <drc_proto/drc_engine.h>
|
||||||
|
|
||||||
class DRC_RULE;
|
class DRC_RULE;
|
||||||
|
class DRC_TEST_PROVIDER;
|
||||||
|
|
||||||
|
|
||||||
class DRC_ITEM : public RC_ITEM
|
class DRC_ITEM : public RC_ITEM
|
||||||
{
|
{
|
||||||
|
@ -45,6 +47,12 @@ public:
|
||||||
|
|
||||||
DRC_ITEM( const wxString& aErrorText ) {} // fixme
|
DRC_ITEM( const wxString& aErrorText ) {} // fixme
|
||||||
|
|
||||||
|
void SetViolatingRule ( test::DRC_RULE *aRule ) { m_violatingRule = aRule; }
|
||||||
|
test::DRC_RULE* GetViolatingRule() const { return m_violatingRule; }
|
||||||
|
|
||||||
|
void SetViolatingTest( test::DRC_TEST_PROVIDER *aProvider ) { m_violatingTest = aProvider; }
|
||||||
|
test::DRC_TEST_PROVIDER* GetViolatingTest() const { return m_violatingTest; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function GetErrorText
|
* Function GetErrorText
|
||||||
* returns the string form of a drc error code.
|
* returns the string form of a drc error code.
|
||||||
|
@ -61,6 +69,8 @@ public:
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
DRC_RULE *m_violatingRule;
|
DRC_RULE *m_violatingRule;
|
||||||
|
DRC_TEST_PROVIDER *m_violatingTest;
|
||||||
|
|
||||||
//std::vector<BOARD_ITEM*> m_violatingObjects;
|
//std::vector<BOARD_ITEM*> m_violatingObjects;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -8,22 +8,29 @@
|
||||||
#include <pcbnew_utils/board_file_utils.h>
|
#include <pcbnew_utils/board_file_utils.h>
|
||||||
#include <drc_proto/drc_engine.h>
|
#include <drc_proto/drc_engine.h>
|
||||||
|
|
||||||
//#include <qa_utils/utility_registry.h>
|
#include <reporter.h>
|
||||||
|
#include <widgets/progress_reporter.h>
|
||||||
|
|
||||||
int main( int argc, char *argv[] )
|
int main( int argc, char *argv[] )
|
||||||
{
|
{
|
||||||
PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance();
|
PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance();
|
||||||
propMgr.Rebuild();
|
propMgr.Rebuild();
|
||||||
|
|
||||||
|
STDOUT_REPORTER msgReporter;
|
||||||
|
|
||||||
auto brd = KI_TEST::ReadBoardFromFileOrStream(argv[1]);
|
auto brd = KI_TEST::ReadBoardFromFileOrStream(argv[1]);
|
||||||
|
|
||||||
test::DRC_ENGINE drcEngine( brd.get(), &brd->GetDesignSettings() );
|
test::DRC_ENGINE drcEngine( brd.get(), &brd->GetDesignSettings() );
|
||||||
|
|
||||||
try {
|
drcEngine.SetLogReporter( &msgReporter );
|
||||||
drcEngine.LoadRules( wxString( argv[2] ) );
|
|
||||||
} catch( PARSE_ERROR& err )
|
try
|
||||||
{
|
{
|
||||||
printf("Exception %s\n", (const char*) err.What().c_str() );
|
drcEngine.LoadRules( wxString( argv[2] ) );
|
||||||
|
}
|
||||||
|
catch( PARSE_ERROR& err )
|
||||||
|
{
|
||||||
|
printf("Can't load DRC rules: %s\n", (const char*) err.What().c_str() );
|
||||||
}
|
}
|
||||||
|
|
||||||
drcEngine.RunTests();
|
drcEngine.RunTests();
|
||||||
|
|
|
@ -43,7 +43,9 @@ namespace test
|
||||||
{
|
{
|
||||||
|
|
||||||
enum class DRC_RULE_ID_T {
|
enum class DRC_RULE_ID_T {
|
||||||
DRC_RULE_ID_CLEARANCE = 0
|
DRC_RULE_ID_CLEARANCE = 0,
|
||||||
|
DRC_RULE_ID_HOLE_CLEARANCE,
|
||||||
|
DRC_RULE_ID_EDGE_CLEARANCE
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class DRC_RULE_SEVERITY_T {
|
enum class DRC_RULE_SEVERITY_T {
|
||||||
|
|
|
@ -117,8 +117,6 @@ test::DRC_RULE_CONDITION* test::DRC_RULES_PARSER::parseCONDITION()
|
||||||
test::DRC_RULE_CONDITION* cond = new test::DRC_RULE_CONDITION();
|
test::DRC_RULE_CONDITION* cond = new test::DRC_RULE_CONDITION();
|
||||||
T token;
|
T token;
|
||||||
|
|
||||||
printf( "parsecondition\n" );
|
|
||||||
|
|
||||||
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
|
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
|
||||||
{
|
{
|
||||||
if( token != T_LEFT )
|
if( token != T_LEFT )
|
||||||
|
@ -126,7 +124,7 @@ test::DRC_RULE_CONDITION* test::DRC_RULES_PARSER::parseCONDITION()
|
||||||
|
|
||||||
token = NextTok();
|
token = NextTok();
|
||||||
|
|
||||||
printf( "Do token xxx %d '%s'\n", token, (const char*) FromUTF8().c_str() );
|
//printf( "Do token xxx %d '%s'\n", token, (const char*) FromUTF8().c_str() );
|
||||||
|
|
||||||
switch( token )
|
switch( token )
|
||||||
{
|
{
|
||||||
|
@ -248,11 +246,11 @@ void test::DRC_RULES_PARSER::parseValueWithUnits( const wxString& aExpr, int& aR
|
||||||
if( !ok )
|
if( !ok )
|
||||||
{
|
{
|
||||||
auto err = evaluator.GetErrorString();
|
auto err = evaluator.GetErrorString();
|
||||||
printf( "eval error: '%s'\n", (const char*) err.c_str() );
|
//printf( "eval error: '%s'\n", (const char*) err.c_str() );
|
||||||
|
// fixme: message
|
||||||
THROW_PARSE_ERROR( err, "", "", 0, 0 );
|
THROW_PARSE_ERROR( err, "", "", 0, 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
aResult = evaluator.Result();
|
aResult = evaluator.Result();
|
||||||
printf("parseValueWithUnits: value %d\n", aResult );
|
//printf("parseValueWithUnits: value %d\n", aResult );
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include <drc_proto/drc_engine.h>
|
#include <drc_proto/drc_engine.h>
|
||||||
|
#include <drc_proto/drc_item.h>
|
||||||
#include <drc_proto/drc_test_provider.h>
|
#include <drc_proto/drc_test_provider.h>
|
||||||
|
|
||||||
test::DRC_TEST_PROVIDER::DRC_TEST_PROVIDER ()
|
test::DRC_TEST_PROVIDER::DRC_TEST_PROVIDER ()
|
||||||
|
@ -19,24 +20,37 @@ bool test::DRC_TEST_PROVIDER::IsEnabled() const
|
||||||
const wxString test::DRC_TEST_PROVIDER::GetName() const { return "<no name test>"; }
|
const wxString test::DRC_TEST_PROVIDER::GetName() const { return "<no name test>"; }
|
||||||
const wxString test::DRC_TEST_PROVIDER::GetDescription() const { return ""; }
|
const wxString test::DRC_TEST_PROVIDER::GetDescription() const { return ""; }
|
||||||
|
|
||||||
void test::DRC_TEST_PROVIDER::Report( DRC_ITEM* item, test::DRC_RULE* violatingRule )
|
void test::DRC_TEST_PROVIDER::Report( DRC_ITEM* item )
|
||||||
{
|
{
|
||||||
|
item->SetViolatingTest( this );
|
||||||
|
m_drcEngine->Report( item, nullptr );
|
||||||
}
|
}
|
||||||
|
|
||||||
void test::DRC_TEST_PROVIDER::ReportWithMarker( DRC_ITEM* item, test::DRC_RULE* violatingRule, wxPoint aMarkerPos )
|
void test::DRC_TEST_PROVIDER::ReportWithMarker( DRC_ITEM* item, wxPoint aMarkerPos )
|
||||||
{
|
{
|
||||||
|
item->SetViolatingTest( this );
|
||||||
|
m_drcEngine->Report( item, nullptr ); // fixme: create marker
|
||||||
}
|
}
|
||||||
|
|
||||||
void test::DRC_TEST_PROVIDER::ReportProgress( double aProgress )
|
void test::DRC_TEST_PROVIDER::ReportProgress( double aProgress )
|
||||||
{
|
{
|
||||||
|
m_drcEngine->ReportProgress( aProgress );
|
||||||
}
|
}
|
||||||
|
|
||||||
void test::DRC_TEST_PROVIDER::ReportStage ( const wxString& aStageName, int index, int total )
|
void test::DRC_TEST_PROVIDER::ReportStage ( const wxString& aStageName, int index, int total )
|
||||||
{
|
{
|
||||||
|
m_drcEngine->ReportStage( aStageName, index, total );
|
||||||
|
ReportAux( aStageName );
|
||||||
|
}
|
||||||
|
|
||||||
|
void test::DRC_TEST_PROVIDER::ReportAux( const wxString fmt, ... )
|
||||||
|
{
|
||||||
|
va_list vargs;
|
||||||
|
va_start( vargs, fmt );
|
||||||
|
wxString str;
|
||||||
|
str.PrintfV( fmt, vargs );
|
||||||
|
va_end( vargs );
|
||||||
|
m_drcEngine->ReportAux( str );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool test::DRC_TEST_PROVIDER::isErrorLimitExceeded( int error_code )
|
bool test::DRC_TEST_PROVIDER::isErrorLimitExceeded( int error_code )
|
||||||
|
|
|
@ -96,8 +96,9 @@ public:
|
||||||
virtual const wxString GetName() const;
|
virtual const wxString GetName() const;
|
||||||
virtual const wxString GetDescription() const;
|
virtual const wxString GetDescription() const;
|
||||||
|
|
||||||
virtual void Report( DRC_ITEM* item, test::DRC_RULE* violatingRule );
|
virtual void ReportAux( const wxString fmt, ... );
|
||||||
virtual void ReportWithMarker( DRC_ITEM* item, test::DRC_RULE* violatingRule, wxPoint aMarkerPos );
|
virtual void Report( DRC_ITEM* item );
|
||||||
|
virtual void ReportWithMarker( DRC_ITEM* item, wxPoint aMarkerPos );
|
||||||
virtual void ReportProgress( double aProgress );
|
virtual void ReportProgress( double aProgress );
|
||||||
virtual void ReportStage ( const wxString& aStageName, int index, int total );
|
virtual void ReportStage ( const wxString& aStageName, int index, int total );
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue