Neural Capture · Demo: open Demo tour

Monograph · 01 · Architecture

01

Foundations · implementation

Architecture

Chapter contract

Owns system spine, module boundaries, threading model, and what “one capture system” means. Must not own Sapera Snap details (ch.02) or RC evaluation (ch.09). Done when a reader can sketch WinUI → CaptureCore → Camera / BLE / Session without opening the repo.

Role in the system

CamMatrixCapture is the acquisition product for multi-view neural rendering datasets. It does not train NeRFs. It owns: discover industrial cameras, drive a BLE turntable, capture synchronized multi-view stacks, and write a session tree that offline tools (RealityCapture, Nerfstudio) can consume.

Call graph at the top: WinUI pages call CaptureService (C# P/Invoke) → CamMatrix_* exports in CaptureAPICameraManager / BluetoothManager / SessionManager / CaptureStateMachine.

System spine

System spine diagram
Fig. ARCH-1

Spine. Didactic diagram of live code modules. Offline thesis pipeline is a consumer of TIFF sessions, not inside the DLL.

Module boundaries

ModuleOwnsMust not own
API / SMC exports, capture-rotation state machine, timing countersUI layout
HardwareSapera devices, Snap/Wait, color config, parallel groupsBLE protocol
BluetoothScan, connect, turntable commandsImage buffers
Capture controllerWorker thread sequence over positionsSfM
SessionPaths, session ids, capture path allocationCamera SDK
GUIWizard UX, polling, settings dialogsDirect Sapera calls
Thesis offlineRC / Nerfstudio / metricsLive capture thread

Threading model

  • UI thread — WinUI dispatcher; never blocks on Snap
  • Capture workerAutomatedCaptureController std::thread walks positions
  • Camera ops — sync Snap/Wait in C++; async wrappers via Task.Run / CaptureAllCamerasAsync
  • BLE — WinRT async / co_await style device IO
  • Status — UI polls CamMatrix_GetCaptureState every ~200–500 ms
Algorithm · cold start (operator)
  1. Launch WinUI host → load settings.ini via CamMatrix_LoadSettings
  2. Connect page: discover GigE + BLE scan
  3. Setup page: choose 36/72/custom positions
  4. Capture page: CamMatrix_StartCapture → worker thread
  5. Done page: open session path under neural_dataset/
Invariant

Capture and rotation must not interleave without the state machine. Invalid events are rejected (logged REJECTED: Event …) rather than silently applied — see ch.04.

Design decisions that landed

Decision

C++ hardware core + C# wizard

Why

Sapera and BLE want native code; operators need a simple wizard. P/Invoke keeps a hard boundary: UI cannot hold SapBuffer pointers.

Code: src/api/CaptureAPI.*, App/Services/CaptureService.cs

Decision

Session folder as the integration contract

Why

Offline tools do not speak CaptureCore. neural_dataset/session/pos_XXX/cam_YY.tiff is the stable handoff.

Source map

src/api/CaptureAPI.*C exports CamMatrix_*
src/api/CaptureStateMachine.*Idle/Capturing/Rotating/Settling/Error
src/hardware/CameraManager.*Sapera discovery + capture groups
src/bluetooth/*BLE + turntable controller
src/capture/AutomatedCaptureController.*Worker sequence
src/utils/SessionManager.*Paths + session metadata
App/Pages/*Page.xamlWizard UI

How to go deeper

  1. Read CaptureStateMachine::IsValidTransition table end-to-end
  2. Trace CameraManager::CaptureAllCameras Snap vs save phases
  3. Run a 36-step dry session and inspect folder layout