Adjust dashed-box and edit-point locations to be outside meanders.

This commit is contained in:
Jeff Young 2023-10-16 13:12:17 +01:00
parent a52ee04fc7
commit 64cc8dd6aa
5 changed files with 96 additions and 41 deletions

View File

@ -252,6 +252,9 @@ protected:
std::optional<SHAPE_LINE_CHAIN> m_baseLine; std::optional<SHAPE_LINE_CHAIN> m_baseLine;
std::optional<SHAPE_LINE_CHAIN> m_baseLineCoupled; std::optional<SHAPE_LINE_CHAIN> m_baseLineCoupled;
int m_trackWidth;
int m_diffPairGap;
bool m_singleSide; bool m_singleSide;
bool m_rounded; bool m_rounded;
@ -366,6 +369,8 @@ static std::string sideToString( const PNS::MEANDER_SIDE aValue )
PCB_GENERATOR_MEANDERS::PCB_GENERATOR_MEANDERS( BOARD_ITEM* aParent, PCB_LAYER_ID aLayer, PCB_GENERATOR_MEANDERS::PCB_GENERATOR_MEANDERS( BOARD_ITEM* aParent, PCB_LAYER_ID aLayer,
LENGTH_TUNING_MODE aMode ) : LENGTH_TUNING_MODE aMode ) :
PCB_GENERATOR( aParent, aLayer ), PCB_GENERATOR( aParent, aLayer ),
m_trackWidth( 0 ),
m_diffPairGap( 0 ),
m_singleSide( false ), m_singleSide( false ),
m_rounded( true ), m_rounded( true ),
m_tuningMode( aMode ), m_tuningMode( aMode ),
@ -386,11 +391,11 @@ PCB_GENERATOR_MEANDERS::PCB_GENERATOR_MEANDERS( BOARD_ITEM* aParent, PCB_LAYER_I
} }
static NETINFO_ITEM* snapToNearestTrackPoint( VECTOR2I& aP, BOARD* aBoard, NETINFO_ITEM* aNet ) static VECTOR2I snapToNearestTrack( const VECTOR2I& aP, BOARD* aBoard, NETINFO_ITEM* aNet,
PCB_TRACK** aNearestTrack )
{ {
SEG::ecoord minDistSq = VECTOR2I::ECOORD_MAX; SEG::ecoord minDist_sq = VECTOR2I::ECOORD_MAX;
VECTOR2I closestPt = aP; VECTOR2I closestPt = aP;
NETINFO_ITEM* closestNet = nullptr;
for( PCB_TRACK *track : aBoard->Tracks() ) for( PCB_TRACK *track : aBoard->Tracks() )
{ {
@ -400,23 +405,19 @@ static NETINFO_ITEM* snapToNearestTrackPoint( VECTOR2I& aP, BOARD* aBoard, NETIN
SEG seg( track->GetStart(), track->GetEnd() ); SEG seg( track->GetStart(), track->GetEnd() );
VECTOR2I nearest = seg.NearestPoint( aP ); VECTOR2I nearest = seg.NearestPoint( aP );
SEG::ecoord distSq = ( nearest - aP ).SquaredEuclideanNorm(); SEG::ecoord dist_sq = ( nearest - aP ).SquaredEuclideanNorm();
if( distSq < minDistSq ) if( dist_sq < minDist_sq )
{ {
minDistSq = distSq; minDist_sq = dist_sq;
closestPt = nearest; closestPt = nearest;
closestNet = track->GetNet();
if( aNearestTrack )
*aNearestTrack = track;
} }
} }
if( minDistSq != VECTOR2I::ECOORD_MAX ) return closestPt;
{
aP = closestPt;
return closestNet;
}
return nullptr;
} }
@ -513,15 +514,20 @@ void PCB_GENERATOR_MEANDERS::EditStart( GENERATOR_TOOL* aTool, BOARD* aBoard,
aTool->ClearRouterCommit(); aTool->ClearRouterCommit();
router->SyncWorld(); router->SyncWorld();
PNS::RULE_RESOLVER* resolver = router->GetRuleResolver();
PNS::CONSTRAINT constraint;
if( !baselineValid() ) if( !baselineValid() )
initBaseLines( router, layer, aBoard ); initBaseLines( router, layer, aBoard );
if( baselineValid() && !m_overrideCustomRules ) if( baselineValid() && !m_overrideCustomRules )
{ {
PNS::CONSTRAINT constraint; PCB_TRACK* track = nullptr;
PNS::RULE_RESOLVER* resolver = router->GetRuleResolver();
NETINFO_ITEM* net = snapToNearestTrackPoint( m_origin, aBoard, nullptr ); m_origin = snapToNearestTrack( m_origin, aBoard, nullptr, &track );
wxCHECK( track, /* void */ );
NETINFO_ITEM* net = track->GetNet();
PNS::SEGMENT pnsItem( m_baseLine->CSegment( 0 ), net ); PNS::SEGMENT pnsItem( m_baseLine->CSegment( 0 ), net );
if( m_tuningMode == SINGLE ) if( m_tuningMode == SINGLE )
@ -694,8 +700,8 @@ bool PCB_GENERATOR_MEANDERS::initBaseLine( PNS::ROUTER* aRouter, int aLayer, BOA
{ {
PNS::NODE* world = aRouter->GetWorld(); PNS::NODE* world = aRouter->GetWorld();
snapToNearestTrackPoint( aStart, aBoard, aNet ); aStart = snapToNearestTrack( aStart, aBoard, aNet, nullptr );
snapToNearestTrackPoint( aEnd, aBoard, aNet ); aEnd = snapToNearestTrack( aEnd, aBoard, aNet, nullptr );
VECTOR2I startSnapPoint, endSnapPoint; VECTOR2I startSnapPoint, endSnapPoint;
@ -732,7 +738,12 @@ bool PCB_GENERATOR_MEANDERS::initBaseLines( PNS::ROUTER* aRouter, int aLayer, BO
{ {
m_baseLineCoupled.reset(); m_baseLineCoupled.reset();
NETINFO_ITEM* net = snapToNearestTrackPoint( m_origin, aBoard, nullptr ); PCB_TRACK* track = nullptr;
m_origin = snapToNearestTrack( m_origin, aBoard, nullptr, &track );
wxCHECK( track, false );
NETINFO_ITEM* net = track->GetNet();
if( !initBaseLine( aRouter, aLayer, aBoard, m_origin, m_end, net, m_baseLine ) ) if( !initBaseLine( aRouter, aLayer, aBoard, m_origin, m_end, net, m_baseLine ) )
return false; return false;
@ -743,8 +754,8 @@ bool PCB_GENERATOR_MEANDERS::initBaseLines( PNS::ROUTER* aRouter, int aLayer, BO
{ {
if( NETINFO_ITEM* coupledNet = aBoard->DpCoupledNet( net ) ) if( NETINFO_ITEM* coupledNet = aBoard->DpCoupledNet( net ) )
{ {
VECTOR2I coupledStart = m_origin; VECTOR2I coupledStart = snapToNearestTrack( m_origin, aBoard, coupledNet, nullptr );
VECTOR2I coupledEnd = m_end; VECTOR2I coupledEnd = snapToNearestTrack( m_end, aBoard, coupledNet, nullptr );
return initBaseLine( aRouter, aLayer, aBoard, coupledStart, coupledEnd, coupledNet, return initBaseLine( aRouter, aLayer, aBoard, coupledStart, coupledEnd, coupledNet,
m_baseLineCoupled ); m_baseLineCoupled );
@ -859,7 +870,7 @@ PNS::MEANDER_SETTINGS PCB_GENERATOR_MEANDERS::toMeanderSettings()
settings.m_targetSkew = m_targetSkew; settings.m_targetSkew = m_targetSkew;
settings.m_overrideCustomRules = m_overrideCustomRules; settings.m_overrideCustomRules = m_overrideCustomRules;
settings.m_singleSided = m_singleSide; settings.m_singleSided = m_singleSide;
settings.m_segmentSide = m_initialSide; settings.m_initialSide = m_initialSide;
settings.m_cornerRadiusPercentage = m_cornerRadiusPercentage; settings.m_cornerRadiusPercentage = m_cornerRadiusPercentage;
return settings; return settings;
@ -876,7 +887,7 @@ void PCB_GENERATOR_MEANDERS::fromMeanderSettings( const PNS::MEANDER_SETTINGS& a
m_targetSkew = aSettings.m_targetSkew; m_targetSkew = aSettings.m_targetSkew;
m_overrideCustomRules = aSettings.m_overrideCustomRules; m_overrideCustomRules = aSettings.m_overrideCustomRules;
m_singleSide = aSettings.m_singleSided; m_singleSide = aSettings.m_singleSided;
m_initialSide = aSettings.m_segmentSide; m_initialSide = aSettings.m_initialSide;
m_cornerRadiusPercentage = aSettings.m_cornerRadiusPercentage; m_cornerRadiusPercentage = aSettings.m_cornerRadiusPercentage;
} }
@ -1026,13 +1037,16 @@ bool PCB_GENERATOR_MEANDERS::Update( GENERATOR_TOOL* aTool, BOARD* aBoard,
if( !router->StartRouting( startSnapPoint, startItem, layer ) ) if( !router->StartRouting( startSnapPoint, startItem, layer ) )
return false; return false;
auto placer = static_cast<PNS::MEANDER_PLACER_BASE*>( router->Placer() ); PNS::MEANDER_PLACER_BASE* placer = static_cast<PNS::MEANDER_PLACER_BASE*>( router->Placer() );
PNS::MEANDER_SETTINGS settings = toMeanderSettings(); PNS::MEANDER_SETTINGS settings = toMeanderSettings();
placer->UpdateSettings( settings ); placer->UpdateSettings( settings );
router->Move( m_end, nullptr ); router->Move( m_end, nullptr );
m_trackWidth = router->Sizes().TrackWidth();
m_diffPairGap = router->Sizes().DiffPairGap();
m_initialSide = placer->MeanderSettings().m_initialSide;
m_lastNetName = iface->GetNetName( startItem->Net() ); m_lastNetName = iface->GetNetName( startItem->Net() );
m_tuningInfo = placer->TuningInfo( aFrame->GetUserUnits() ); m_tuningInfo = placer->TuningInfo( aFrame->GetUserUnits() );
m_tuningStatus = placer->TuningStatus(); m_tuningStatus = placer->TuningStatus();
@ -1127,12 +1141,15 @@ bool PCB_GENERATOR_MEANDERS::MakeEditPoints( std::shared_ptr<EDIT_POINTS> points
base.A += centerlineOffset; base.A += centerlineOffset;
base.B += centerlineOffset; base.B += centerlineOffset;
int offset = m_maxAmplitude; int amplitude = m_maxAmplitude + KiROUND( m_trackWidth / 2.0 );
if( m_tuningMode == DIFF_PAIR )
amplitude += KiROUND( m_diffPairGap * 1.5 ) + m_trackWidth;
if( m_initialSide == -1 ) if( m_initialSide == -1 )
offset *= -1; amplitude *= -1;
VECTOR2I widthHandleOffset = ( base.B - base.A ).Perpendicular().Resize( offset ); VECTOR2I widthHandleOffset = ( base.B - base.A ).Perpendicular().Resize( amplitude );
points->AddPoint( base.A + widthHandleOffset ); points->AddPoint( base.A + widthHandleOffset );
points->Point( 2 ).SetGridConstraint( IGNORE_GRID ); points->Point( 2 ).SetGridConstraint( IGNORE_GRID );
@ -1169,6 +1186,12 @@ bool PCB_GENERATOR_MEANDERS::UpdateFromEditPoints( std::shared_ptr<EDIT_POINTS>
VECTOR2I wHandle = aEditPoints->Point( 2 ).GetPosition(); VECTOR2I wHandle = aEditPoints->Point( 2 ).GetPosition();
int value = base.LineDistance( wHandle ); int value = base.LineDistance( wHandle );
value -= KiROUND( m_trackWidth / 2.0 );
if( m_tuningMode == DIFF_PAIR )
value -= KiROUND( m_diffPairGap * 1.5 ) + m_trackWidth;
SetMaxAmplitude( KiROUND( value / pcbIUScale.mmToIU( 0.1 ) ) * pcbIUScale.mmToIU( 0.1 ) ); SetMaxAmplitude( KiROUND( value / pcbIUScale.mmToIU( 0.1 ) ) * pcbIUScale.mmToIU( 0.1 ) );
int side = base.Side( wHandle ); int side = base.Side( wHandle );
@ -1206,12 +1229,15 @@ bool PCB_GENERATOR_MEANDERS::UpdateEditPoints( std::shared_ptr<EDIT_POINTS> aEdi
base.A += centerlineOffset; base.A += centerlineOffset;
base.B += centerlineOffset; base.B += centerlineOffset;
int offset = m_maxAmplitude; int amplitude = m_maxAmplitude + KiROUND( m_trackWidth / 2.0 );
if( m_tuningMode == DIFF_PAIR )
amplitude += KiROUND( m_diffPairGap * 1.5 ) + m_trackWidth;
if( m_initialSide == -1 ) if( m_initialSide == -1 )
offset *= -1; amplitude *= -1;
VECTOR2I widthHandleOffset = ( base.B - base.A ).Perpendicular().Resize( offset ); VECTOR2I widthHandleOffset = ( base.B - base.A ).Perpendicular().Resize( amplitude );
aEditPoints->Point( 0 ).SetPosition( m_origin + centerlineOffset ); aEditPoints->Point( 0 ).SetPosition( m_origin + centerlineOffset );
aEditPoints->Point( 1 ).SetPosition( m_end + centerlineOffset ); aEditPoints->Point( 1 ).SetPosition( m_end + centerlineOffset );
@ -1243,13 +1269,20 @@ SHAPE_LINE_CHAIN PCB_GENERATOR_MEANDERS::getRectShape() const
cl.SetPoint( -1, ( cl.CPoint( -1 ) + m_baseLineCoupled->CPoint( -1 ) ) / 2 ); cl.SetPoint( -1, ( cl.CPoint( -1 ) + m_baseLineCoupled->CPoint( -1 ) ) / 2 );
} }
bool singleSided = m_tuningMode != DIFF_PAIR && m_singleSide; bool singleSided = m_singleSide;
int amplitude = m_maxAmplitude + KiROUND( m_trackWidth / 2.0 );
if( m_tuningMode == DIFF_PAIR )
{
singleSided = false;
amplitude += KiROUND( m_diffPairGap * 1.5 ) + m_trackWidth;
}
if( singleSided ) if( singleSided )
{ {
SHAPE_LINE_CHAIN left, right; SHAPE_LINE_CHAIN left, right;
if( cl.OffsetLine( m_maxAmplitude, CORNER_STRATEGY::ROUND_ALL_CORNERS, ARC_LOW_DEF, if( cl.OffsetLine( amplitude, CORNER_STRATEGY::ROUND_ALL_CORNERS, ARC_LOW_DEF,
left, right, true ) ) left, right, true ) )
{ {
chain.Append( cl.CPoint( 0 ) ); chain.Append( cl.CPoint( 0 ) );
@ -1268,7 +1301,7 @@ SHAPE_LINE_CHAIN PCB_GENERATOR_MEANDERS::getRectShape() const
{ {
SHAPE_POLY_SET poly; SHAPE_POLY_SET poly;
poly.OffsetLineChain( cl, m_maxAmplitude * 2, CORNER_STRATEGY::ROUND_ALL_CORNERS, poly.OffsetLineChain( cl, amplitude * 2, CORNER_STRATEGY::ROUND_ALL_CORNERS,
ARC_LOW_DEF, false ); ARC_LOW_DEF, false );
if( poly.OutlineCount() > 0 ) if( poly.OutlineCount() > 0 )
@ -1339,6 +1372,8 @@ const STRING_ANY_MAP PCB_GENERATOR_MEANDERS::GetProperties() const
props.set_iu( "min_spacing", m_spacing ); props.set_iu( "min_spacing", m_spacing );
props.set_iu( "target_length", m_targetLength ); props.set_iu( "target_length", m_targetLength );
props.set_iu( "target_skew", m_targetSkew ); props.set_iu( "target_skew", m_targetSkew );
props.set_iu( "last_track_width", m_trackWidth );
props.set_iu( "last_diff_pair_gap", m_diffPairGap );
props.set( "last_netname", m_lastNetName ); props.set( "last_netname", m_lastNetName );
props.set( "last_tuning", m_tuningInfo ); props.set( "last_tuning", m_tuningInfo );
@ -1380,6 +1415,8 @@ void PCB_GENERATOR_MEANDERS::SetProperties( const STRING_ANY_MAP& aProps )
aProps.get_to_iu( "min_spacing", m_spacing ); aProps.get_to_iu( "min_spacing", m_spacing );
aProps.get_to_iu( "target_length", m_targetLength ); aProps.get_to_iu( "target_length", m_targetLength );
aProps.get_to_iu( "target_skew", m_targetSkew ); aProps.get_to_iu( "target_skew", m_targetSkew );
aProps.get_to_iu( "last_track_width", m_trackWidth );
aProps.get_to_iu( "last_diff_pair_gap", m_diffPairGap );
aProps.get_to( "override_custom_rules", m_overrideCustomRules ); aProps.get_to( "override_custom_rules", m_overrideCustomRules );
aProps.get_to( "last_netname", m_lastNetName ); aProps.get_to( "last_netname", m_lastNetName );

View File

@ -249,10 +249,10 @@ bool DP_MEANDER_PLACER::Move( const VECTOR2I& aP, ITEM* aEndItem )
SEG base = baselineSegment( sp ); SEG base = baselineSegment( sp );
bool side = false; bool side = false;
if( m_settings.m_segmentSide == 0 ) if( m_settings.m_initialSide == 0 )
side = base.Side( aP ) < 0; side = base.Side( aP ) < 0;
else else
side = m_settings.m_segmentSide < 0; side = m_settings.m_initialSide < 0;
PNS_DBG( Dbg(), AddShape, base, GREEN, 10000, wxT( "dp-baseline" ) ); PNS_DBG( Dbg(), AddShape, base, GREEN, 10000, wxT( "dp-baseline" ) );

View File

@ -87,6 +87,14 @@ void MEANDERED_LINE::MeanderSegment( const SEG& aBase, bool aSide, int aBaseInde
{ {
if( m.Fit( MT_SINGLE, aBase, m_last, !side ) ) if( m.Fit( MT_SINGLE, aBase, m_last, !side ) )
{ {
if( !started )
{
// Update initial side to the one that fits
MEANDER_SETTINGS settings = m_placer->MeanderSettings();
settings.m_initialSide = ( PNS::MEANDER_SIDE) -settings.m_initialSide;
m_placer->UpdateSettings( settings );
}
AddMeander( new MEANDER_SHAPE( m ) ); AddMeander( new MEANDER_SHAPE( m ) );
fail = false; fail = false;
started = false; started = false;
@ -108,6 +116,14 @@ void MEANDERED_LINE::MeanderSegment( const SEG& aBase, bool aSide, int aBaseInde
if( m.Fit( MT_CHECK_START, aBase, m_last, checkSide ) ) if( m.Fit( MT_CHECK_START, aBase, m_last, checkSide ) )
{ {
if( !started && checkSide != side )
{
// Update initial side to the one that fits
MEANDER_SETTINGS settings = m_placer->MeanderSettings();
settings.m_initialSide = ( PNS::MEANDER_SIDE) -settings.m_initialSide;
m_placer->UpdateSettings( settings );
}
turning = true; turning = true;
AddMeander( new MEANDER_SHAPE( m ) ); AddMeander( new MEANDER_SHAPE( m ) );
side = !checkSide; side = !checkSide;

View File

@ -80,7 +80,7 @@ public:
m_cornerStyle = MEANDER_STYLE_ROUND; m_cornerStyle = MEANDER_STYLE_ROUND;
m_cornerRadiusPercentage = 100; m_cornerRadiusPercentage = 100;
m_singleSided = false; m_singleSided = false;
m_segmentSide = MEANDER_SIDE_LEFT; m_initialSide = MEANDER_SIDE_LEFT;
m_lengthTolerance = 100000; m_lengthTolerance = 100000;
} }
@ -117,7 +117,7 @@ public:
bool m_singleSided; bool m_singleSided;
///< Initial side when placing meanders at segment ///< Initial side when placing meanders at segment
MEANDER_SIDE m_segmentSide; MEANDER_SIDE m_initialSide;
///< Allowable tuning error. ///< Allowable tuning error.
int m_lengthTolerance; int m_lengthTolerance;

View File

@ -141,10 +141,10 @@ bool MEANDER_PLACER::doMove( const VECTOR2I& aP, ITEM* aEndItem, long long int a
bool side = false; bool side = false;
const SEG s = tuned.CSegment( i ); const SEG s = tuned.CSegment( i );
if( m_settings.m_segmentSide == 0 ) if( m_settings.m_initialSide == 0 )
side = s.Side( aP ) < 0; side = s.Side( aP ) < 0;
else else
side = m_settings.m_segmentSide < 0; side = m_settings.m_initialSide < 0;
m_result.AddCorner( s.A ); m_result.AddCorner( s.A );
m_result.MeanderSegment( s, side ); m_result.MeanderSegment( s, side );
@ -159,7 +159,9 @@ bool MEANDER_PLACER::doMove( const VECTOR2I& aP, ITEM* aEndItem, long long int a
if( compareWithTolerance( lineLen, aTargetLength, m_settings.m_lengthTolerance ) > 0 ) if( compareWithTolerance( lineLen, aTargetLength, m_settings.m_lengthTolerance ) > 0 )
{ {
m_lastStatus = TOO_LONG; m_lastStatus = TOO_LONG;
} else { }
else
{
m_lastLength = lineLen - tuned.Length(); m_lastLength = lineLen - tuned.Length();
tuneLineLength( m_result, aTargetLength - lineLen ); tuneLineLength( m_result, aTargetLength - lineLen );
} }