ifcviewer: rename stage1/2/3/4 to their proper IFC-mapped names

Replace the placeholder "stage1/2/3/4" terminology with names that
mirror the IFC concepts each step represents:

  stage 1 -> PlacementTransformation
            (per-instance, derived from IfcObjectPlacement)
  stage 2 -> CoordinateOperation
            (per-model, IfcCoordinateOperation / IfcMapConversion)
  stage 3 -> FederatedFalseOrigin
            (federation-wide, user-nominated)
  stage 4 -> ModelTransformation
            (per-model, user-authored within the federation)

API renames:
  FederationOrigin            -> FederatedFalseOrigin
  ModelTransform              -> ModelTransformation
  composeFederationOrigin     -> composeFederatedFalseOrigin
  composeModelTransform       -> composeModelTransformation
  Federation::setOrigin       -> Federation::setFederatedFalseOrigin
  Federation::setModelTransform -> Federation::setModelTransformation
  Federation::origin()        -> Federation::federatedFalseOrigin()
  Federation::Model::transform_intent -> ::model_transformation
  ModelGeoref::stage2_meters  -> ::coordinate_operation_meters
  ModelGeoref::has_stage2     -> ::has_coordinate_operation

JSON keys in .ifcfed renamed in lockstep:
  origin                -> federated_false_origin
  transform_intent      -> model_transformation

The streamer's per-mesh "stage 1 vertex rebasing" comment is reframed:
the rebase isn't its own stage — it's a precision optimisation applied
inside the PlacementTransformation step.

All 36 ctest cases pass under the new names.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Dion Moult
2026-05-01 20:06:06 +10:00
parent 600d3a3460
commit 92c3b4c308
4 changed files with 143 additions and 126 deletions
+12 -11
View File
@@ -147,12 +147,12 @@ std::vector<ElementInfo> GeometryStreamer::drainElements() {
// Build a mesh chunk (local coords, 28-byte interleaved vertices) from a
// TriangulationElement. Per-vertex color is baked from material_ids so that
// triangulations with per-face materials still render correctly.
// Stage 1 — vertex rebasing. When `offset` is non-zero, every vertex
// position is subtracted by it so the emitted mesh-local coordinates stay
// near the origin (and float32 precision survives upload to the GPU).
// Caller compensates by post-multiplying each instance's placement by
// T(+offset), which is mathematically the identity overall but moves the
// "magnitude" off the float-precision-sensitive vertex column.
// Vertex rebasing: when `offset` is non-zero, every vertex position is
// subtracted by it so the emitted mesh-local coordinates stay near the
// origin (and float32 precision survives upload to the GPU). Caller
// compensates by post-multiplying each instance's PlacementTransformation
// by T(+offset), which is mathematically the identity overall but moves
// the magnitude off the float-precision-sensitive vertex column.
static MeshChunk buildMeshChunk(uint32_t model_id,
uint32_t local_mesh_id,
const IfcGeom::TriangulationElement* elem,
@@ -593,8 +593,8 @@ void GeometryStreamer::run(const std::string& path, int num_threads) {
}
if (first_sight) {
// Stage 1: pick a rebase offset when the mesh's first
// source vertex is far from origin (>1 km in metres,
// Vertex rebasing: pick a rebase offset when the mesh's
// first source vertex is far from origin (>1 km in metres,
// matching bonsai's distance_limit default). Iterator
// outputs metres, so the threshold is in metres directly.
Eigen::Vector3d offset = Eigen::Vector3d::Zero();
@@ -627,9 +627,10 @@ void GeometryStreamer::run(const std::string& path, int num_threads) {
}
}
// Stage 1 cont.: post-multiply the per-instance placement by
// T(+offset) so world position is preserved. Matrix arithmetic
// is in double; narrow to float at the end.
// Vertex rebasing cont.: post-multiply the per-instance
// PlacementTransformation by T(+offset) so world position is
// preserved. Matrix arithmetic is in double; narrow to float
// at the end.
Eigen::Matrix4d mat_d =
tri_elem->transformation().data()->ccomponents();
if (mesh_aabbs[local_mesh_id].has_offset) {