Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
06922c3
refactor: rename imview module to viewer
rxdu Apr 26, 2026
96d125f
refactor: rename gldraw module to scene
rxdu Apr 26, 2026
d44d5d3
feat(plot): split ImPlot widgets out of widget/ into new plot/ module
rxdu Apr 26, 2026
0479241
feat(canvas): split Cairo widgets out of widget/ into new canvas/ module
rxdu Apr 26, 2026
fcb47c5
feat(image): merge cvdraw + widget's OpenCV widgets into new image/ m…
rxdu Apr 26, 2026
64fad97
docs: refresh CLAUDE.md and TODO.md for the new module layout
rxdu Apr 26, 2026
557a27a
refactor(scene): rename GlViewer → SceneApp, reframe as quickstart fa…
rxdu Apr 26, 2026
e637b8d
docs: rewrite CLAUDE.md as a tighter project contract
rxdu Apr 26, 2026
135070a
feat(core): add quickviz::demo::* synthetic data generators
rxdu Apr 26, 2026
c6b9a2a
feat(sample/quickstart): smallest possible QuickViz program
rxdu Apr 26, 2026
22ef647
feat(core): add quickviz::DataStream<T> for streaming sensor data
rxdu Apr 26, 2026
a8d126b
docs(TODO): roadmap for "truly useful, low-friction" robotics library
rxdu Apr 26, 2026
f672d85
docs(TODO): sharpen entries with audit results; nothing removed
rxdu Apr 26, 2026
1b3022b
feat(sample/streaming_demo): canonical sensor-streaming pattern
rxdu Apr 26, 2026
f9c93a8
feat(scene): OccupancyGrid renderable
rxdu Apr 26, 2026
54852f0
feat(scene): TfFrameTree renderable
rxdu Apr 26, 2026
1114780
docs: codify "external SDK deps must be optional" as a hard rule
rxdu Apr 26, 2026
27a2583
refactor(scene): move Triangle to scene/test/test_utils/
rxdu Apr 26, 2026
a12d66d
feat(scene/path): trajectory streaming extensions
rxdu Apr 26, 2026
a477e4f
feat(scene/path): per-pose orientation + ArrowMode::kPoseArrows
rxdu Apr 26, 2026
4f60a05
docs(TODO): tighten to a tracker; nothing else
rxdu Apr 26, 2026
63b42c1
cmake: leave pcl_bridge out if no pcl lib is found
rxdu May 3, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,6 @@
[submodule "third_party/stb"]
path = third_party/stb
url = https://github.com/rxdu/stb.git
[submodule "third_party/imcore/implot3d"]
path = third_party/imcore/implot3d
url = https://github.com/brenocq/implot3d
712 changes: 294 additions & 418 deletions CLAUDE.md

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ message(STATUS "------------------------------------------------")

## Project Options
option(ENABLE_AUTO_LAYOUT "Enable autolayout" ON)
option(IMVIEW_WITH_GLAD "Integrate glad into imview" ON)
option(VIEWER_WITH_GLAD "Integrate glad into viewer" ON)
option(BUILD_QUICKVIZ_APP "Build quickviz app" OFF)
option(BUILD_TESTING "Build tests" OFF)
option(QUICKVIZ_DEV_MODE "Development mode forces building tests" OFF)
Expand Down Expand Up @@ -153,7 +153,7 @@ endforeach ()

# targets to install defined in each module
add_library(quickviz INTERFACE)
target_link_libraries(quickviz INTERFACE core imview widget gldraw visualization)
target_link_libraries(quickviz INTERFACE core viewer widget scene visualization)

# export target configuration
include(CMakePackageConfigHelpers)
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@

This repository provides a collection of C++ libraries for creating data visualization and basic UI applications, primarily focused on use cases in robotics.

