drc: more robust segment pair detection, still issues with approximated arc corners though...
This commit is contained in:
parent
719363fa4a
commit
8a7fc7e970
|
@ -46,6 +46,7 @@ class REPORTER;
|
||||||
namespace KIGFX
|
namespace KIGFX
|
||||||
{
|
{
|
||||||
class WS_PROXY_VIEW_ITEM;
|
class WS_PROXY_VIEW_ITEM;
|
||||||
|
class VIEW_OVERLAY;
|
||||||
};
|
};
|
||||||
|
|
||||||
void drcPrintDebugMessage( int level, const wxString& msg, const char *function, int line );
|
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; }
|
void SetWorksheet( KIGFX::WS_PROXY_VIEW_ITEM* aWorksheet ) { m_worksheet = aWorksheet; }
|
||||||
KIGFX::WS_PROXY_VIEW_ITEM* GetWorksheet() const { return m_worksheet; }
|
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).
|
* Set an optional DRC violation handler (receives DRC_ITEMs and positions).
|
||||||
*/
|
*/
|
||||||
|
@ -224,6 +229,7 @@ protected:
|
||||||
PROGRESS_REPORTER* m_progressReporter;
|
PROGRESS_REPORTER* m_progressReporter;
|
||||||
|
|
||||||
wxString m_msg; // Allocating strings gets expensive enough to want to avoid it
|
wxString m_msg; // Allocating strings gets expensive enough to want to avoid it
|
||||||
|
std::shared_ptr<KIGFX::VIEW_OVERLAY> m_debugOverlay;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // DRC_H
|
#endif // DRC_H
|
||||||
|
|
|
@ -239,8 +239,8 @@ public:
|
||||||
|
|
||||||
bool CheckColliding( SHAPE* aRefShape,
|
bool CheckColliding( SHAPE* aRefShape,
|
||||||
PCB_LAYER_ID aTargetLayer,
|
PCB_LAYER_ID aTargetLayer,
|
||||||
int aClearance = 0
|
int aClearance = 0,
|
||||||
)
|
std::function<bool( BOARD_ITEM*)> aFilter = nullptr )
|
||||||
{
|
{
|
||||||
BOX2I box = aRefShape->BBox();
|
BOX2I box = aRefShape->BBox();
|
||||||
box.Inflate( aClearance );
|
box.Inflate( aClearance );
|
||||||
|
@ -254,6 +254,10 @@ public:
|
||||||
{
|
{
|
||||||
int actual;
|
int actual;
|
||||||
|
|
||||||
|
// keep searching
|
||||||
|
if( aFilter && ! aFilter( aItem->parent ) )
|
||||||
|
return true;
|
||||||
|
|
||||||
bool colliding = aRefShape->Collide( aItem->shape, aClearance, &actual );
|
bool colliding = aRefShape->Collide( aItem->shape, aClearance, &actual );
|
||||||
|
|
||||||
if( colliding )
|
if( colliding )
|
||||||
|
|
|
@ -256,6 +256,7 @@ struct DIFF_PAIR_KEY
|
||||||
SEG coupledN, coupledP;
|
SEG coupledN, coupledP;
|
||||||
TRACK* parentN, *parentP;
|
TRACK* parentN, *parentP;
|
||||||
int computedGap;
|
int computedGap;
|
||||||
|
PCB_LAYER_ID layer;
|
||||||
bool couplingOK;
|
bool couplingOK;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -270,10 +271,11 @@ struct DIFF_PAIR_KEY
|
||||||
|
|
||||||
static void extractDiffPairCoupledItems( DIFF_PAIR_ITEMS& aDp, DRC_RTREE& aTree )
|
static void extractDiffPairCoupledItems( DIFF_PAIR_ITEMS& aDp, DRC_RTREE& aTree )
|
||||||
{
|
{
|
||||||
|
|
||||||
for( BOARD_CONNECTED_ITEM* itemP : aDp.itemsP )
|
for( BOARD_CONNECTED_ITEM* itemP : aDp.itemsP )
|
||||||
{
|
{
|
||||||
auto sp = dyn_cast<TRACK*>( itemP );
|
auto sp = dyn_cast<TRACK*>( itemP );
|
||||||
|
OPT<DIFF_PAIR_COUPLED_SEGMENTS> bestCoupled;
|
||||||
|
int bestGap = std::numeric_limits<int>::max();
|
||||||
|
|
||||||
if(!sp)
|
if(!sp)
|
||||||
continue;
|
continue;
|
||||||
|
@ -298,28 +300,61 @@ static void extractDiffPairCoupledItems( DIFF_PAIR_ITEMS& aDp, DRC_RTREE& aTree
|
||||||
|
|
||||||
if( coupled )
|
if( coupled )
|
||||||
{
|
{
|
||||||
SHAPE_SEGMENT checkSegStart( cpair.coupledP.A, cpair.coupledN.A );
|
cpair.parentP = sp;
|
||||||
SHAPE_SEGMENT checkSegEnd( cpair.coupledP.B, cpair.coupledN.B );
|
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
|
// check if there's anyting in between the segments suspected to be coupled. If
|
||||||
// there's nothing, assume they are really coupled.
|
// there's nothing, assume they are really coupled.
|
||||||
|
|
||||||
if( !aTree.CheckColliding( &checkSegStart, sp->GetLayer() )
|
if( !aTree.CheckColliding( &checkSegStart, sp->GetLayer(), 0, excludeSelf )
|
||||||
&& !aTree.CheckColliding( &checkSegEnd, sp->GetLayer() ) )
|
&& !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()
|
bool test::DRC_TEST_PROVIDER_DIFF_PAIR_COUPLING::Run()
|
||||||
{
|
{
|
||||||
m_board = m_drcEngine->GetBoard();
|
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
|
if( !isNetADiffPair( m_board, refNet, key.netP, key.netN ) ) // not our business
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
drc_dbg(10, "eval dp %p\n", item );
|
||||||
|
|
||||||
const DRC_CONSTRAINT_TYPE_T constraintsToCheck[] = {
|
const DRC_CONSTRAINT_TYPE_T constraintsToCheck[] = {
|
||||||
DRC_CONSTRAINT_TYPE_DIFF_PAIR_GAP,
|
DRC_CONSTRAINT_TYPE_DIFF_PAIR_GAP,
|
||||||
DRC_CONSTRAINT_TYPE_DIFF_PAIR_MAX_UNCOUPLED
|
DRC_CONSTRAINT_TYPE_DIFF_PAIR_MAX_UNCOUPLED
|
||||||
|
@ -350,6 +387,8 @@ bool test::DRC_TEST_PROVIDER_DIFF_PAIR_COUPLING::Run()
|
||||||
if( constraint.IsNull() )
|
if( constraint.IsNull() )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
drc_dbg(10, "cns %d item %p\n", constraintsToCheck[i], item );
|
||||||
|
|
||||||
key.parentRule = constraint.GetParentRule();
|
key.parentRule = constraint.GetParentRule();
|
||||||
|
|
||||||
if( refNet == key.netN )
|
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 },
|
forEachGeometryItem( { PCB_TRACE_T, PCB_VIA_T, PCB_ARC_T },
|
||||||
LSET::AllCuMask(), evaluateDpConstraints );
|
LSET::AllCuMask(), evaluateDpConstraints );
|
||||||
|
|
||||||
|
drc_dbg(10, "dp rule matches %d\n", dpRuleMatches.size() );
|
||||||
|
|
||||||
|
|
||||||
DRC_RTREE copperTree;
|
DRC_RTREE copperTree;
|
||||||
|
|
||||||
|
@ -430,6 +471,21 @@ bool test::DRC_TEST_PROVIDER_DIFF_PAIR_COUPLING::Run()
|
||||||
|
|
||||||
cpair.computedGap = gap;
|
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() );
|
drc_dbg(10, " len %d gap %d l %d\n", length, gap, cpair.parentP->GetLayer() );
|
||||||
|
|
||||||
if( gapConstraint )
|
if( gapConstraint )
|
||||||
|
|
Loading…
Reference in New Issue