You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Register-only pass (no re-structure, no facts changed): strip
implementation-history narration a reviewer never needs while keeping every
caveat as a present-tense property of the design.
- Proof 4: drop the SetStage-fallback aside ('stage-free path added alongside
the SetStage path, preserved as fallback'); state the thread-safety as a
present-tense fact (mutex-guarded XformCache) instead of 'getting Storm to
render surfaced a bug'.
- Projected-vs-geographic rule: rewrite 'an earlier revision used the ENU lift
... the harness caught it' as a present-tense property (compose through
true-ENU instead of the grid plane -> 4.86 m off; the test asserts frame
selection). Same fact, no changelog.
- Guard rails / open questions: 'the adversarial testing surfaced' -> present
tense; drop 'now'/'no longer' temporal phrasing.
- Running: drop the 'Tier 1/Tier 2' plan-numbering labels (keep both run modes).
- Status: 'Done:' checklist -> 'It demonstrates:' present-tense properties.
All numbers/proofs/caveats preserved (418.9m/4.86m/6,369km/162mm/480,000x/
0.40mm/0.0mm/NCAT/DB no-overfit/thread-safety/9-9/30-30/5-CRS anti-overfit/
composition-overlay). Deck re-derived (26 slides, unchanged; markers untouched).
PR body kept in sync (same SetStage->'no application code' edit); all 8 README
anchors verified against current slugs.
Copy file name to clipboardExpand all lines: extras/usd/examples/usdGeospatial/README.md
+28-27Lines changed: 28 additions & 27 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -107,25 +107,24 @@ the build if disagreement exceeds 1 mm**.
107
107