* For UI design, `imview` includes automatic layout management and widgets such as buttons, sliders, and text boxes.
* For data visualization, `imview` and `renderer` provide a set of API functions to easily plot 2D time-series data, draw 2D primitives and render 3D objects in real-time.
* For UI design, `viewer` includes automatic layout management and widgets such as buttons, sliders, and text boxes.
* For data visualization, `viewer` and `renderer` provide a set of API functions to easily plot 2D time-series data, draw 2D primitives and render 3D objects in real-time.

The design of the libraries is documented in [docs/imview_design.md](docs/imview_design.md) and [docs/renderer_design.md](docs/renderer_design.md). If you are interested in using the libraries in your own project, it's recommended to read the design documents first. Additionally, an app named "quickviz" is included with commonly used data visualization functions (to support development of [libxmotion](https://github.com/rxdu/libxmotion)). It also serves as an example to demonstrate the usage of the `imview` library.
The design of the libraries is documented in [docs/viewer_design.md](docs/viewer_design.md) and [docs/renderer_design.md](docs/renderer_design.md). If you are interested in using the libraries in your own project, it's recommended to read the design documents first. Additionally, an app named "quickviz" is included with commonly used data visualization functions (to support development of [libxmotion](https://github.com/rxdu/libxmotion)). It also serves as an example to demonstrate the usage of the `viewer` library.

<table>
<tr>
Expand Down
188 changes: 100 additions & 88 deletions TODO.md
Original file line number Diff line number Diff line change
@@ -1,110 +1,122 @@
# QuickViz Implementation Tracker
# QuickViz TODO

*Last Updated: April 26, 2026*
*Purpose: Track implementation status and priorities*
*Last updated: 2026-04-26*

## Mission
Tracker only. Mission, conventions, and module structure live in
[`CLAUDE.md`](CLAUDE.md). Older history: `git log`.

QuickViz is a **visualization-first** C++ library for robotics. The library
provides building blocks (rendering, UI, selection, tools) that consuming
applications compose. Editor / app-level concerns (commands, undo/redo,
project files, history) live in `sample/` or downstream apps, never in `src/`.
---

`sample/editor/` (planned) is the dogfood check: if a vis+editing app cannot
be built on top of `src/` without modifying `src/`, the library is missing
a visualization-justified hook.
## 🎯 Active priorities (in order)

### 1. ROS2 bridge — `bridges/ros2/`
ROS2 is **optional** in CMake; the library must build and run without
it (CLAUDE.md §4 "Optional external dependencies").

- [ ] `bridges/` umbrella + `bridges/ros2/` first child, CMake-gated
- [ ] `sensor_msgs::PointCloud2` ↔ `PointCloud`
- [ ] `geometry_msgs::PoseStamped` / `PoseArray` ↔ `Path` (with orientations)
- [ ] `nav_msgs::OccupancyGrid` ↔ `OccupancyGrid`
- [ ] `tf2_msgs::TFMessage` ↔ `TfFrameTree`
- [ ] `visualization_msgs::Marker` / `MarkerArray` ↔ generic primitives
- [ ] Sample app demonstrating ROS2 streaming end-to-end (also gated)

### 2. Diagnostics
- [ ] HUD overlay: frame time, draw calls, GPU mem, scene object count, active tool
- [ ] Structured logger (replaces ~232 `std::cerr/cout` in `src/`, mostly in `scene` and `viewer`)
- [ ] Visible UI surface for shader/asset load failures

### 3. Documentation site
- [ ] Doxygen + GitHub Pages
- [ ] `docs/tutorial/01-quickstart.md`
- [ ] `docs/tutorial/02-editor.md`
- [ ] `docs/tutorial/03-streaming.md`
- [ ] `docs/tutorial/04-custom-renderable.md`
- [ ] `docs/tutorial/05-ros2.md` (after bridge lands)

---

## 🎯 Active Work

