Source Vertical Position
Per-tenant configurator setting that controls how Model Group elevation from per-floor source RVTs is preserved during configuration
Source Vertical Position
The configurator merges per-group RVT files into a single configured house by calling Revit's CopyElements, placing each source Model Group at a target position supplied by the backend. How the Z (vertical) component of that target position is interpreted depends on a per-tenant setting — preserveSourceVerticalPosition.
This setting exists because tenants author their per-floor source RVTs in two genuinely different ways, and the configurator has to know which convention you use.
The two conventions
preserveSourceVerticalPosition = false — backend-driven Z (default)
The source RVT authors each Model Group with its LocationPoint at z = 0 (i.e. the group sits on its own internal origin). The backend then supplies an absolute target position including the per-floor Z for every group, and the configurator places the group at that exact point.
If your source RVT actually has the LocationPoint sitting at a non-zero elevation (e.g. a baked-in floor height of 2900 mm), the configurator will subtract that source Z out and the group will land below its level — by exactly the source Z.
preserveSourceVerticalPosition = true — source-driven Z
The source RVT authors each Model Group with its LocationPoint at the real floor elevation (e.g. the first-floor group at z ≈ 2900 mm). The configurator preserves that vertical position and treats the backend's target position as a horizontal-only translation — X and Y are applied, the Z component is ignored.
Use this when your modelers want to author each per-floor RVT with the Group already sitting at its correct floor elevation in the source file.
Which one do I want?
| If your per-floor source RVTs have the Model Group's LocationPoint at… | Set preserveSourceVerticalPosition to |
|---|---|
z = 0 and the backend should drive the per-floor stacking | false (default) |
| The actual per-floor elevation (e.g. 1V at z≈2900) | true |
A quick way to check: open one of your per-floor RVTs, select the Model Group, and read the Z of its LocationPoint. If it is 0, you are on the default. If it is the real floor height, flip the flag.
Where the setting lives
The flag is on the tenant:
tenant.settings.configuratorSettings.preserveSourceVerticalPositionIt defaults to false. There is no UI yet — change it directly on the tenant document for now.
Symptoms of a mismatch
If the convention does not match the source files, the configurator silently produces wrong elevations:
- Default mode + source RVT bakes in floor height → every floor collapses downward; groups end up at
-floorHeightbelow their target Level. - Flag enabled + source RVT has LocationPoint at z = 0 → every floor ends up on the ground floor stacked on top of each other (the per-floor Z from the backend is being ignored).
The configurator logs the chosen mode and per-model source location on every run — look for Copy strategy: …, preserveSourceVerticalPosition: … and source location (ft) 0,0,Z_floor lines in the run log to confirm what the source file actually contains.
Authoring the nulpunt reference
When compensateInsertion is enabled, each source GLB is expected to contain a node whose name includes nulpunt (typically NLRS_0-_GM_nulpunt_origin_group). The configurator uses that node's bottom-front-left bounding-box corner as the canonical model origin — its negated position becomes the offset applied to the placement target.
Authoring rule: place the nulpunt mesh so that its bottom-front-left corner sits at the point you want the model to align with at run-time. For a cube resting on the floor at the building's front-left corner, that's already correct: the cube's bottom face is the floor surface and its corner is the building origin.
A common pitfall is placing the cube with its center at the intended origin instead of its corner. The configurator's previous behaviour (≤ 2026-05-18) sampled the bbox center, which silently absorbed half the cube's vertical extent (e.g. 50 mm for a 100 mm cube resting on the floor) into Z compensation, producing groups landing 50 mm below their target level. Current behaviour samples the corner, so models with the cube floating above the floor produce a vertical offset equal to the cube's bottom Z. If you see a small but consistent vertical mismatch across every group in a configuration, open one of the source RVTs and check that the nulpunt cube's bottom face sits exactly on the level it represents.