Pick DP coupled segment closest to start item and baseline.
This commit is contained in:
parent
01327b24b4
commit
dd6213051d
|
@ -786,33 +786,25 @@ void PCB_TUNING_PATTERN::EditStart( GENERATOR_TOOL* aTool, BOARD* aBoard, BOARD_
|
||||||
|
|
||||||
|
|
||||||
static PNS::LINKED_ITEM* pickSegment( PNS::ROUTER* aRouter, const VECTOR2I& aWhere, int aLayer,
|
static PNS::LINKED_ITEM* pickSegment( PNS::ROUTER* aRouter, const VECTOR2I& aWhere, int aLayer,
|
||||||
VECTOR2I& aPointOut )
|
VECTOR2I& aPointOut,
|
||||||
|
const SHAPE_LINE_CHAIN& aBaseline = SHAPE_LINE_CHAIN() )
|
||||||
{
|
{
|
||||||
int maxSlopRadius = aRouter->Sizes().Clearance() + aRouter->Sizes().TrackWidth() / 2;
|
int maxSlopRadius = aRouter->Sizes().Clearance() + aRouter->Sizes().TrackWidth() / 2;
|
||||||
|
bool checkBaseline = aBaseline.SegmentCount() > 0;
|
||||||
|
|
||||||
static const int candidateCount = 2;
|
static const int candidateCount = 2;
|
||||||
PNS::LINKED_ITEM* prioritized[candidateCount];
|
PNS::LINKED_ITEM* prioritized[candidateCount];
|
||||||
SEG::ecoord dist[candidateCount];
|
SEG::ecoord dist[candidateCount];
|
||||||
|
SEG::ecoord distBaseline[candidateCount];
|
||||||
VECTOR2I point[candidateCount];
|
VECTOR2I point[candidateCount];
|
||||||
|
|
||||||
for( int i = 0; i < candidateCount; i++ )
|
for( int i = 0; i < candidateCount; i++ )
|
||||||
{
|
{
|
||||||
prioritized[i] = nullptr;
|
prioritized[i] = nullptr;
|
||||||
dist[i] = VECTOR2I::ECOORD_MAX;
|
dist[i] = VECTOR2I::ECOORD_MAX;
|
||||||
|
distBaseline[i] = VECTOR2I::ECOORD_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto haveCandidates =
|
|
||||||
[&]()
|
|
||||||
{
|
|
||||||
for( PNS::ITEM* item : prioritized )
|
|
||||||
{
|
|
||||||
if( item )
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
for( int slopRadius : { 0, maxSlopRadius } )
|
for( int slopRadius : { 0, maxSlopRadius } )
|
||||||
{
|
{
|
||||||
PNS::ITEM_SET candidates = aRouter->QueryHoverItems( aWhere, slopRadius );
|
PNS::ITEM_SET candidates = aRouter->QueryHoverItems( aWhere, slopRadius );
|
||||||
|
@ -837,13 +829,23 @@ static PNS::LINKED_ITEM* pickSegment( PNS::ROUTER* aRouter, const VECTOR2I& aWhe
|
||||||
VECTOR2I nearest = pnsArc->Arc().NearestPoint( aWhere );
|
VECTOR2I nearest = pnsArc->Arc().NearestPoint( aWhere );
|
||||||
SEG::ecoord d0 = ( nearest - aWhere ).SquaredEuclideanNorm();
|
SEG::ecoord d0 = ( nearest - aWhere ).SquaredEuclideanNorm();
|
||||||
|
|
||||||
if( d0 <= dist[1] )
|
if( d0 > dist[1] )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if( checkBaseline )
|
||||||
{
|
{
|
||||||
|
SEG::ecoord dcBaseline = aBaseline.SquaredDistance( pnsArc->Arc().GetArcMid() );
|
||||||
|
|
||||||
|
if( dcBaseline > distBaseline[1] )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
distBaseline[1] = dcBaseline;
|
||||||
|
}
|
||||||
|
|
||||||
prioritized[1] = linked;
|
prioritized[1] = linked;
|
||||||
dist[1] = d0;
|
dist[1] = d0;
|
||||||
point[1] = nearest;
|
point[1] = nearest;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else if( item->Kind() & PNS::ITEM::SEGMENT_T )
|
else if( item->Kind() & PNS::ITEM::SEGMENT_T )
|
||||||
{
|
{
|
||||||
PNS::SEGMENT* segm = static_cast<PNS::SEGMENT*>( item );
|
PNS::SEGMENT* segm = static_cast<PNS::SEGMENT*>( item );
|
||||||
|
@ -851,8 +853,19 @@ static PNS::LINKED_ITEM* pickSegment( PNS::ROUTER* aRouter, const VECTOR2I& aWhe
|
||||||
VECTOR2I nearest = segm->CLine().NearestPoint( aWhere, false );
|
VECTOR2I nearest = segm->CLine().NearestPoint( aWhere, false );
|
||||||
SEG::ecoord dd = ( aWhere - nearest ).SquaredEuclideanNorm();
|
SEG::ecoord dd = ( aWhere - nearest ).SquaredEuclideanNorm();
|
||||||
|
|
||||||
if( dd <= dist[1] )
|
if( dd > dist[1] )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if( checkBaseline )
|
||||||
{
|
{
|
||||||
|
SEG::ecoord dcBaseline = aBaseline.SquaredDistance( segm->Shape()->Centre() );
|
||||||
|
|
||||||
|
if( dcBaseline > distBaseline[1] )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
distBaseline[1] = dcBaseline;
|
||||||
|
}
|
||||||
|
|
||||||
prioritized[1] = segm;
|
prioritized[1] = segm;
|
||||||
dist[1] = dd;
|
dist[1] = dd;
|
||||||
point[1] = nearest;
|
point[1] = nearest;
|
||||||
|
@ -860,10 +873,6 @@ static PNS::LINKED_ITEM* pickSegment( PNS::ROUTER* aRouter, const VECTOR2I& aWhe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( haveCandidates() )
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
PNS::LINKED_ITEM* rv = nullptr;
|
PNS::LINKED_ITEM* rv = nullptr;
|
||||||
|
|
||||||
for( int i = 0; i < candidateCount; i++ )
|
for( int i = 0; i < candidateCount; i++ )
|
||||||
|
@ -1306,8 +1315,10 @@ bool PCB_TUNING_PATTERN::Update( GENERATOR_TOOL* aTool, BOARD* aBoard, BOARD_COM
|
||||||
// Snap points
|
// Snap points
|
||||||
VECTOR2I startSnapPoint, endSnapPoint;
|
VECTOR2I startSnapPoint, endSnapPoint;
|
||||||
|
|
||||||
PNS::LINKED_ITEM* startItem = pickSegment( router, m_origin, layer, startSnapPoint );
|
wxCHECK( m_baseLine, false );
|
||||||
PNS::LINKED_ITEM* endItem = pickSegment( router, m_end, layer, endSnapPoint );
|
|
||||||
|
PNS::LINKED_ITEM* startItem = pickSegment( router, m_origin, layer, startSnapPoint, *m_baseLine);
|
||||||
|
PNS::LINKED_ITEM* endItem = pickSegment( router, m_end, layer, endSnapPoint, *m_baseLine );
|
||||||
|
|
||||||
wxASSERT( startItem );
|
wxASSERT( startItem );
|
||||||
wxASSERT( endItem );
|
wxASSERT( endItem );
|
||||||
|
|
|
@ -500,8 +500,10 @@ bool TOPOLOGY::AssembleDiffPair( ITEM* aStart, DIFF_PAIR& aPair )
|
||||||
LINKED_ITEM* refItem = nullptr;
|
LINKED_ITEM* refItem = nullptr;
|
||||||
LINKED_ITEM* coupledItem = nullptr;
|
LINKED_ITEM* coupledItem = nullptr;
|
||||||
SEG::ecoord minDist_sq = std::numeric_limits<SEG::ecoord>::max();
|
SEG::ecoord minDist_sq = std::numeric_limits<SEG::ecoord>::max();
|
||||||
|
SEG::ecoord minDistTarget_sq = std::numeric_limits<SEG::ecoord>::max();
|
||||||
|
VECTOR2I targetPoint = aStart->Shape()->Centre();
|
||||||
|
|
||||||
for( ITEM* p_item : pItems )
|
auto findNItem = [&]( ITEM* p_item )
|
||||||
{
|
{
|
||||||
for( ITEM* n_item : nItems )
|
for( ITEM* n_item : nItems )
|
||||||
{
|
{
|
||||||
|
@ -512,8 +514,8 @@ bool TOPOLOGY::AssembleDiffPair( ITEM* aStart, DIFF_PAIR& aPair )
|
||||||
|
|
||||||
if( p_item->Kind() == ITEM::SEGMENT_T )
|
if( p_item->Kind() == ITEM::SEGMENT_T )
|
||||||
{
|
{
|
||||||
SEGMENT* p_seg = static_cast<SEGMENT*>( p_item );
|
const SEGMENT* p_seg = static_cast<const SEGMENT*>( p_item );
|
||||||
SEGMENT* n_seg = static_cast<SEGMENT*>( n_item );
|
const SEGMENT* n_seg = static_cast<const SEGMENT*>( n_item );
|
||||||
|
|
||||||
if( n_seg->Width() != p_seg->Width() )
|
if( n_seg->Width() != p_seg->Width() )
|
||||||
continue;
|
continue;
|
||||||
|
@ -530,8 +532,8 @@ bool TOPOLOGY::AssembleDiffPair( ITEM* aStart, DIFF_PAIR& aPair )
|
||||||
}
|
}
|
||||||
else if( p_item->Kind() == ITEM::ARC_T )
|
else if( p_item->Kind() == ITEM::ARC_T )
|
||||||
{
|
{
|
||||||
ARC* p_arc = static_cast<ARC*>( p_item );
|
const ARC* p_arc = static_cast<const ARC*>( p_item );
|
||||||
ARC* n_arc = static_cast<ARC*>( n_item );
|
const ARC* n_arc = static_cast<const ARC*>( n_item );
|
||||||
|
|
||||||
if( n_arc->Width() != p_arc->Width() )
|
if( n_arc->Width() != p_arc->Width() )
|
||||||
continue;
|
continue;
|
||||||
|
@ -545,14 +547,45 @@ bool TOPOLOGY::AssembleDiffPair( ITEM* aStart, DIFF_PAIR& aPair )
|
||||||
dist_sq = SEG::Square( p_arc->CArc().GetRadius() - n_arc->CArc().GetRadius() );
|
dist_sq = SEG::Square( p_arc->CArc().GetRadius() - n_arc->CArc().GetRadius() );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( dist_sq < minDist_sq )
|
if( dist_sq <= minDist_sq )
|
||||||
{
|
{
|
||||||
|
SEG::ecoord distTarget_sq = n_item->Shape()->SquaredDistance( targetPoint );
|
||||||
|
if( distTarget_sq < minDistTarget_sq )
|
||||||
|
{
|
||||||
|
minDistTarget_sq = distTarget_sq;
|
||||||
minDist_sq = dist_sq;
|
minDist_sq = dist_sq;
|
||||||
|
|
||||||
refItem = static_cast<LINKED_ITEM*>( p_item );
|
refItem = static_cast<LINKED_ITEM*>( p_item );
|
||||||
coupledItem = static_cast<LINKED_ITEM*>( n_item );
|
coupledItem = static_cast<LINKED_ITEM*>( n_item );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
findNItem( startItem );
|
||||||
|
|
||||||
|
if( !coupledItem )
|
||||||
|
{
|
||||||
|
LINKED_ITEM* linked = static_cast<LINKED_ITEM*>( startItem );
|
||||||
|
std::set<ITEM*> linksToTest;
|
||||||
|
|
||||||
|
for( int i = 0; i < linked->AnchorCount(); i++ )
|
||||||
|
{
|
||||||
|
const JOINT* jt = m_world->FindJoint( linked->Anchor( i ), linked );
|
||||||
|
|
||||||
|
if( !jt )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for( ITEM* link : jt->LinkList() )
|
||||||
|
{
|
||||||
|
if( link != linked )
|
||||||
|
linksToTest.emplace( link );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for( ITEM* link : linksToTest )
|
||||||
|
findNItem( link );
|
||||||
|
}
|
||||||
|
|
||||||
if( !coupledItem )
|
if( !coupledItem )
|
||||||
return false;
|
return false;
|
||||||
|
|
Loading…
Reference in New Issue