added mesh export preview
This commit is contained in:
@@ -299,6 +299,68 @@ every object separately, such as cutting or weeding. A failing `min_feature_mm`
|
||||
alongside a passing `nominal_cell.dots` means the artwork is fragmented, not that
|
||||
the pattern itself is unprintable.
|
||||
|
||||
## Preview the export
|
||||
|
||||
`orisys-design preview` opens the built export in a minimal PyOpenGL window so a
|
||||
revision can be checked before it reaches Studio: the sensing surface highlighted,
|
||||
the exported housing around it, and the exported camera frustum.
|
||||
|
||||
```powershell
|
||||
python -m pip install -e .[preview] # numpy, PyQt5, PyOpenGL
|
||||
orisys-design preview sensors/finger-xynova/r01
|
||||
```
|
||||
|
||||
Controls: left-drag orbit, middle/right-drag pan, wheel zoom, `H` toggle housing,
|
||||
`W` wireframe, `C` frustum. `--self-test` renders one frame, reports how many
|
||||
mesh pixels were drawn, and exits without waiting for a window — use it to check
|
||||
a machine's GL setup. `--screenshot PATH` writes that frame to a PNG so a view
|
||||
can be reviewed or shared without describing it. `--no-housing` and
|
||||
`--no-frustum` simplify the view.
|
||||
|
||||
Normals are crease-aware: faces are grouped per vertex and split where the
|
||||
dihedral angle exceeds `--crease-angle` (default 35°), so machined edges read as
|
||||
creases instead of smooth roll-offs. `--smooth` disables splitting. This matters
|
||||
because the housing is sharp and the sensing surface is not — 13.5% of `frame_L`
|
||||
edges exceed 30° while the sensing surface has none, and the default leaves its
|
||||
2508 vertices untouched.
|
||||
|
||||
Exit codes: `2` for a missing optional dependency, `3` for a payload that has not
|
||||
been exported, `4` when no OpenGL context can be created (the offscreen/minimal
|
||||
Qt platform cannot create one at all, so run on a desktop session).
|
||||
|
||||
### Housing is a separate artifact
|
||||
|
||||
`export` also writes **`housing.npz`** for the objects in the `ASSEMBLY`
|
||||
collection, transformed into the same sensor frame as the sensing surface. It is
|
||||
deliberately *not* merged into `mesh.npz`: `orisys-sdk`'s unroll consumes
|
||||
`mesh.npz` vertices as the sensing surface, so housing vertices there would
|
||||
corrupt it. Declare the collections with `--housing-collections` or via
|
||||
`design.yaml`'s `collections.assembly`.
|
||||
|
||||
### Lighting mirrors Studio, by value
|
||||
|
||||
This window reimplements a small renderer rather than importing Studio's, so the
|
||||
look is copied rather than shared. Every mirrored value — clear colour, light
|
||||
direction, the `0.35 + 0.65 * lambert` shading, housing graphite — lives in
|
||||
`preview/appearance.py` with the `gl_backend.py` line it came from, and
|
||||
`tests/test_preview.py` re-reads Studio's source and fails if it changes. That
|
||||
keeps the duplication honest and makes adopting real reuse a one-module swap.
|
||||
|
||||
The sensing surface is drawn in a preview-only highlight colour; Studio colours
|
||||
it from the measurement LUT instead. Treat this as a design-time check, not the
|
||||
authoritative renderer.
|
||||
|
||||
### One caveat about export units
|
||||
|
||||
The exported sensor frame is **not metres**. `origin_sensor` carries a uniform
|
||||
scale, so a ~21 mm assembly exports with bounds around ±574 units and
|
||||
`world_to_cam` is a scaled (non-rigid) pose: its rotation column norms are
|
||||
`0.003937` on Xynova, not `1`. Projection is still self-consistent — all 2508
|
||||
sensing vertices land inside the 1000×1000 frame — but any consumer that assumes
|
||||
metres will be wrong. The preview therefore frames the model from its own
|
||||
bounding sphere rather than Studio's fixed metre limits, and prints a warning
|
||||
when the pose is not rigid.
|
||||
|
||||
Collection check:
|
||||
|
||||
```powershell
|
||||
|
||||
Reference in New Issue
Block a user