KiCad PCB EDA Suite
drc_test_provider_diff_pair_coupling.cpp File Reference
#include <common.h>
#include <board.h>
#include <track.h>
#include <drc/drc_engine.h>
#include <drc/drc_item.h>
#include <drc/drc_rule.h>
#include <drc/drc_test_provider.h>
#include <drc/drc_length_report.h>
#include <drc/drc_rtree.h>
#include <geometry/shape_segment.h>
#include <connectivity/connectivity_data.h>
#include <connectivity/from_to_cache.h>

Go to the source code of this file.

Classes

class  test::DRC_TEST_PROVIDER_DIFF_PAIR_COUPLING
 
struct  DIFF_PAIR_KEY
 
struct  DIFF_PAIR_COUPLED_SEGMENTS
 
struct  DIFF_PAIR_ITEMS
 

Namespaces

 test
 
 detail
 

Functions

static bool commonParallelProjection (SEG p, SEG n, SEG &pClip, SEG &nClip)
 
static void extractDiffPairCoupledItems (DIFF_PAIR_ITEMS &aDp, DRC_RTREE &aTree)
 

Variables

static DRC_REGISTER_TEST_PROVIDER< test::DRC_TEST_PROVIDER_DIFF_PAIR_COUPLINGdetail::dummy
 

Function Documentation

◆ commonParallelProjection()

static bool commonParallelProjection ( SEG  p,
SEG  n,
SEG pClip,
SEG nClip 
)
static

Definition at line 91 of file drc_test_provider_diff_pair_coupling.cpp.

92 {
93  SEG n_proj_p( p.LineProject( n.A ), p.LineProject( n.B ) );
94 
95  int64_t t_a = 0;
96  int64_t t_b = p.TCoef( p.B );
97 
98  int64_t tproj_a = p.TCoef( n_proj_p.A );
99  int64_t tproj_b = p.TCoef( n_proj_p.B );
100 
101  if( t_b < t_a )
102  std::swap( t_b, t_a );
103 
104  if( tproj_b < tproj_a )
105  std::swap( tproj_b, tproj_a );
106 
107  if( t_b <= tproj_a )
108  return false;
109 
110  if( t_a >= tproj_b )
111  return false;
112 
113  int64_t t[4] = { 0, p.TCoef( p.B ), p.TCoef( n_proj_p.A ), p.TCoef( n_proj_p.B ) };
114  std::vector<int64_t> tv( t, t + 4 );
115  std::sort( tv.begin(), tv.end() ); // fixme: awful and disgusting way of finding 2 midpoints
116 
117  int64_t pLenSq = p.SquaredLength();
118 
119  VECTOR2I dp = p.B - p.A;
120  pClip.A.x = p.A.x + rescale( (int64_t)dp.x, tv[1], pLenSq );
121  pClip.A.y = p.A.y + rescale( (int64_t)dp.y, tv[1], pLenSq );
122 
123  pClip.B.x = p.A.x + rescale( (int64_t)dp.x, tv[2], pLenSq );
124  pClip.B.y = p.A.y + rescale( (int64_t)dp.y, tv[2], pLenSq );
125 
126  nClip.A = n.LineProject( pClip.A );
127  nClip.B = n.LineProject( pClip.B );
128 
129  return true;
130 }
ecoord SquaredLength() const
Definition: seg.h:360
VECTOR2I LineProject(const VECTOR2I &aP) const
Compute the perpendicular projection point of aP on a line passing through ends of the segment.
Definition: seg.h:404
ecoord TCoef(const VECTOR2I &aP) const
Definition: seg.h:431
Definition: seg.h:41
VECTOR2I A
Definition: seg.h:49
T rescale(T aNumerator, T aValue, T aDenominator)
Function rescale()
Definition: util.h:95
VECTOR2I B
Definition: seg.h:50

References SEG::A, SEG::B, SEG::LineProject(), rescale(), SEG::SquaredLength(), SEG::TCoef(), VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by extractDiffPairCoupledItems().

◆ extractDiffPairCoupledItems()

static void extractDiffPairCoupledItems ( DIFF_PAIR_ITEMS aDp,
DRC_RTREE aTree 
)
static

Definition at line 188 of file drc_test_provider_diff_pair_coupling.cpp.

