ReUseX  0.0.5
3D Point Cloud Processing for Building Reuse
Loading...
Searching...
No Matches
stage_contract.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2025 Povl Filip Sonne-Frederiksen
2//
3// SPDX-License-Identifier: GPL-3.0-or-later
4
5#pragma once
6
7// The single, machine-readable source of truth for what each pipeline stage
8// consumes and produces in a `.rux` project (#246).
9//
10// This table used to exist three times: as a hand-written `switch` in
11// `core::check_stage_inputs()`, as
12// `rux::validation::validate_*_prerequisites()` in the CLI, and as prose in
13// docs/CONTRACTS.md. The three could — and did — disagree, so `rux validate
14// --stage mesh` could pass while `rux create mesh` refused. Everything now
15// reads THIS table:
16//
17// core::check_stage_inputs() interprets it against a ProjectDB
18// pipeline::run_stage() refuses through check_stage_inputs()
19// apps/rux gates every subcommand through it
20// docs/CONTRACTS.md is a prose mirror, asserted by a unit test
21//
22// Layering (STANDARDS §1): the table is pure data — enums and names — with no
23// PCL/CGAL/ProjectDB in it, so it sits at the lowest layer every consumer can
24// reach. `pipeline` is Layer 4 and could not be read from `core`; `utils` would
25// divorce it from the ProjectDB naming semantics it describes. Hence `core`.
26
27#include <optional>
28#include <string>
29#include <string_view>
30#include <vector>
31
32namespace reusex::core {
33
37enum class PipelineStage {
38 import,
49 // `gsplat` consumes `cloud` + `sensor_frames`, so anywhere after `clouds`
50 // would satisfy the ordering invariant. It sits last because it is a LEAF:
51 // it produces a `splat` nothing else consumes, so putting it mid-table would
52 // read as if the reconstruction spine ran through it. Leaves at the end also
53 // keeps the numbering of the existing stages stable.
55};
56
64
75
83
85struct StageInput {
89 std::vector<std::string_view> any_of;
91 int min_rows = 1;
96};
97
102 std::string_view name;
104 std::vector<std::string_view> aliases;
106 std::string_view command;
108 std::string_view summary;
109 std::vector<StageInput> inputs;
112 std::vector<std::string_view> outputs;
126 std::string_view external_outputs = {};
127};
128
130const std::vector<StageContract> &stage_contracts();
131
135
137const std::vector<Artifact> &pipeline_artifacts();
138
140const Artifact *find_artifact(std::string_view name);
141
145std::optional<PipelineStage> producing_stage(std::string_view artifact);
146
149std::optional<PipelineStage> parse_pipeline_stage(std::string_view name);
150
152std::string_view to_string(PipelineStage stage);
153
155std::vector<std::string> pipeline_stage_names();
156
157} // namespace reusex::core
Alignment
Which index-alignment class an artifact belongs to.
@ per_point
one entry per point of cloud
@ per_plane
one entry per detected plane
@ none
not index-aligned with anything (tables, meshes)
const std::vector< StageContract > & stage_contracts()
Every stage contract, in pipeline order.
std::vector< std::string > pipeline_stage_names()
All stage names accepted by parse_pipeline_stage(), for help text.
PipelineStage
Pipeline stages that have an input contract.
@ clouds
back-project sensor frames into "cloud" + "normals"
@ mesh
generate the reconstructed mesh
@ windows
derive window building components
@ project
project 2D semantic labels onto the 3D cloud
@ annotate
ML semantic labelling of the stored frames.
@ texture
texture-map the reconstructed mesh
@ instances
separate semantic labels into spatial instances
@ optimize
refine per-frame sensor poses (a.k.a. register)
@ planes
detect planar surfaces
@ rooms
partition into rooms
std::optional< PipelineStage > parse_pipeline_stage(std::string_view name)
Parse a stage name (e.g.
const StageContract & stage_contract(PipelineStage stage)
The contract of one stage.
auto to_string(Material value) -> std::string_view
Convert Material enum to its string identifier.
const std::vector< Artifact > & pipeline_artifacts()
Every artifact the contracts refer to.
ArtifactKind
What kind of thing a named artifact is inside a .rux project.
@ point_cloud
a named ProjectDB point cloud
@ table
a relational table (sensor_frames, …)
@ gaussian_splat
a row in the gaussian_splats table
const Artifact * find_artifact(std::string_view name)
Look up an artifact by name, or nullptr when it is not a pipeline artifact.
std::optional< PipelineStage > producing_stage(std::string_view artifact)
The earliest stage that writes artifact, or nullopt when nothing does (an externally sourced artifact...
One named cloud / table / mesh the pipeline traffics in.
std::string_view description
The full input/output contract of one pipeline stage.
std::vector< StageInput > inputs
std::string_view external_outputs
Artifacts this stage writes OUTSIDE the project, described in prose (e.g.
std::string_view summary
One-line description for help text.
std::vector< std::string_view > aliases
Additional accepted names (register for optimize).
std::string_view name
Canonical lower-case name — the rux validate --stage token.
std::string_view command
The command that runs this stage, used to build resolution hints.
std::vector< std::string_view > outputs
Artifacts this stage writes INTO the project.
One prerequisite of a stage.
std::vector< std::string_view > any_of
Artifact names, satisfied when ANY of them is present.
int min_depth_frames
Minimum number of sensor frames that must carry depth.
int min_rows
Minimum row count, for ArtifactKind::table inputs only.