108
108
109
109
**4 — It just works in usdview (real Hydra Storm render).** Beyond the plots: with only the built
110
-
plugins on `PXR_PLUGINPATH_NAME` — **no `SetStage`, no hand-built scene-index chain, no app
111
-
edits** — opening the georef scene in **usdview** (or `usdrecord`) draws the railway at its correct
110
+
plugins on `PXR_PLUGINPATH_NAME` — **no application code, no hand-built scene-index chain** —
111
+
opening the georef scene in **usdview** (or `usdrecord`) draws the railway at its correct
112
112
ECEF position via Storm. The `crs:` data flows through Hydra and an auto-inserted scene index
113
113
resolves it. This is a *real renderer image*, not a plot.
114
114
115
115
<!-- slide:image src="docs/railway_storm_autoinsert.png" eyebrow="Proof · real render, auto-insert" title="It just works in usdview (Storm)" caption="Real Hydra Storm render (not a plot): with the plugin on the path, the railway auto-resolves at its ECEF position — no app code. Negative control (plugin removed): railway absent. The auto-insert path matches the oracle 30/30 at 0.0 mm (testHydraAutoParity)." -->
How it works: `crs:` properties are custom attrs/rel on a codeless schema, so they never entered
119
+
How it works: `crs:` properties are custom attrs/rel on a codeless schema, so they are absent from
120
120
the default Hydra stream. A **keyless `UsdImagingAPISchemaAdapter`** (`apiSchemaName ""`, modeled on
121
121
`coordSysAPIAdapter` and NVIDIA's `omniGeoSceneIndex`) surfaces `crs:position`/`crs:binding`/
122
-
`crs:wkt`*into* Hydra for every prim; the scene index then resolves entirely from the Hydra data
123
-
stream (a stage-free path added alongside the `SetStage` path, which is preserved as fallback).
124
-
*Scope note (stated, not hidden):* the auto path resolves **direct**`crs:binding` (+ nearest /
125
-
stronger); collection- and purpose-based strength remain stage-path only — the neutral railway /
126
-
earth2 scenes use direct bindings, which is what auto-insert exercises. (Getting Storm to render also
127
-
surfaced and fixed a real bug: the resolver's `UsdGeomXformCache` was not thread-safe, and Storm syncs
128
-
rprims across TBB threads — a double-free — now guarded by a mutex.)
122
+
`crs:wkt`*into* Hydra for every prim; the scene index resolves entirely from the Hydra data
123
+
stream. *Scope note (stated, not hidden):* the auto path resolves **direct**`crs:binding`
124
+
(+ nearest / stronger); collection- and purpose-based strength are resolved via the stage path — the
125
+
neutral railway / earth2 scenes use direct bindings, which is what auto-insert exercises. The resolver
126
+
is thread-safe: its `UsdGeomXformCache` is mutex-guarded, so Storm can sync rprims across TBB threads
127
+
without a double-free.
129
128
130
129
## The design call: resolve, don't bake
131
130
@@ -225,12 +224,13 @@ goes wrong: **compose a child's offsets in the frame its anchor's CRS implies.**
225
224
anchor→corner lever in a UTM-17N-under-UTM-30N test).
226
225
227
226
The authored scene is identical either way; the runtime selects the frame from the bound CRS type
228
-
(`crs_engine.is_projected`). This rule was **found by an adversarial head-to-head**
229
-
(`test_coexist_vs_baked.py`) that rebuilds Simon Haegler's multi-CRS POC scene (MoMA in
227
+
(`crs_engine.is_projected`). An adversarial head-to-head enforces this rule
228
+
(`test_coexist_vs_baked.py`): it rebuilds Simon Haegler's multi-CRS POC scene (MoMA in
230
229
NAD83/UTM-17N under a WGS84/UTM-30N anchor) both baked and neutral and measures each against an
231
-
independent closed-form pyproj ground truth. Both approaches now land the corner at the same ECEF
232
-
point to **0.0 mm**; an earlier revision that used the ENU lift for the projected anchor landed
233
-
4.86 m off, and the harness caught it.
230
+
independent closed-form pyproj ground truth. Composed in the CRS-implied frame, both approaches land
231
+
the corner at the same ECEF point to **0.0 mm**; compose a projected anchor's child through the
232
+
true-ENU basis instead of its grid plane and the corner lands 4.86 m off — the test asserts the
233
+
frame selection so that error cannot pass silently.
234
234
235
235
## Non-geometric georeferenced data — visualize by composition, don't bake
236
236
@@ -306,7 +306,7 @@ renders empty, so the placement is unambiguously the runtime's, not the geometry
306
306
<!-- slide:section title="Guard rails" subtitle="Coexist's costs are asset-structure invariants a validator can enforce." -->
307
307
<!-- slide:text eyebrow="Enforceable, not showstoppers" title="Guard rails a validator can check" body="Coexist has no architectural showstopper — it matches baking to 0 mm when it composes in the CRS-implied frame. | Its residual costs are a small set of ASSET-STRUCTURE invariants, each mechanically checkable. | (1) anchor-vs-child is unambiguous; (2) child offsets are authored in the frame the bound CRS implies; (3) a CRS-requiring stage declares it so unaware consumers detect-and-refuse. | A neutral authored scene PRESERVES the semantic info a validator needs; a baked scene has already collapsed CRS intent into a matrix." -->
308
308
309
-
The adversarial testing surfaced the honest shape of "coexist": it is **not** blocked by any
309
+
The honest shape of "coexist" is that it is **not** blocked by any
310
310
architectural showstopper — it reproduces the baked approach to 0.0 mm when it composes in the
311
311
CRS-implied frame. Its residual costs are a small set of **asset-structure invariants**, and the
312
312
important property is that **each is mechanically checkable by a validator** — the same conformance
@@ -444,9 +444,9 @@ Every test is openable and runnable; each has a real negative control or an inde
444
444
puts georef prims at the origin. `testHydraAutoParity` adds the stage-free auto-insert path (30/30).
445
445
-`pxr/usd/usdGeospatial/regen-schema.sh --check` — schema resources are in sync.
446
446
447
-
### Running — two honest tiers
447
+
### Running — two paths
448
448
449
-
**Tier 1 — the codeless Python path (no external renderer):**
449
+
**The codeless Python path (no external renderer):**
0 commit comments