drc: more robust segment pair detection, still issues with approximated arc corners though...

This commit is contained in:
Tomasz Wlostowski 2020-10-06 11:24:19 +02:00
parent 719363fa4a
commit 8a7fc7e970
3 changed files with 81 additions and 15 deletions

View File

@ -46,6 +46,7 @@ class REPORTER;
namespace KIGFX
{
class WS_PROXY_VIEW_ITEM;
class VIEW_OVERLAY;
};
void drcPrintDebugMessage( int level, const wxString& msg, const char *function, int line );
@ -96,6 +97,10 @@ public:
void SetWorksheet( KIGFX::WS_PROXY_VIEW_ITEM* aWorksheet ) { m_worksheet = aWorksheet; }
KIGFX::WS_PROXY_VIEW_ITEM* GetWorksheet() const { return m_worksheet; }
void SetDebugOverlay( std::shared_ptr<KIGFX::VIEW_OVERLAY> aOverlay ) { m_debugOverlay = aOverlay; }
std::shared_ptr<KIGFX::VIEW_OVERLAY> GetDebugOverlay() const { return m_debugOverlay; }
/**
* Set an optional DRC violation handler (receives DRC_ITEMs and positions).
*/
@ -224,6 +229,7 @@ protected:
PROGRESS_REPORTER* m_progressReporter;
wxString m_msg; // Allocating strings gets expensive enough to want to avoid it
std::shared_ptr<KIGFX::VIEW_OVERLAY> m_debugOverlay;
};
#endif // DRC_H

View File

@ -239,8 +239,8 @@ public:
bool CheckColliding( SHAPE* aRefShape,
PCB_LAYER_ID aTargetLayer,
int aClearance = 0
)
int aClearance = 0,
std::function<bool( BOARD_ITEM*)> aFilter = nullptr )
{
BOX2I box = aRefShape->BBox();
box.Inflate( aClearance );
@ -254,6 +254,10 @@ public:
{
int actual;
// keep searching
if( aFilter && ! aFilter( aItem->parent ) )
return true;
bool colliding = aRefShape->Collide( aItem->shape, aClearance, &actual );
if( colliding )

View File

@ -256,6 +256,7 @@ struct DIFF_PAIR_KEY
SEG coupledN, coupledP;
TRACK* parentN, *parentP;
int computedGap;
PCB_LAYER_ID layer;
bool couplingOK;
};
@ -270,10 +271,11 @@ struct DIFF_PAIR_KEY
static void extractDiffPairCoupledItems( DIFF_PAIR_ITEMS& aDp, DRC_RTREE& aTree )
{
for( BOARD_CONNECTED_ITEM* itemP : aDp.itemsP )
{
auto sp = dyn_cast<TRACK*>( itemP );
OPT<DIFF_PAIR_COUPLED_SEGMENTS> bestCoupled;
int bestGap = std::numeric_limits<int>::max();
if(!sp)
continue;
@ -298,28 +300,61 @@ static void extractDiffPairCoupledItems( DIFF_PAIR_ITEMS& aDp, DRC_RTREE& aTree
if( coupled )
{
SHAPE_SEGMENT checkSegStart( cpair.coupledP.A, cpair.coupledN.A );
SHAPE_SEGMENT checkSegEnd( cpair.coupledP.B, cpair.coupledN.B );
cpair.parentP = sp;
cpair.parentN = sn;
cpair.layer = sp->GetLayer();
int gap = (cpair.coupledP.A - cpair.coupledN.A).EuclideanNorm();
if( gap < bestGap )
{
bestGap = gap;
bestCoupled = cpair;
}
}
}
}
if( bestCoupled )
{
printf("Best-gap %d\n", bestGap );
auto excludeSelf = [&] ( BOARD_ITEM *aItem )
{
if( aItem == bestCoupled->parentN || aItem == bestCoupled->parentP )
{
return false;
}
if( aItem->Type() == PCB_TRACE_T || aItem->Type() == PCB_VIA_T )
{
auto bci = static_cast<BOARD_CONNECTED_ITEM*>( aItem );
if( bci->GetNetCode() == bestCoupled->parentN->GetNetCode()
|| bci->GetNetCode() == bestCoupled->parentP->GetNetCode() )
return false;
}
return true;
};
SHAPE_SEGMENT checkSegStart( bestCoupled->coupledP.A, bestCoupled->coupledN.A );
SHAPE_SEGMENT checkSegEnd( bestCoupled->coupledP.B, bestCoupled->coupledN.B );
// check if there's anyting in between the segments suspected to be coupled. If
// there's nothing, assume they are really coupled.
if( !aTree.CheckColliding( &checkSegStart, sp->GetLayer() )
&& !aTree.CheckColliding( &checkSegEnd, sp->GetLayer() ) )
if( !aTree.CheckColliding( &checkSegStart, sp->GetLayer(), 0, excludeSelf )
&& !aTree.CheckColliding( &checkSegEnd, sp->GetLayer(), 0, excludeSelf ) )
{
aDp.coupled.push_back( *bestCoupled );
}
cpair.parentP = sp;
cpair.parentN = sn;
aDp.coupled.push_back( cpair );
}
}
}
}
}
}
bool test::DRC_TEST_PROVIDER_DIFF_PAIR_COUPLING::Run()
{
m_board = m_drcEngine->GetBoard();
@ -338,6 +373,8 @@ bool test::DRC_TEST_PROVIDER_DIFF_PAIR_COUPLING::Run()
if( !isNetADiffPair( m_board, refNet, key.netP, key.netN ) ) // not our business
return true;
drc_dbg(10, "eval dp %p\n", item );
const DRC_CONSTRAINT_TYPE_T constraintsToCheck[] = {
DRC_CONSTRAINT_TYPE_DIFF_PAIR_GAP,
DRC_CONSTRAINT_TYPE_DIFF_PAIR_MAX_UNCOUPLED
@ -350,6 +387,8 @@ bool test::DRC_TEST_PROVIDER_DIFF_PAIR_COUPLING::Run()
if( constraint.IsNull() )
continue;
drc_dbg(10, "cns %d item %p\n", constraintsToCheck[i], item );
key.parentRule = constraint.GetParentRule();
if( refNet == key.netN )
@ -366,6 +405,8 @@ bool test::DRC_TEST_PROVIDER_DIFF_PAIR_COUPLING::Run()
forEachGeometryItem( { PCB_TRACE_T, PCB_VIA_T, PCB_ARC_T },
LSET::AllCuMask(), evaluateDpConstraints );
drc_dbg(10, "dp rule matches %d\n", dpRuleMatches.size() );
DRC_RTREE copperTree;
@ -430,6 +471,21 @@ bool test::DRC_TEST_PROVIDER_DIFF_PAIR_COUPLING::Run()
cpair.computedGap = gap;
auto overlay = m_drcEngine->GetDebugOverlay();
printf("Overlay %p\n", overlay.get () );
if( overlay )
{
overlay->SetIsFill(false);
overlay->SetIsStroke(true);
overlay->SetStrokeColor( RED );
overlay->SetLineWidth( 100000 );
overlay->Line( cpair.coupledP );
overlay->SetStrokeColor( BLUE );
overlay->Line( cpair.coupledN );
}
drc_dbg(10, " len %d gap %d l %d\n", length, gap, cpair.parentP->GetLayer() );
if( gapConstraint )