### Reshape — bring the codebase back to visualization-first
- [x] Delete `src/scenegraph/` (state mgmt + command pattern + bridge that
fabricated data — see commit `af77ad4`)
- [x] Delete `sample/object_management/` (demo of the deleted bridge)
- [x] CI `boundary-check` job: `src/` may not include from `sample/`
- [x] Update CLAUDE.md, archive stale design docs
- [ ] Build `sample/editor/` MVP as the API completeness check
(load PCD/PLY → render → select → DeleteSelectedPoints → undo/redo
via app-side `CommandStack` → minimal history panel)
- [ ] Add library hooks discovered while building the sample (additive only).
Logged candidates from sample/editor MVP:
- `SceneManager::GetObjectId(name) / GetObjectName(id)` so editors can
avoid relying on stringly-typed cloud names.
- `PointSelection::object_id` so selection callbacks don't need
string-equality on cloud_name.
- `PointCloud::SetActiveMask(span<bool>)` or `SetActiveIndices(...)` so
editing a point cloud doesn't require rebuilding the full vertex
buffer on every command (current MVP rewrites all visible points).
- Stable point-identity for selection persistence across cloud
mutations (today the editor must `ClearSelection()` on every
rebuild because the tool tracks visible indices).
Re-evaluate each one against the "is this a visualization concern?"
bar before merging to src/.

### Known visualization gaps
- [ ] Selection support for Arrow, Plane, Path, Triangle, Pose primitives
- [ ] LOD system for >1M point scenes
- [ ] `PCLLoaderTest.InvalidFileError` is failing — modern PCL no longer
throws on corrupt PCDs; rewrite the test to match current behavior
- [ ] Move bundled fonts from `core/include` to `resources/`
- [ ] Replace `std::cerr` / `std::cout` debug spew in library code with a
lightweight logger (also audit for leftover noise after the deletions)

### Smaller cleanups
- [ ] `src/gldraw/src/renderable/canvas.cpp` is 2069 LOC; split into
cohesive sub-files (~500 LOC target per CLAUDE.md)
- [ ] Audit `interactive_scene_manager.cpp` for disabled/legacy paths left
over from the editor migration; either finish or remove
## 📋 Backlog

---
### Onramp
- [ ] Layout presets — `viewer::layout::SidebarLeft(width)` etc.
- [ ] `viewer::AppState` — window pos, camera, panel sizes persisted

### Tools / data
- [ ] Recording + replay for `DataStream` — `core/Record<T>` / `core/Replay<T>`

### Performance
- [ ] LOD system for >1M point scenes (octree-based)

## ✅ Recently Completed
### Extension
- [ ] Plugin system (defer until concrete user)

### April 2026
- ✅ **Reshape: visualization-first re-anchor** — Removed the in-library
state management module (`scenegraph`) and its sample (`object_management`).
Locked the `src/ ↛ sample/` boundary in CI and CLAUDE.md. Editor concerns
are now built on top of the library, not inside it. Stale architecture and
design docs archived. (commits `af77ad4`, `079eb2b`)
### Robotics gold demo
- [ ] Composite sample: robot driving through occupancy grid with
streaming cloud + trajectory + frustum + small dashboard

### September 2025
- ✅ CameraController refactor (Strategy pattern, configurable parameters,
utility methods)
- ✅ Input debug message cleanup
- ✅ GLDraw architecture review
---

### December 2024
- ✅ ThreadSafeQueue, BufferRegistry, AsyncEventDispatcher modernization
## 🔧 Library hooks (from sample/editor)

### September 2024
- ✅ Configurable camera controls (Modeling/FPS/CAD/Scientific styles)
- ✅ Unified input system with gamepad support
- ✅ Selection support for LineStrip, Mesh, Cylinder, BoundingBox
Re-evaluate each against "is this a visualization concern?" before merging.

