mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-10-17 19:09:25 +02:00
Editor: fold the plan library into the tree as modules, drop its own name
The track layout library came in as a subproject of its own -- its own CMakeLists, its own install and export rules, its own include tree -- which only made the build harder to follow now that everything else is a module. It is part of the editor, so it lives where the editor lives. - editor/plan_*.cppm / plan_*.cpp: the fifteen interface units and twelve implementation units, flat in editor/ beside editorTerrain and orthophoto, with the plan_ prefix keeping them clear of what was already there (editor/turnouts is the preset catalogue, so the geometry is plan_turnout_geometry). - modules are named eu07.editor.plan_*, like every other module in the tree. - namespaces move under the editor's own: editor::plan, editor::plan::geometry, ::io, ::render. The library's old name is gone from the sources and the docs. - every moved file carries the MPL header the rest of the tree carries; it had none. version.hpp went with the subproject: macros only, and unused. - the umbrella header is dropped -- nothing imported it. - the unit tests survive the fold: editor/tests, behind EU07_EDITOR_PLAN_TESTS (off by default), compiles the interfaces a second time into a small library of its own, because a test can only import modules from a target it links and linking the game would drag the whole simulator in. The code under test needs nothing but a compiler. 7/7 pass. - a switch may now be written with two dashes as well: --editor beside -editor. Builds with clang 22 (-DWITH_BETTER_RENDERER=OFF); -editor and --editor both come up in the editor on empty ground.
This commit is contained in:
181
editor/plan_solution.cppm
Normal file
181
editor/plan_solution.cppm
Normal file
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
This Source Code Form is subject to the
|
||||
terms of the Mozilla Public License, v.
|
||||
2.0. If a copy of the MPL was not
|
||||
distributed with this file, You can
|
||||
obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
module;
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
export module eu07.editor.plan_solution;
|
||||
export import eu07.editor.plan_segment;
|
||||
export import eu07.editor.plan_turnout_geometry;
|
||||
export import eu07.editor.plan_model;
|
||||
|
||||
export {
|
||||
|
||||
namespace editor::plan {
|
||||
|
||||
/// A point in the project's CRS (metres for EPSG:2180).
|
||||
struct PlanPoint {
|
||||
double x{0.0};
|
||||
double y{0.0};
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Solved geometry
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/// What one authored element works out to on the ground. Curvatures rather than
|
||||
/// radii, because that is what `geometry::layout_segment` takes and what makes a
|
||||
/// straight (0, 0), an arc (k, k) and a clothoid (k0, k1) one shape.
|
||||
struct SolvedElement {
|
||||
ElementId id{ElementId::none};
|
||||
Kind kind{Kind::Line};
|
||||
geometry::Pose start{}; ///< pose the element is laid from
|
||||
geometry::Pose end{}; ///< pose it ends on = the next element's start
|
||||
double k0{0.0}; ///< signed curvature at the start (1/m)
|
||||
double k1{0.0}; ///< signed curvature at the end
|
||||
double length{0.0};
|
||||
std::vector<PlanPoint> points; ///< sampled axis, first point == start
|
||||
};
|
||||
|
||||
/// A solved track: its elements in order, plus the axis flattened into one
|
||||
/// polyline with no duplicated join points, which is what a station along the
|
||||
/// track is resolved against.
|
||||
struct SolvedTrack {
|
||||
TrackId id{TrackId::none};
|
||||
std::vector<SolvedElement> elements;
|
||||
std::vector<PlanPoint> centreline;
|
||||
geometry::Pose start{};
|
||||
geometry::Pose end{};
|
||||
double length{0.0};
|
||||
/// True when the chain was laid whole. False means it was cut short by a
|
||||
/// diagnostic — the elements up to the cut are still here and still drawable.
|
||||
bool complete{true};
|
||||
};
|
||||
|
||||
/// One laid segment of a turnout's diverging path.
|
||||
struct SolvedTurnoutSegment {
|
||||
geometry::Pose start{};
|
||||
double k0{0.0}, k1{0.0}, length{0.0};
|
||||
plan::TurnoutPart part{plan::TurnoutPart::Curve};
|
||||
std::vector<PlanPoint> points;
|
||||
};
|
||||
|
||||
/// A construction point of a turnout: where two of its parts meet, or a point
|
||||
/// the catalogue drawing is dimensioned from. Reported rather than left to be
|
||||
/// eyeballed off the drawn curve.
|
||||
struct TurnoutMark {
|
||||
double x{0.0}, y{0.0};
|
||||
/// 0 PR, 1 ostrze iglicy (where the blade begins, the odcinek przediglicowy
|
||||
/// behind it), 2 pięta iglicy, 3 joint inside the curve, 4 end of curve /
|
||||
/// start of the frog rail, 5 KR, 6 punkt teoretyczny, 7 koniec dzioba iglicy
|
||||
/// (A, where the blade is u thick), 8 koniec strugania, 9 koniec rozjazdu on
|
||||
/// the through track (the frog projected back onto the straight).
|
||||
int kind{0};
|
||||
double station{0.0}; ///< along the diverging path from PR; 0 for the theoretical point
|
||||
};
|
||||
|
||||
struct SolvedTurnout {
|
||||
TurnoutId id{TurnoutId::none};
|
||||
bool valid{false};
|
||||
geometry::Pose start{}; ///< PR, on the through track
|
||||
geometry::Pose frog{}; ///< KR, where a branch anchors
|
||||
double tangent_front{0.0}, tangent_back{0.0};
|
||||
double diverging_length{0.0};
|
||||
double through_length{0.0}; ///< PR to the frog's projection, along the through track
|
||||
std::vector<SolvedTurnoutSegment> path;
|
||||
std::vector<TurnoutMark> marks;
|
||||
|
||||
/// The blade as dimensioned: where its tip stands (the odcinek przediglicowy
|
||||
/// is everything before it), how long the planed nose and the planing run,
|
||||
/// the kąt przylegania, and whether the type's own a/d/u agree with the curve.
|
||||
/// Łukowanie, as laid: the signed curvature of the through track under it, the
|
||||
/// one the branch came out at, and how far the through track turns over the
|
||||
/// turnout. All zero for a rozjazd zwyczajny.
|
||||
double bend{0.0};
|
||||
double diverging_curvature{0.0};
|
||||
double bend_angle{0.0};
|
||||
|
||||
bool has_blade{false};
|
||||
double blade_station{0.0};
|
||||
double nose_end{0.0};
|
||||
double planing_length{0.0};
|
||||
double blade_angle{0.0};
|
||||
double blade_residual{0.0};
|
||||
/// What the laid path works out to, against what the catalogue promised:
|
||||
/// deflection minus the crossing angle, and through-length minus the
|
||||
/// catalogue length. Reported, never fitted away.
|
||||
double angle_residual{0.0};
|
||||
double length_residual{0.0};
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Diagnostics
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/// Why something could not be laid. Reported, never silently dropped: the user
|
||||
/// gets the reason along with whatever part of the drawing did stand up.
|
||||
enum class Code {
|
||||
UnknownReference, ///< an anchor points at an id that is not there
|
||||
CyclicDependency, ///< tracks/turnouts depend on each other in a circle
|
||||
DegenerateElement, ///< non-positive radius or length, a clothoid that eases nothing
|
||||
TurnoutInvalid, ///< catalogue numbers admit no geometry
|
||||
TurnoutNotClosed, ///< the laid path misses the crossing angle or the catalogue length
|
||||
StationOffTrack, ///< a turnout sits past the end of its through track
|
||||
TouchingStraights, ///< two straights end to end, which is one straight
|
||||
HoldConflict, ///< two elements of one movable track both hold it parallel
|
||||
OffsetNotHeld, ///< a pinned track cannot move, so its offset is what it is
|
||||
};
|
||||
|
||||
[[nodiscard]] const char* code_name(Code code);
|
||||
|
||||
struct Diagnostic {
|
||||
Code code{Code::DegenerateElement};
|
||||
TrackId track{TrackId::none};
|
||||
ElementId element{ElementId::none};
|
||||
TurnoutId turnout{TurnoutId::none};
|
||||
/// Human-readable, with the number that matters in it ("R=300 m nie mieści
|
||||
/// się, maksimum 214,4 m"). The host shows this; it does not compose it.
|
||||
std::string text;
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// The whole solution
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/// Everything derived. Rebuilt whole on each solve, never fed back into the
|
||||
/// document. Vectors rather than maps so iteration order is the document's and
|
||||
/// two solves of the same document compare equal.
|
||||
struct Solution {
|
||||
std::vector<SolvedTrack> tracks;
|
||||
std::vector<SolvedTurnout> turnouts;
|
||||
std::vector<Diagnostic> diagnostics;
|
||||
};
|
||||
|
||||
[[nodiscard]] const SolvedTrack* find_track(const Solution& solution, TrackId id);
|
||||
[[nodiscard]] const SolvedTurnout* find_turnout(const Solution& solution, TurnoutId id);
|
||||
[[nodiscard]] const SolvedElement* find_element(const Solution& solution, ElementId id);
|
||||
|
||||
/// Pose at @p station metres along a solved track's centreline. Clamped to the
|
||||
/// ends. Returns false for an empty track.
|
||||
[[nodiscard]] bool pose_at(const SolvedTrack& track, double station,
|
||||
geometry::Pose& out);
|
||||
|
||||
/// How much track of one steady curvature there is around @p station: @p behind
|
||||
/// back to where the element begins, @p ahead on to where it ends, and
|
||||
/// @p curvature what it runs at (signed, positive turns left; zero on a
|
||||
/// straight). A turnout is laid as one piece of geometry, bent to the one radius
|
||||
/// under it, so it belongs on a single element and has to fit on it whole.
|
||||
/// False on a clothoid, where there is no one radius to bend to, and past the
|
||||
/// end of the track. Nothing is written then.
|
||||
[[nodiscard]] bool steady_room(const SolvedTrack& track, double station, double& curvature,
|
||||
double& behind, double& ahead);
|
||||
|
||||
} // namespace editor::plan
|
||||
|
||||
} // export
|
||||
Reference in New Issue
Block a user