189 {
190  for( BOARD_CONNECTED_ITEM* itemP : aDp.itemsP )
191  {
192  TRACK* sp = dyn_cast<TRACK*>( itemP );
194  int bestGap = std::numeric_limits<int>::max();
195 
196  if(!sp)
197  continue;
198 
199  for ( BOARD_CONNECTED_ITEM* itemN : aDp.itemsN )
200  {
201  auto sn = dyn_cast<TRACK*> ( itemN );
202 
203  if(!sn)
204  continue;
205 
206  if( ( sn->GetLayerSet() & sp->GetLayerSet() ).none() )
207  continue;
208 
209  SEG ssp ( sp->GetStart(), sp->GetEnd() );
210  SEG ssn ( sn->GetStart(), sn->GetEnd() );
211 
212  if( ssp.ApproxParallel(ssn) )
213  {
215  bool coupled = commonParallelProjection( ssp, ssn, cpair.coupledP, cpair.coupledN );
216 
217  if( coupled )
218  {
219  cpair.parentP = sp;
220  cpair.parentN = sn;
221  cpair.layer = sp->GetLayer();
222 
223  int gap = (cpair.coupledP.A - cpair.coupledN.A).EuclideanNorm();
224  if( gap < bestGap )
225  {
226  bestGap = gap;
227  bestCoupled = cpair;
228  }
229  }
230 
231  }
232  }
233 
234  if( bestCoupled )
235  {
236  auto excludeSelf =
237  [&] ( BOARD_ITEM *aItem )
238  {
239  if( aItem == bestCoupled->parentN || aItem == bestCoupled->parentP )
240  {
241  return false;
242  }
243 
244  if( aItem->Type() == PCB_TRACE_T || aItem->Type() == PCB_VIA_T )
245  {
246  auto bci = static_cast<BOARD_CONNECTED_ITEM*>( aItem );
247 
248  if( bci->GetNetCode() == bestCoupled->parentN->GetNetCode()
249  || bci->GetNetCode() == bestCoupled->parentP->GetNetCode() )
250  return false;
251  }
252 
253  return true;
254  };
255 
256  SHAPE_SEGMENT checkSegStart( bestCoupled->coupledP.A, bestCoupled->coupledN.A );
257  SHAPE_SEGMENT checkSegEnd( bestCoupled->coupledP.B, bestCoupled->coupledN.B );
258 
259  // check if there's anyting in between the segments suspected to be coupled. If
260  // there's nothing, assume they are really coupled.
261 
262  if( !aTree.CheckColliding( &checkSegStart, sp->GetLayer(), 0, excludeSelf )
263  && !aTree.CheckColliding( &checkSegEnd, sp->GetLayer(), 0, excludeSelf ) )
264  {
265  aDp.coupled.push_back( *bestCoupled );
266  }
267  }
268  }
269 }
double EuclideanNorm(const wxPoint &vector)
Euclidean norm of a 2D vector.
Definition: trigo.h:148
static bool commonParallelProjection(SEG p, SEG n, SEG &pClip, SEG &nClip)
std::set< BOARD_CONNECTED_ITEM * > itemsN
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:82
const wxPoint & GetStart() const
Definition: track.h:116
std::set< BOARD_CONNECTED_ITEM * > itemsP
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
class TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:95
bool CheckColliding(SHAPE *aRefShape, PCB_LAYER_ID aTargetLayer, int aClearance=0, std::function< bool(BOARD_ITEM *)> aFilter=nullptr) const
Definition: drc_rtree.h:153
std::vector< DIFF_PAIR_COUPLED_SEGMENTS > coupled
Definition: seg.h:41
VECTOR2I A
Definition: seg.h:49
const wxPoint & GetEnd() const
Definition: track.h:113
boost::optional< T > OPT
Definition: optional.h:7
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:96
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition: board_item.h:173
Definition: track.h:83
virtual LSET GetLayerSet() const
Return a std::bitset of all layers on which the item physically resides.
Definition: board_item.h:178

References SEG::A, DRC_RTREE::CheckColliding(), commonParallelProjection(), DIFF_PAIR_ITEMS::coupled, DIFF_PAIR_COUPLED_SEGMENTS::coupledN, DIFF_PAIR_COUPLED_SEGMENTS::coupledP, EuclideanNorm(), TRACK::GetEnd(), BOARD_ITEM::GetLayer(), BOARD_ITEM::GetLayerSet(), TRACK::GetStart(), DIFF_PAIR_ITEMS::itemsN, DIFF_PAIR_ITEMS::itemsP, DIFF_PAIR_COUPLED_SEGMENTS::layer, DIFF_PAIR_COUPLED_SEGMENTS::parentN, DIFF_PAIR_COUPLED_SEGMENTS::parentP, PCB_TRACE_T, and PCB_VIA_T.

Referenced by test::DRC_TEST_PROVIDER_DIFF_PAIR_COUPLING::Run().