### Core Infrastructure
- ✅ CMake build system with module-private include layout
- ✅ GoogleTest integration
- ✅ Multi-layer point cloud system (60-100x batching speedup)
- ✅ GPU ID-buffer selection (16.5M point capacity)
- ✅ GeometricPrimitive template pattern
- [ ] `SceneManager::GetObjectId(name)` / `GetObjectName(id)`
- [ ] `PointSelection::object_id` (drop string-equality on `cloud_name`)
- [ ] `PointCloud::SetActiveMask(span<bool>)` or `SetActiveIndices(...)`
- [ ] Stable point identity across cloud rebuilds (selections survive)

---

## 📊 Status Summary
## 🐛 Visualization gaps

**Branch**: `feature-pointcloud_editing` (will rename once the editor sample
is in place)
**Focus**: Re-anchor the library on visualization, then build the editor
sample as the API check.
**Architecture**: Library = `core` + `imview` + `widget` + `gldraw` +
`pcl_bridge` + `cvdraw` (optional). Apps live in `sample/`.
- [ ] Selection support for `Arrow`, `Plane`, `Path`, `Pose` primitives
- [ ] `PCLLoaderTest.InvalidFileError` — modern PCL no longer throws
on corrupt PCDs; rewrite test against current behavior
- [ ] Move bundled fonts from `core/include/` to top-level `resources/`

---

## 📝 Notes
## 🧹 Cleanups

- [ ] `GeometricPrimitive` 405-LOC header — design review (likely
API-breaking)
- [ ] `scene/src/renderable/canvas.cpp` 2069 LOC — split (~500 target)
- [ ] `sample/pointcloud_viewer/interactive_scene_manager.cpp` —
empty `HandleMouseInput()` line 141, disabled callback line 113,
stale TODO line 107
- [ ] `sample/quickviz_demo_app/` — audit for boilerplate after layout
presets land

---

- See `docs/notes/` for design deep-dives (rendering, picking, input)
- See `CLAUDE.md` for project guidelines and module boundaries
- Update this file after finishing tasks; keep entries terse, factual,
and one bullet per outcome
## ✅ Recent (current iteration)

Use `git show <hash>` for full context.

- `a477e4f` Path: per-pose orientation + `ArrowMode::kPoseArrows`
- `a12d66d` Path: trajectory streaming extensions
(`AddPoint(p, scalar)`, `EnableAutoColorRange`,
scalar-color subdivision fix)
- `27a2583` Triangle moved to `scene/test/test_utils/`;
new `scene_test_utils` library
- `1114780` ROS-optional CMake rule codified (CLAUDE.md §4)
- `54852f0` `TfFrameTree` renderable
- `f9c93a8` `OccupancyGrid` renderable
- `1b3022b` `sample/streaming_demo/`
- `f672d85` TODO audit
- `a8d126b` TODO roadmap rewrite
- `22ef647` `quickviz::DataStream<T>`
- `c6b9a2a` `sample/quickstart/`
- `135070a` `quickviz::demo::*` synthetic generators
- `e637b8d` CLAUDE.md rewrite (470 → 308 lines)
- `557a27a` `GlViewer` → `SceneApp` rename + reframe
- `64fad97` Module-reorg docs refresh
- `fcb47c5` New `image/` module (cvdraw + widget cv parts)
- `0479241` New `canvas/` module (Cairo bits of widget)
- `d44d5d3` New `plot/` module (ImPlot + ImPlot3D)
- `96d125f` `gldraw` → `scene` rename
- `06922c3` `imview` → `viewer` rename
- `2109140` Mission docs realigned, stale design docs deleted
- `079eb2b` `src/ ↛ sample/` boundary locked in CI + CLAUDE.md
- `af77ad4` Removed in-library state-mgmt module + bridge sample
12 changes: 6 additions & 6 deletions docs/imview_design.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
# ImView Design

For GUI applications, imview provides automatic layout management and commonly used UI widgets such as buttons, sliders, and text boxes.
For GUI applications, viewer provides automatic layout management and commonly used UI widgets such as buttons, sliders, and text boxes.

## Implementation

### Core Components

