mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-11-05 12:09:02 +01:00
feat(editor): the whole-scenery grade fit sets the tracks over a bridge or a viaduct to the bridge environment
Where the terrain model falls away under a fitted line by the abutments, the paths are cut off at the ends of the stretch as the line is applied and set to the bridge, in the same step of the history: they sound as on a bridge, get no formation and the terrain under them stays as the model has it, also after the scenery is saved and opened again. Tunnels and tracks set to the bridge already are left as they are. The status says how many paths went on a bridge.
This commit is contained in:
@@ -2288,8 +2288,9 @@ class editor_mode : public application_mode, private editor_track::observer, pri
|
|||||||
void profile_restore_ground();
|
void profile_restore_ground();
|
||||||
void render_profile_earthworks();
|
void render_profile_earthworks();
|
||||||
void profile_check();
|
void profile_check();
|
||||||
// Terrain: the heightmap terrain follows the tracks changed
|
// Terrain: the heightmap terrain follows the tracks changed. Bridges: stretches of the route over a bridge or a viaduct, the
|
||||||
void profile_apply(bool const Terrain = false);
|
// paths over them cut off at their ends and set to the bridge environment
|
||||||
|
void profile_apply(bool const Terrain = false, std::vector<profile::departure> const &Bridges = {});
|
||||||
// the terrain under the tracks changed by the last Edits steps of the history which changed tracks
|
// the terrain under the tracks changed by the last Edits steps of the history which changed tracks
|
||||||
void profile_follow_terrain(std::size_t const Edits);
|
void profile_follow_terrain(std::size_t const Edits);
|
||||||
void profile_fit_view();
|
void profile_fit_view();
|
||||||
|
|||||||
@@ -2069,7 +2069,15 @@ bool editor_mode::nmt_fit_line(TTrack &Track)
|
|||||||
profile_check();
|
profile_check();
|
||||||
auto const fitted_line{profile.line};
|
auto const fitted_line{profile.line};
|
||||||
auto const authored{profile.samples};
|
auto const authored{profile.samples};
|
||||||
profile_apply();
|
// where the model falls away under the line by the abutments, the line goes over on a bridge or a viaduct: its paths there
|
||||||
|
// are cut off and set to the bridge, the formation is laid up to it, the ground under it stays as the model has it
|
||||||
|
double constexpr kBridged{1.0}; // m
|
||||||
|
double constexpr kAbutment{100.0}; // per mille
|
||||||
|
std::vector<double> heights(count);
|
||||||
|
for (std::size_t i = 0; i < count; ++i)
|
||||||
|
heights[i] = profile::elevation(fitted_line, sampled[i]);
|
||||||
|
auto const bridges{profile::bridged(sampled, heights, model, kBridged, kAbutment)};
|
||||||
|
profile_apply(false, bridges);
|
||||||
auto const applied{profile.error.empty()};
|
auto const applied{profile.error.empty()};
|
||||||
// where the line parts from the model: under it a gap, a bridge or a viaduct, over it a wall or a structure above the track
|
// where the line parts from the model: under it a gap, a bridge or a viaduct, over it a wall or a structure above the track
|
||||||
auto const parted{profile::departures(fitted_line, sampled, model, 2.0 * kModel)};
|
auto const parted{profile::departures(fitted_line, sampled, model, 2.0 * kModel)};
|
||||||
@@ -2125,14 +2133,7 @@ bool editor_mode::nmt_fit_line(TTrack &Track)
|
|||||||
m_nmt_state.laid[{static_cast<int>(std::floor(sample.position.x / kPlanCell)), static_cast<int>(std::floor(sample.position.z / kPlanCell))}].push_back(
|
m_nmt_state.laid[{static_cast<int>(std::floor(sample.position.x / kPlanCell)), static_cast<int>(std::floor(sample.position.z / kPlanCell))}].push_back(
|
||||||
{sample.position, sample.direction, sample.grade, editor_track::sampled_elevation(authored, sample.chainage), track != nullptr ? static_cast<double>(track->rail_height()) : 0.0, track});
|
{sample.position, sample.direction, sample.grade, editor_track::sampled_elevation(authored, sample.chainage), track != nullptr ? static_cast<double>(track->rail_height()) : 0.0, track});
|
||||||
}
|
}
|
||||||
// where the model falls away under the line by the abutments, the line goes over on a bridge or a viaduct: the formation
|
auto const spans{applied ? bridges : std::vector<profile::departure>{}};
|
||||||
// is laid up to it, the ground under it stays as the model has it
|
|
||||||
double constexpr kBridged{1.0}; // m
|
|
||||||
double constexpr kAbutment{100.0}; // per mille
|
|
||||||
std::vector<double> heights(count);
|
|
||||||
for (std::size_t i = 0; i < count; ++i)
|
|
||||||
heights[i] = profile::elevation(fitted_line, sampled[i]);
|
|
||||||
auto const spans{applied ? profile::bridged(sampled, heights, model, kBridged, kAbutment) : std::vector<profile::departure>{}};
|
|
||||||
for (auto const &stretch : spans)
|
for (auto const &stretch : spans)
|
||||||
for (std::size_t i = 0; i < count; ++i)
|
for (std::size_t i = 0; i < count; ++i)
|
||||||
if (sampled[i] >= stretch.from && sampled[i] <= stretch.to)
|
if (sampled[i] >= stretch.from && sampled[i] <= stretch.to)
|
||||||
|
|||||||
@@ -1450,7 +1450,7 @@ void editor_mode::profile_frame_view()
|
|||||||
fly_to(centre - right * (shift.x * pixel) + above * (shift.y * pixel), look, distance, 0.35);
|
fly_to(centre - right * (shift.x * pixel) + above * (shift.y * pixel), look, distance, 0.35);
|
||||||
}
|
}
|
||||||
|
|
||||||
void editor_mode::profile_apply(bool const Terrain)
|
void editor_mode::profile_apply(bool const Terrain, std::vector<profile::departure> const &Bridges)
|
||||||
{
|
{
|
||||||
auto &state{m_profile};
|
auto &state{m_profile};
|
||||||
state.status.clear();
|
state.status.clear();
|
||||||
@@ -1475,8 +1475,22 @@ void editor_mode::profile_apply(bool const Terrain)
|
|||||||
auto const before{state.samples};
|
auto const before{state.samples};
|
||||||
std::vector<std::pair<TTrack *, editor_track::state>> states;
|
std::vector<std::pair<TTrack *, editor_track::state>> states;
|
||||||
std::vector<TTrack *> created;
|
std::vector<TTrack *> created;
|
||||||
|
auto cuts{profile::breaks(line)};
|
||||||
|
for (auto const &bridge : Bridges)
|
||||||
|
cuts.insert(cuts.end(), {bridge.from, bridge.to});
|
||||||
|
std::sort(cuts.begin(), cuts.end());
|
||||||
auto const gaps{editor_track::apply_profile(
|
auto const gaps{editor_track::apply_profile(
|
||||||
state.route, [&](double const Chainage) { return profile::elevation(line, Chainage); }, [&](double const Chainage) { return profile::grade(line, Chainage); }, profile::breaks(line), states, created)};
|
state.route, [&](double const Chainage) { return profile::elevation(line, Chainage); }, [&](double const Chainage) { return profile::grade(line, Chainage); }, cuts, states, created)};
|
||||||
|
// the paths over a bridge sound and light as on one, and get no formation; within what a cut too near an end leaves on
|
||||||
|
double constexpr kBridgeEnd{0.5}; // m
|
||||||
|
std::size_t bridged{0};
|
||||||
|
for (auto const &span : state.route.spans)
|
||||||
|
if (span.track->eEnvironment != e_bridge && span.track->eEnvironment != e_tunnel
|
||||||
|
&& std::any_of(Bridges.begin(), Bridges.end(), [&](profile::departure const &Bridge) { return span.from >= Bridge.from - kBridgeEnd && span.to <= Bridge.to + kBridgeEnd; }))
|
||||||
|
{
|
||||||
|
span.track->eEnvironment = e_bridge;
|
||||||
|
++bridged;
|
||||||
|
}
|
||||||
auto const changed{states.size()};
|
auto const changed{states.size()};
|
||||||
auto const added{created.size()};
|
auto const added{created.size()};
|
||||||
state.created = created;
|
state.created = created;
|
||||||
@@ -1499,6 +1513,8 @@ void editor_mode::profile_apply(bool const Terrain)
|
|||||||
state.status = format(STR_P("Grade line applied: %zu path changed, %zu added, largest departure %.3f m", "Grade line applied: %zu paths changed, %zu added, largest departure %.3f m", changed), changed, added, state.departure);
|
state.status = format(STR_P("Grade line applied: %zu path changed, %zu added, largest departure %.3f m", "Grade line applied: %zu paths changed, %zu added, largest departure %.3f m", changed), changed, added, state.departure);
|
||||||
if (false == scene::Layers.empty())
|
if (false == scene::Layers.empty())
|
||||||
state.status += STR_C("\nThe paths and the design (//$p lines) go to the scenery files on save");
|
state.status += STR_C("\nThe paths and the design (//$p lines) go to the scenery files on save");
|
||||||
|
if (bridged > 0)
|
||||||
|
state.status += format(STR_P("\nOver a bridge or a viaduct: %zu path", "\nOver a bridge or a viaduct: %zu paths", bridged), bridged);
|
||||||
auto const name = [](TTrack const *Track) { return name_of(*Track); };
|
auto const name = [](TTrack const *Track) { return name_of(*Track); };
|
||||||
auto const closed{std::count_if(gaps.begin(), gaps.end(), [](auto const &Gap) { return Gap.closed; })};
|
auto const closed{std::count_if(gaps.begin(), gaps.end(), [](auto const &Gap) { return Gap.closed; })};
|
||||||
if (closed > 0)
|
if (closed > 0)
|
||||||
|
|||||||
@@ -8960,6 +8960,12 @@ msgstr "Serwis nie zwrócił modelu terenu"
|
|||||||
msgid "\nThe paths and the design (//$p lines) go to the scenery files on save"
|
msgid "\nThe paths and the design (//$p lines) go to the scenery files on save"
|
||||||
msgstr "\nTory i projekt (wiersze //$p) trafią do plików scenerii przy zapisie"
|
msgstr "\nTory i projekt (wiersze //$p) trafią do plików scenerii przy zapisie"
|
||||||
|
|
||||||
|
msgid "\nOver a bridge or a viaduct: %zu path"
|
||||||
|
msgid_plural "\nOver a bridge or a viaduct: %zu paths"
|
||||||
|
msgstr[0] "\nNa moście lub wiadukcie: %zu tor"
|
||||||
|
msgstr[1] "\nNa moście lub wiadukcie: %zu tory"
|
||||||
|
msgstr[2] "\nNa moście lub wiadukcie: %zu torów"
|
||||||
|
|
||||||
msgid "\nPaths off the route brought to the height of the switches:"
|
msgid "\nPaths off the route brought to the height of the switches:"
|
||||||
msgstr "\nTory spoza trasy dociągnięte do wysokości rozjazdów:"
|
msgstr "\nTory spoza trasy dociągnięte do wysokości rozjazdów:"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user