12 Commits

Author SHA1 Message Date
ykcheungab f700102067 docs: record the GUI extraction plan, postponed
examples/gui/ is a full Qt + open3d application (30 modules, 4,815 lines) rather
than an example, and its proper home is the orisys-studio application. The move
is planned but not started, so this records the plan rather than performing any
of it.

What the plan establishes, so the work does not have to be re-derived:

- src/orisys/ imports no gui/viz/examples module, verified by AST rather than
  grep. The dependency is one-way, so the GUI can leave without a library
  change. The single apparent hit is `from .pipeline import ...` in
  src/orisys/__init__.py, which is the SDK's own module.
- examples/viz/ is shared and cannot follow the GUI wholesale: it mixes open3d
  renderers with toolkit-independent helpers that examples/pipeline/service.py
  and tests/test_contact_arrow_scale.py depend on. It has to be split.
- The real coupling is inverted and lives in the tests: tests/test_qt_viewer_backend.py
  imports examples/gui, and tests/conftest.py deliberately puts examples/ ahead
  of build/ because both define a package named `gui`. Removing the GUI means
  re-deriving that guard, not deleting it blindly.
- UVMeshViewer and friends are in src/orisys/finger/__init__.__all__, so removing
  them is a breaking change to a released API and needs a deprecation release
  first. It must not be folded into a code move.
- The `examples/` directory must keep existing in the packaged layout even after
  gui/ leaves it: src/orisys/configs.py anchors its run-root detection on a
  sibling examples/ folder.

Also updates examples/README.md to say "lives here for now" instead of "is moving
out", so nothing reads as work in progress. The GUI itself is untouched, and the
only guidance offered is that new SDK work should not build on it.
2026-09-30 17:10:17 +08:00
ykcheungab b5d7533e24 examples: make StreamPipeline the recommended entry, archive the manual loop
The two canonical examples taught the advanced path: they sequenced
get_img() -> compute_deformation() -> compute_contact() -> read_info() by hand
and unpacked a 13-element tuple positionally, which is what led developers to
reach for the compute backend, the capture queue and the stitch mode. The
managed alternative already existed and was documented nowhere.

Library (add-only, nothing removed):

- FrameSnapshot.image_size_raw carries the capture resolution, so a caller can
  compare it with the processed frame instead of reaching into Sensor.
- StreamPipeline.reset() resets the tracker and force filters *safely*. It is
  queued and applied by the flow stage before its next frame, never inline:
  Sensor.reset rebases initial_img on the current Sensor.img, which the flow
  stage is reading concurrently, so a caller-thread reset would capture a
  half-written reference frame. Idempotent.
- TactileProcessor.pipeline(produce) and FingerRuntime.pipeline() build a
  pipeline without the caller naming a backend concept; the latter is
  `with runtime.pipeline(contact=True) as pipe`.

Examples:

- examples/basic_pipeline.py and examples/finger_pipeline.py rewritten onto
  StreamPipeline + FrameSnapshot: one object, one call per frame, no tuple, and
  no compute backend, queue or stitch setting in sight.
- examples/archive/basic_pipeline_manual.py and _finger_pipeline_manual.py keep
  the previous versions byte-for-byte apart from a supersede header, so code
  copied from them keeps working. The finger header also records the archived
  --show defect (store_true with default=True, so it could never be disabled).
- examples/_display.py holds the shared display helpers, so an example no longer
  hand-rolls depth normalisation and colormap application.
- examples/README.md leads with the recommended pair and documents the manual
  form as still-supported, and states that examples/gui/ is moving to
  orisys-studio.

Tests: three added to tests/test_pipeline.py, covering the reset queue (it must
not run on the caller's thread and must land before the first compute_flow),
image_size_raw, and the None case when a producer reports no size. Verified the
reset test fails when reset() is made inline, so it discriminates.

Verified end-to-end against real media: basic_pipeline on data/sample/s1_480p.mp4
(box) reaches ~113 FPS and exits 0; finger_pipeline on data/dd02-0703/1.mp4
(finger) reaches ~140 FPS with mask coverage 0.41 and exits 0. Both archived
manual versions still run. tests/test_pipeline.py: 20 passed. Full suite:
342 passed, 3 failed - all three failures reproduce on the pristine tree
(import precedence, longrun timing, and a stale ruff version literal in
docs/code-review.md) and are unrelated to this change.
2026-09-30 17:09:02 +08:00
ykcheungab 2e09c9360e included low pass filter in package and add to plot_data example 2026-08-17 22:11:17 +08:00
ykcheungab 3117ddd5b9 organize exampels according to products 2026-08-03 15:52:15 +08:00
ykcheungab 87ac152907 update csv export and added fixed mesh axis drawing 2026-07-15 14:25:03 +08:00
zhangyijian d58fa1caa2 moved examples/app_paths.py into gui 2026-07-12 19:54:32 +08:00
ykcheungab c2fb0b12b5 AI 更新文档 2026-07-09 14:03:45 +08:00
ykcheungab 9317bb3942 update examples read.me 2026-06-30 09:55:41 +08:00
ykcheungab 7feae9550e update exe GUI build 2026-06-21 12:01:34 +08:00
ykcheungab 3fd9b839a9 GUI for finger v1 2026-06-18 22:18:19 +08:00
ykcheungab f19f092b64 split example visualizaiton pipeline 2026-06-18 13:47:16 +08:00
ykcheungab d38ce82059 clean up folder 2026-05-10 17:41:39 +08:00