* **Window management**: imview uses GLFW for window management. GLFW is a lightweight library that provides a simple API for creating windows and handling input events. GLFW is cross-platform and supports Windows, macOS, and Linux.
* **UI**: imview uses `Dear ImGui`, a lightweight GUI library that provides a simple API for creating UI elements.
* **2D plotting**: imview uses `ImPlot` for 2D plotting. ImPlot is a lightweight plotting library built on top of `Dear ImGui`.
* **Window management**: viewer uses GLFW for window management. GLFW is a lightweight library that provides a simple API for creating windows and handling input events. GLFW is cross-platform and supports Windows, macOS, and Linux.
* **UI**: viewer uses `Dear ImGui`, a lightweight GUI library that provides a simple API for creating UI elements.
* **2D plotting**: viewer uses `ImPlot` for 2D plotting. ImPlot is a lightweight plotting library built on top of `Dear ImGui`.

The class diagram below shows the main classes in the imview library:
The class diagram below shows the main classes in the viewer library:

```mermaid
---
title: imview core components
title: viewer core components
---
classDiagram
Window <|-- Viewer
Expand Down
12 changes: 6 additions & 6 deletions docs/notes/canvas_optimization_analysis.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Canvas implements a **production-grade optimization architecture** with sophisti

### 1. **Advanced Batching System** ✅ **ALREADY IMPLEMENTED**

**Files**: `src/gldraw/include/gldraw/renderable/details/canvas_batching.hpp`
**Files**: `src/scene/include/scene/renderable/details/canvas_batching.hpp`

**Architecture**:
- **Multi-tier batching system** with separate batches for different primitive types:
Expand Down Expand Up @@ -49,7 +49,7 @@ struct BatchOrderTracker {

### 2. **Comprehensive Performance Monitoring** ✅ **ALREADY IMPLEMENTED**

**Files**: `src/gldraw/include/gldraw/renderable/details/canvas_performance.hpp`
**Files**: `src/scene/include/scene/renderable/details/canvas_performance.hpp`

**Features**:
- **Real-time rendering statistics** with detailed metrics:
Expand Down Expand Up @@ -92,7 +92,7 @@ struct PerformanceConfig {

### 3. **Thread-Safe Data Management** ✅ **ALREADY IMPLEMENTED**

**Files**: `src/gldraw/src/renderable/details/canvas_data_manager.hpp/.cpp`
**Files**: `src/scene/src/renderable/details/canvas_data_manager.hpp/.cpp`

**Architecture**:
- **Complete thread-safe operation** with mutex protection on all data access
Expand Down Expand Up @@ -132,7 +132,7 @@ public:

### 4. **GPU Resource Pool Management** ✅ **ALREADY IMPLEMENTED**

**Files**: `src/gldraw/src/renderable/details/opengl_resource_pool.hpp`
**Files**: `src/scene/src/renderable/details/opengl_resource_pool.hpp`

**Features**:
- **VAO/VBO pooling system** to eliminate per-frame OpenGL resource allocation
Expand Down Expand Up @@ -169,8 +169,8 @@ public:
### 5. **Dual Render Strategy System** ✅ **ALREADY IMPLEMENTED**

**Files**:
- `src/gldraw/src/renderable/details/batched_render_strategy.hpp`
- `src/gldraw/src/renderable/details/individual_render_strategy.hpp`
- `src/scene/src/renderable/details/batched_render_strategy.hpp`
- `src/scene/src/renderable/details/individual_render_strategy.hpp`

**Architecture**:
- **Strategy pattern implementation** with runtime switching:
Expand Down
16 changes: 8 additions & 8 deletions docs/notes/core_imview_code_quality.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Date: 2025-09-01

This document captures targeted, high‑impact improvements for the `core` and `imview` modules. Items are grouped by module with concrete actions and file pointers.
This document captures targeted, high‑impact improvements for the `core` and `viewer` modules. Items are grouped by module with concrete actions and file pointers.

## Core

Expand Down Expand Up @@ -49,20 +49,20 @@ This document captures targeted, high‑impact improvements for the `core` and `

