From 153cdc550c142325162668b81600321a29f450ae Mon Sep 17 00:00:00 2001 From: maj00r Date: Fri, 23 Oct 2026 19:39:07 +0200 Subject: [PATCH] fix(sleepers): the fastenings of a rail part between two carved cuts where the part is laid, not twice as far out: both cuts carry its carved lines, taken once as the rails are laid, by one rule for both --- world/RailLayer.cpp | 9 ++------- world/RailLayout.h | 11 +++++++++++ world/SleeperFastenings.cpp | 2 +- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/world/RailLayer.cpp b/world/RailLayer.cpp index 9ba6c119..4dfe7f3d 100644 --- a/world/RailLayer.cpp +++ b/world/RailLayer.cpp @@ -785,16 +785,12 @@ void TTrack::rail_layer::lay_cuts( gfx::vertex_array const &Shape, std::vector tread_brightness( A, m_track.tread_band() ) ? B : A ); }; - knots::line offsets, extents, inner; + knots::line extents, inner; for( std::size_t i = 0; i <= Cuts.size(); ++i ) { auto const end { i < Cuts.size() ? Cuts[ i ].end : 1e9 }; // a piece carved between two cuts has the same lines at both auto const own { i < Cuts.size() && false == ( i > 0 && Cuts[ i - 1 ].carved && Cuts[ i ].carved ) }; - auto pieceoffsets { offsets }; - if( own ) { - pieceoffsets.insert( pieceoffsets.end(), Cuts[ i ].endoffsets.begin(), Cuts[ i ].endoffsets.end() ); - } - knots::sort( pieceoffsets ); + auto const pieceoffsets { part_offsets( i > 0 ? &Cuts[ i - 1 ] : nullptr, i < Cuts.size() ? &Cuts[ i ] : nullptr ) }; // the limits of the head from both ends can overlap along a short piece, as the planed wing rail of one frog and the cut of the next: the tighter of them holds auto const pieceextents { own ? knots::bound( extents, Cuts[ i ].endextents, true ) : extents }; auto const pieceinner { own ? knots::bound( inner, Cuts[ i ].endinner, false ) : inner }; @@ -861,7 +857,6 @@ void TTrack::rail_layer::lay_cuts( gfx::vertex_array const &Shape, std::vector cuts; }; +// how far out a part of a rail between two cuts is laid: as it goes on from the one and comes to the other, once where both are carved, which +// gives both its lines +inline knots::line part_offsets( rail_cut const *Before, rail_cut const *After ) { + + knots::line result { Before != nullptr ? Before->startoffsets : knots::line {} }; + if( After != nullptr && false == ( Before != nullptr && Before->carved && After->carved ) ) { + result.insert( result.end(), After->endoffsets.begin(), After->endoffsets.end() ); + } + knots::sort( result ); + return result; +} struct rail_tread { double from { 0.0 }; double to { 0.0 }; diff --git a/world/SleeperFastenings.cpp b/world/SleeperFastenings.cpp index b31318ad..9e282efa 100644 --- a/world/SleeperFastenings.cpp +++ b/world/SleeperFastenings.cpp @@ -94,7 +94,7 @@ fastened_rails::fastened_rails( TTrack &Track ) { if( to - from < fastening_merge ) { continue; } - auto const offsets { knots::sum( before != nullptr ? before->startoffsets : knots::line {}, after != nullptr ? after->endoffsets : knots::line {} ) }; + auto const offsets { track_rails::part_offsets( before, after ) }; auto const count { std::max( 1, static_cast( std::ceil( ( to - from ) / fastening_step ) ) ) }; rail line; line.track = track;