fixed commetn from songxiao

This commit is contained in:
ykcheungab
2026-09-25 17:46:37 +08:00
parent 6effe74172
commit 12781854ca
56 changed files with 4935 additions and 419 deletions
+109 -1
View File
@@ -5,7 +5,9 @@ the app loads a **compiled** package (`.oryscene`) and nothing else.
| tool | what it is for |
|---|---|
| `compile_scene.py` | a Blender export (+ optional housing GLB) → one `.oryscene` package |
| `compile_scene.py` | a legacy NPZ export (+ optional housing npz) → one `.oryscene` package |
| `align_housing.py` | a housing exported in another frame → a sensor-frame `housing.npz`, with the fit checked |
| `fit_design_frame.py` | the design export's *(unit scale, rigid transform)* pair, split out of the fitted similarity |
| `validate_scene.py` | the checks the loader and the compiler must agree on; the release gate |
| `probe_gl.py` | what this machine's OpenGL actually is (exit 0 GPU, 3 software, 4 no context) |
| `bench_scene.py` | per-stage p50/p95 of the running view (`--cpu-only` for the pure CPU cost) |
@@ -63,6 +65,112 @@ that the scene it is drawing was built from the same surface — and the same ma
via `field_domain_id` — that the device is actually running. A package that predates
this record is still accepted, and reported as *unverified* rather than as a match.
## The housing (the mounting frame)
Non-sensing geometry is a **separate part** with `part_id="housing"`, `role="housing"`: it is
drawn in a flat graphite grey (`unlit`-free, never coloured by the measurement) and the operator
can hide it. It ships **hidden by default** (`DisplaySettings.housing_visible`), because on the
finger sensor the frame is ~33 % wider than the sensing surface and dominated the picture.
`compile_scene.py --housing <npz>` takes a `vertices`/`faces` file **in the same source frame and
units as the export's `mesh.npz`**. Omitted, `<legacy-dir>/housing.npz` is used when present.
The finger sensor's design export lives in a **different frame**: it is at
`orisys-sensor-design/build/export/finger/r01/compute` and holds both `mesh.npz` and
`housing.npz` (`part_names = ['frame']`) in a camera/world frame. That export's mesh and the SDK
asset's mesh are the same surface with **identical `faces`**, so the frame relationship can be
fitted from the 1032 shared vertices instead of transcribed by hand:
```powershell
$design = 'D:\orisys_ws\orisys-sensor-design\build\export\finger\r01\compute'
& $py tools\scene_assets\align_housing.py `
--design $design `
--sensor $sdk `
--output tools\scene_assets\housing\finger_r01_housing.npz `
--matrix tools\scene_assets\housing\finger_r01_design_to_sensor.npy
& $py tools\scene_assets\compile_scene.py `
--legacy-dir $sdk `
--map "$sdk\unroll_map_uv_s0.4.npz" `
--meters-per-source-unit 0.001 `
--housing tools\scene_assets\housing\finger_r01_housing.npz `
--output apps\studio\config\sensors\finger\scene\finger-display-1.0.0.oryscene
```
`align_housing.py` **refuses to write** when the fitted transform does not hold to
`--tolerance` of the mesh diagonal, so a housing from an unrelated mesh cannot be dropped in
silently (a wrong transform still produces a plausible-looking picture). Re-running it also
regenerates `finger_r01_design_to_sensor.npy`, the 4×4 (`sensor = 0.018388452·R·design + t`)
that the fit found.
`geometry_id` and `source_geometry_id` cover the **sensing surface only** — the housing is in the
asset hash but not in the identities the acquisition side verifies, so adding a frame does not
make every device look unverified.
## Rebuilding the shipped package from the design export (r01)
The committed `apps/studio/config/sensors/finger/scene/finger-display-1.0.0.oryscene` is compiled
from the **design export** — the authoritative surface — and from the unroll map that export
produces (`unroll_map_uv_s0.42.npz`, coverage 39.211 %, domain `dfac267f…`). The SDK asset is
neither the source of it nor promoted into it; the *filename* stays `1.0.0` because
`asset_source.COMPILE_HINT`, `shared/tests/test_scene3d_device_geometry.py` and the stage
documents all name that exact path, and because `find_package()` takes
`sorted(*.oryscene)[-1]` — a second, higher-named package would shadow this one while the
hard-coded references kept validating the stale one. Bumping `asset_version` is a release
decision, not a rebuild side effect.
The export is in the design repo's camera/world frame and in *design* units, so the pair the
compiler needs is **derived**, never transcribed:
```powershell
$design = 'D:\orisys_ws\orisys-sensor-design\build\export\finger\r01\compute'
$sdk = 'D:\orisys_ws\orisys-sdk\sensors\finger\assets\30fps-0703'
& $py tools\scene_assets\fit_design_frame.py `
--design $design --sensor $sdk `
--rigid-output tools\scene_assets\housing\finger_r01_design_to_sensor_rigid_m.npy `
--report tools\scene_assets\housing\finger_r01_design_frame.json
& $py tools\scene_assets\compile_scene.py `
--legacy-dir $design `
--map "$design\unroll_map_uv_s0.42.npz" `
--meters-per-source-unit 1.8388451511463653e-05 `
--transform tools\scene_assets\housing\finger_r01_design_to_sensor_rigid_m.npy `
--housing "$design\housing.npz" `
--output apps\studio\config\sensors\finger\scene\finger-display-1.0.0.oryscene
```
- The fit over the 1032 shared vertices (identical `faces`/`loop_to_vertex`, so vertex *i* is
vertex *i*) is exact to float noise: rms **5.97e-07 sensor-mm**, 2.59e-08 of the 23.048-mm
diagonal. One design unit is therefore 1/54.38195812 of a sensor millimetre, and the unit
statement is `0.001 × 0.0183884515115`.
- `--transform` must be **rigid** (`compile_scene.py` validates the rotation block) and must be
in the compiler's **column** convention, `p_sensor = T @ [p; 1]`. `align_housing.fit_similarity`
fits the **row** form `p_sensor = s·(p @ R) + t`, so the block is `R.T` and the translation is
`0.001·t` metres. Feeding `housing/finger_r01_design_to_sensor.npy` straight in — it already
carries the scale *and* is in the row convention — is refused outright:
`geometry_mismatch: transform is not a rigid rotation`.
- Hence the trap the two files exist to prevent: the unit statement already contains the fit
scale, so a matrix that contains it too would apply it twice. Calling a design unit a
millimetre (`0.001`) with the correct rigid transform is worse, because it *compiles* and is
54.38196× too large.
- The housing comes from the export's own `housing.npz` (`part_names = ['frame', 'rubber-b']`,
2716 vertices / 5424 triangles). It is already in the frame and units `mesh.npz` is stated in,
which is exactly what `--housing` documents, so the sensor-frame
`housing/finger_r01_housing.npz` that `align_housing.py` regenerates is provenance and an
independent cross-check (the two routes agree to 9.5e-10 m), not a compile input.
- `housing_visible` keeps its shipped default `False` (`DisplaySettings.housing_visible`); there
is no compile flag for it.
The identities this package records are **not** the SDK-route ones, and that is the honest
result rather than a defect to paper over: `geometry_id` and `source_geometry_id` are digests of
positions and of the map's `world_xyz` surface, which the design frame and its differing UVs
state differently, and `field_domain.id` is the new map's. Consequence to expect: the device
description the app derives from `config/sensors/finger/assets/30fps-0703` (its `s0.4` map,
domain `feb7f71e…`) no longer matches, so the pane refuses the package with
`field_domain_mismatch` until that bundle carries the matching `unroll_map_uv_s0.42.npz` and
`camera.source_scale` `0.42`.
## Where the application looks for a package
1. `preference.json` → `"scene3d_package": "<path>"` (an absolute path; also the way