### Centralize input: single InputManager per Window
- Problem: `Panel` keeps its own `InputManager` and polls ImGui state; `Window` also owns an `InputManager`.
- Files: `src/imview/include/imview/panel.hpp`, `src/imview/src/panel.cpp`, `src/imview/include/imview/window.hpp`, `src/imview/src/window.cpp`
- Files: `src/viewer/include/viewer/panel.hpp`, `src/viewer/src/panel.cpp`, `src/viewer/include/viewer/window.hpp`, `src/viewer/src/window.cpp`
- Improve:
- Panels should register as `InputEventHandler`s on the Window’s single `InputManager`; provide `AttachTo(Window&)` or inject via ctor.
- Poll ImGui once per frame at the Window and dispatch through the centralized `InputDispatcher`.

### ImGui capture and debug output
- Problem: Hidden Ctrl+Shift+K bypass and periodic `std::cout` noise in release.
- File: `src/imview/src/input/imgui_input_utils.cpp`
- File: `src/viewer/src/input/imgui_input_utils.cpp`
- Improve: Gate with `#ifdef QUICKVIZ_INPUT_DEBUG` or a runtime flag; route through logger. Make bypass behavior configurable via `InputManager`/Window settings.

### GamepadManager: state ownership, singleton removal path
- Problems:
- `GamepadManager` is a singleton; `ImGuiInputUtils` uses a static `previous_states` map outside the manager.
- Files: `src/imview/include/imview/input/gamepad_manager.hpp`, `src/imview/src/input/gamepad_manager.cpp`, `src/imview/src/input/imgui_input_utils.cpp`
- Files: `src/viewer/include/viewer/input/gamepad_manager.hpp`, `src/viewer/src/input/gamepad_manager.cpp`, `src/viewer/src/input/imgui_input_utils.cpp`
- Improve:
- Move previous-state tracking into `GamepadManager` per device and expose delta-friendly queries.
- Long term: make `GamepadManager` instance-owned by `Window` (align with `InputManager`).
Expand All @@ -73,13 +73,13 @@ This document captures targeted, high‑impact improvements for the `core` and `

### Window lifecycle: GLFW ownership
- Problem: `Window::~Window()` calls `glfwTerminate()` unconditionally; breaks multi-window use.
- File: `src/imview/src/window.cpp`
- File: `src/viewer/src/window.cpp`
- Improve: Centralize GLFW init/term in an `Application`-level owner or use ref-counting; windows only destroy their own contexts.

### CMake options and link scopes
- Add `option(ENABLE_AUTO_LAYOUT ...)`, `option(ENABLE_TUI_SUPPORT ...)`, `option(IMVIEW_WITH_GLAD ...)` with defaults and help strings.
- Add `option(ENABLE_AUTO_LAYOUT ...)`, `option(ENABLE_TUI_SUPPORT ...)`, `option(VIEWER_WITH_GLAD ...)` with defaults and help strings.
- Use proper scope for compile definitions and link interfaces; minimize PUBLIC exposure.
- Files: `src/imview/CMakeLists.txt`, `src/core/CMakeLists.txt`
- Files: `src/viewer/CMakeLists.txt`, `src/core/CMakeLists.txt`

## Cross‑Cutting

Expand Down Expand Up @@ -109,6 +109,6 @@ This document captures targeted, high‑impact improvements for the `core` and `

## Notes
- Related references in-tree:
- BufferRegistry usages: search for `BufferRegistry::GetInstance()` across `widget/` and `gldraw/`.
- BufferRegistry usages: search for `BufferRegistry::GetInstance()` across `widget/` and `scene/`.
- Existing design notes: `docs/notes/core_module_review_2025-01-28.md`.

Loading
Loading