diff --git a/.gitmodules b/.gitmodules index 72bdfad..4294597 100644 --- a/.gitmodules +++ b/.gitmodules @@ -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 diff --git a/CLAUDE.md b/CLAUDE.md index 4bf38cc..8b95fae 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,452 +1,328 @@ # QuickViz Project Guidelines -This document provides comprehensive guidance for working with the QuickViz C++ visualization library for robotics applications. - -## Project Overview - -QuickViz is a C++ visualization library for robotics applications, providing: -- **imview**: Automatic layout management and UI widgets (buttons, sliders, text boxes) -- **gldraw**: 2D/3D real-time rendering with OpenGL -- **widget**: Cairo-based drawing and plotting widgets -- **core**: Event system, buffers, and shared utilities - -## Core Development Principles - -### Design Philosophy -- **Small surface, strong contracts**: Keep public APIs minimal and explicit; hide implementation details -- **Seams before abstractions**: Extract clear boundaries first; abstract later if duplication persists -- **Single responsibility**: Each module/file does one thing well (target ~500 LOC per file) -- **Local reasoning**: Callers shouldn't need global state knowledge to use an API -- **Performance by design**: Favor data-oriented layouts, predictable memory, and measured hot paths -- **Determinism over cleverness**: Prefer simple, reproducible behavior to smart but fragile logic -- **Building blocks philosophy**: Provide generic, composable components that users can combine to build domain-specific applications. Use generic terms (geometry, mesh, camera, viewport) rather than application-specific terminology (map, terrain, navigation) - -### Library Interface Boundaries -QuickViz is designed as a toolkit of building blocks for robotics visualization applications. The interface design clearly distinguishes between different levels of user interaction: - -**Direct Use Components** (Ready-to-use, minimal configuration): -- Core rendering primitives (points, lines, meshes, textures) -- Standard UI widgets (buttons, sliders, text inputs) -- Camera controllers and viewport management -- File I/O utilities (image, mesh formats) - -**Configurable Components** (Parameters and settings exposed): -- Rendering passes and shaders (lighting models, post-processing) -- Layout managers and containers -- Event handling and input mapping -- Color schemes and visual styling - -**Extensible Components** (Virtual interfaces for inheritance): -- `Renderable`, `InputHandler`, `SceneObject` interfaces -- Custom drawing and interaction tools -- Specialized data visualization widgets -- Custom file format adapters - -**Build-Upon Components** (Library hooks apps compose into bigger frameworks): -- Scene composition (`SceneManager` + `OpenGlObject` registration) -- Tool registration (`InteractionTool` interface + `ToolManager`) -- Threading and job hand-off boundaries -- Custom data adapters (e.g., `pcl_bridge` pattern) - -> Editor-shaped frameworks — command/undo stacks, scene graphs with parent/child -> hierarchies, project-file persistence, history panels — are **not** part of the -> library. They live in consuming apps (see `sample/editor/` for a reference -> implementation) and are built on top of the hooks above. - -> **Design Rule**: Generic robotics and graphics terminology should be preferred over domain-specific names. For example, use "Mesh", "PointCloud", "Camera" rather than "Map", "Scan", "Observer". This ensures the library remains broadly applicable across different robotics applications. - -### When to Create or Split Modules -Create (or split) a module when: -- **Two or more** other modules depend on a concept -- The code has **distinct lifecycles** (e.g., GPU resources vs. CPU parsing) -- You need to **swap implementations** behind an interface -- You want **separate testability** (unit tests without GL context) - -**Do not** create a module if it only wraps 1-2 functions without clear benefit. - -## Architecture & Dependencies - -### Module Structure +QuickViz is a C++ visualization library for robotics. Its goal is to let +users build a working UI/visualization tool with minimal boilerplate, then +keep growing the tool from there. This document is the contract for how the +codebase is organized and the rules contributors (human or agent) must +follow. + +If anything in this file conflicts with code on disk, the code wins — +update this file in the same change. + +--- + +## 1. Mission + +- **Visualization first.** The library renders, displays, and interacts. + It does not run editors, manage projects, persist documents, or model + application state. Those belong in apps built *on top* of the library. +- **Building blocks, not a framework.** Provide composable pieces; let + apps decide the architecture. No global state, no singletons exposed in + public headers, no hidden lifecycles. +- **Generic over domain-specific.** Use graphics/robotics terms (`Mesh`, + `PointCloud`, `Camera`) rather than app terms (`Map`, `Scan`, + `Observer`). Keeps the library reusable across robotics applications. + +--- + +## 2. Module Map + ``` src/ -├── core/ # Event system, buffers, utilities (depends on nothing) -├── imview/ # GLFW window management, ImGui integration -├── widget/ # Cairo drawing, image widgets, plotting -├── gldraw/ # OpenGL 3D rendering, point clouds, textures -├── pcl_bridge/ # Optional PCL adapter (file loading, conversions) -├── cvdraw/ # OpenCV-based drawing utilities (optional bridge) -└── third_party/ # imgui, implot, stb, yoga, googletest - -sample/ # Reference applications built ON TOP of the library +├── core/ # events, buffers, threading helpers +├── viewer/ # window + panels + layout (GLFW + ImGui + Yoga) +├── scene/ # interactive 3D scene rendering (OpenGL) +├── plot/ # data charts (ImPlot 2D + ImPlot3D) +├── canvas/ # 2D vector drawing (Cairo) +├── image/ # image display & annotation (OpenCV, optional) +└── pcl_bridge/ # PCL adapter (optional) + +third_party/ # imgui, implot, implot3d, stb, yoga, googletest +sample/ # reference applications built on top of the library +tests/ # cross-module integration tests +docs/ # design notes, architecture references ``` -### Dependency Rules -- **Core** (math, logging, utilities) depends on nothing else -- **Model** (scene/data types, transforms, selection) may depend on Core -- **Graphics** (GL wrappers, passes, shaders) may depend on Core and Model -- **Tools/Interaction** (picking, gizmos, measure) may depend on Graphics + Model -- **UI** (ImGui panels, docking) can depend on everything but is never depended on -- **Bridges/Adapters** (OpenCV/PCL/etc.) depend outward; nothing core depends on them - -> **Rule**: Lower layers never include headers from higher layers - -### Library Boundary: `src/` is visualization-only -QuickViz is a visualization library. Editor / app-level concerns -(undo/redo, command history, scene serialization, project files, editing -operations) live in `sample/` and consume the library, never the reverse. - -- `sample/*` may include from `src/*/include/` and link against library targets. -- `src/*` must not include from `sample/`. Enforced by CI (`boundary-check`). -- If a sample needs something from the library, add it as an additive, - visualization-justified hook to the library — do not pull sample code in. -- Sample applications also serve as a dogfood check: if a fully-featured - vis+editing app cannot be built on top of `src/` without modifying `src/`, - the library is missing a hook and we evaluate the gap deliberately. - -### Key Design Patterns - -#### 1. Scene Object Hierarchy (imview) -- `Window` → `Viewer` → `SceneObject` -- `SceneObject` implements: `Renderable`, `Resizable`, `InputHandler` -- `Panel` extends `SceneObject` for ImGui panels -- `Box` provides container with automatic layout via Yoga - -#### 2. OpenGL Rendering Pipeline (gldraw) -- `GlSceneManager` manages OpenGL objects and framebuffer -- `OpenGlObject` interface for all renderable 3D objects -- Render-to-texture approach with `FrameBuffer` -- `Camera` + `CameraController` for 3D navigation - -#### 3. Multi-Layer Point Cloud System -- `LayerManager` handles multiple rendering layers with priorities -- `PointLayer` for subset rendering with custom colors/sizes -- PCL bridge utilities for integration with Point Cloud Library - -## Build System & Dependencies - -### Initial Setup -```bash -# Clone with submodules -git clone --recursive https://github.com/rxdu/quickviz.git -git submodule update --init --recursive +Pick a module by **what you want to do**, not by which backend it uses: -# Install dependencies (Ubuntu 22.04/24.04) -sudo apt-get install libgl1-mesa-dev libglfw3-dev libcairo2-dev \ - libopencv-dev libglm-dev libncurses-dev +| I want to… | Module | +| --------------------------------------------- | ------------- | +| Open a window with panels | `viewer` | +| Show a 3D scene (robots, point clouds, mesh) | `scene` | +| Plot a chart of data (2D or 3D) | `plot` | +| Draw a custom 2D figure | `canvas` | +| Display or annotate camera images | `image` | +| Load PCL data | `pcl_bridge` | +| Use shared infrastructure | `core` | -# Optional: Install PCL for point cloud features -sudo apt-get install libpcl-dev +Domain modules stay tech-neutral so a future Vulkan-backed `scene` or +libpng-backed `image` slot in without churn. Inside each module, +implementation-specific types keep an explicit prefix (`Gl*` in `scene`, +`Cv*` in `image`). -# Optional: Development tools -sudo apt-get install valgrind libbenchmark-dev lcov -``` +### Quickstart classes worth knowing -### Build Configuration -```bash -mkdir build && cd build -cmake .. -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=ON -make -j8 -``` +- **`quickviz::Viewer`** (`viewer/viewer.hpp`) — the GLFW window + ImGui + app shell. The fundamental primitive every QuickViz app starts from. +- **`quickviz::SceneApp`** (`scene/scene_app.hpp`) — five-line + quickstart for a 3D viewer. Wraps `Viewer + GlScenePanel + grid + + coordinate frame`. Use this when you want to display a scene fast; + drop down to `Viewer` directly when you need richer layouts. -### CMake Options -- `BUILD_TESTING`: Enable tests (OFF by default) -- `QUICKVIZ_DEV_MODE`: Development mode, forces tests (OFF by default) -- `ENABLE_AUTO_LAYOUT`: Enable Yoga-based automatic layout (ON by default, requires C++20) -- `BUILD_QUICKVIZ_APP`: Build the quickviz application (OFF by default) -- `IMVIEW_WITH_GLAD`: Integrate GLAD for OpenGL loading (ON by default) -- `STATIC_CHECK`: Enable cppcheck static analysis (OFF by default) - -### Dependencies -**Required**: OpenGL 3.3+, GLFW3, GLM, Cairo -**Optional**: OpenCV (cvdraw), PCL (point cloud bridge), Google Benchmark, Valgrind -**Bundled**: Dear ImGui & ImPlot, STB libraries, Yoga, GoogleTest, GLAD - -## API Design Standards - -### Public API Requirements -- **Explicit inputs**: Functions take `projection`, `view`, sizes, IDs; avoid hidden globals -- **Return handles or IDs**: Use opaque 32-bit IDs for user-visible resources; RAII classes for GL internals -- **Clear ownership**: Prefer `std::unique_ptr` in APIs; only use `std::shared_ptr` for true sharing -- **Narrow types**: Use `span` for read-only bulk data; avoid exposing STL containers -- **Unit awareness**: Document meters/seconds/radians; never assume degrees or "pixels" for world scale -- **Generic terminology**: Use standard robotics/graphics terms (Geometry, Transform, Viewport) over application-specific names (Map, World, Scene). This ensures broad applicability across different domains - -### Interface Design Patterns - -#### Extensibility Levels -Design APIs with clear extensibility boundaries: - -```cpp -// Direct Use: Simple, concrete functions -void DrawPoints(span points, glm::vec3 color, float size); -void DrawMesh(const MeshData& mesh, const Transform& transform); - -// Configurable: Parameter objects for complex configurations -struct RenderConfig { - LightingModel lighting = LightingModel::kPhong; - bool wireframe = false; - float point_size = 1.0f; -}; -void DrawMesh(const MeshData& mesh, const Transform& transform, const RenderConfig& config); - -// Extensible: Virtual interfaces for custom behavior -class Renderable { -public: - virtual void OnRender(const RenderContext& context) = 0; - virtual BoundingBox GetBounds() const = 0; -}; - -// Build-Upon: Framework classes with protected extension points -class InteractionTool { -public: - void HandleInput(const InputEvent& event); // final -protected: - virtual bool OnMouseDown(int x, int y) { return false; } // override points - virtual bool OnMouseDrag(int x, int y) { return false; } - virtual void OnToolActivated() {} -}; -``` +--- -### API Pattern Examples +## 3. Library Boundary -#### Opaque Handles + Narrow Interface -```cpp -using ObjectId = uint32_t; // 0 reserved as "none" +`src/` is visualization-only. Editor / app-level concerns — undo/redo, +command stacks, project files, scene serialization, history panels, full +application frameworks — live in `sample/` or downstream apps and consume +the library, never the reverse. -struct View { - glm::mat4 projection; // float - glm::mat4 view; // float - int width, height; -}; +- `sample/*` may include from `src/*/include/`. +- `src/*` must not include from `sample/`. Enforced by the + `boundary-check` CI job. +- If a sample wants something from the library, add it as a small, + visualization-justified hook to `src/` — never pull sample code in. -ObjectId CreateMesh(span vertices, span indices); -void SetTransform(ObjectId id, const glm::dmat4& world_from_object); -void DrawView(const View& view); -ObjectId PickAt(const View& view, int x, int y); -``` +`sample/editor/` is the canonical example: a working point-cloud editor +built entirely on top of the library. It's also the dogfood check — if a +fully-featured vis+editing app cannot be built without modifying `src/`, +the library is missing a hook and we evaluate the gap deliberately. -#### Core Interfaces -```cpp -class Renderable { - virtual bool IsVisible() = 0; - virtual void OnRender() = 0; -}; +--- -class OpenGlObject { - virtual void OnDraw(const glm::mat4& projection, const glm::mat4& view) = 0; -}; -``` +## 4. Dependency Direction -## Rendering Pipeline Best Practices - -### OpenGL 3.3+ Guidelines -- **Isolate passes**: Each pass sets all required GL state (program, VAO, FBO, depth, blend, cull) -- **Shared camera block**: Put `proj`/`view` in UBO; bind once per pass -- **Per-draw data**: Prefer small UBO/SSBO structs over many `glUniform*` calls -- **Debug output**: Enable `GL_KHR_debug` in debug builds - -### GPU Resource Management -- **RAII GL objects**: Thin wrappers for VAO/VBO/EBO/FBO/Program; no naked GLuints -- **Buffer usage**: - - Static: `glBufferData` or `glBufferStorage` - - Dynamic: `glMapBufferRange` with appropriate flags -- **Batching**: Sort by program → material → geometry -- **Minimize readbacks**: Only read pixels for picking; never read large buffers per frame - -### GL Pass Pattern -```cpp -class Pass { - public: - void Execute(const View& view) { - BindFbo(); - ConfigureState(); // depth/blend/cull - UseProgram(); // bind UBOs/textures - DrawAll(); // VAO binds and draw calls - } - private: - void BindFbo(); - void ConfigureState(); - void UseProgram(); - void DrawAll(); -}; -``` +Modules form a layered DAG. Lower layers never include from higher ones. -## Coordinate System & Precision - -- **CPU double, GPU float**: Keep CPU transforms in `double`; upload as `float` to shaders -- **Consistent "up" direction**: Support Z-up or Y-up at boundary; convert once internally -- **Camera sanity**: Warn if far/near > 1e6 to avoid z-fighting - -## Point Cloud Enhancement Features - -### PCL Integration -- Import/export between PCL and renderer formats -- Visualization of PCL algorithm results (clusters, surfaces) -- Template-based conversions for all PCL point types - -### Multi-Layer Rendering System -**Core Features**: -- Priority-based layer composition (higher priority renders on top) -- Multiple highlight modes: surface fill, outline, size increase -- Index buffer optimization for efficient batch rendering (60-100x improvement) -- 3D sphere rendering with Phong lighting - -**Usage Example**: -```cpp -// Create selection layer -auto selection_layer = point_cloud->CreateLayer("selection", 100); -selection_layer->SetPoints(selected_indices); -selection_layer->SetColor(glm::vec3(1.0f, 1.0f, 0.0f)); // Yellow -selection_layer->SetPointSizeMultiplier(1.5f); -selection_layer->SetHighlightMode(PointLayer::HighlightMode::kSphereSurface); -selection_layer->SetVisible(true); +``` +core ─► viewer ─► (scene | plot | canvas | image) ─► samples + │ +pcl_bridge ◄──── scene ───────┘ (optional adapters depend outward) ``` -## Interaction & Tool Patterns +- `core` depends on nothing else in the library. +- `viewer` depends on `core` (and ImGui/GLFW/Yoga from third_party). +- Visualization modules (`scene`, `plot`, `canvas`, `image`) depend on + `core` + `viewer`. They do **not** depend on each other unless there + is a concrete need (currently none do). +- Adapters (`pcl_bridge`, optional OpenCV in `image`) depend outward; + no in-library code depends on them. -These patterns are in scope for the library — they support inspection, -selection, and visual feedback. Editing semantics (undoable mutations, -project files, history) are an app-side concern; see `sample/editor/`. +When tempted to add a cross-module dependency, ask: is this concept truly +shared, or am I leaking implementation? Prefer to widen the public API of +the lower module than to reach across at the same level. -### Two-Stage Picking -1. **GPU ID buffer** → object ID -2. **CPU raycast** → precise hit/feature (BVH/KD-tree) +### Optional external dependencies -### Tool State Machine -- One active tool at a time, registered via `SceneManager::RegisterTool` -- Tools consume input and emit selection / hover / measurement events -- Gizmos drawn as overlay with selective depth testing -- Editor apps may layer their own command-based mutations on top of these - events; the library tools themselves do not record history +Any module or component that depends on a heavyweight external SDK +(ROS2, PCL, OpenCV, vendor sensor SDKs) **must** be CMake-gated so the +library compiles cleanly without that SDK installed. The pattern: -## Threading Model +- Use `find_package( QUIET)`. If absent, `return()` early from the + module's `CMakeLists.txt`. +- Do not reference the optional dep's headers, types, or functions + outside the gated module's source files. +- Document the dep in §5 Build System under "Optional". +- Library users without the dep get a working library with that + feature missing, not a build failure. -- **GL main-thread only**: All GL calls and ImGui rendering on render thread -- **Background stages**: File I/O, decoding, normal generation, BVH builds -- **Handoff boundary**: Jobs produce immutable CPU buffers; enqueue main-thread task for GL resources -- **No frame stalls**: Never wait on background jobs in frame loop +This applies specifically to ROS2: any current or future module that +consumes ROS messages — `bridges/ros2/`, downstream converters, +sample apps that use them — must be optional. A user who has never +installed ROS must still be able to clone, configure, build, and run +the rest of the library. -## Code Quality Standards +--- -### Style Guide -- **C++ Standard**: C++17 (C++14 minimum for Ubuntu 20.04) -- **File Extensions**: `.cpp` for source, `.hpp` for headers -- **Style**: Google C++ style guide, clang-format -- **Line Length**: 100 characters +## 5. Build System -### Testing Strategy -- **Unit Tests**: Core functionality (`tests/unit/`) -- **Integration Tests**: Module interactions (`tests/integration/`) -- **Memory Tests**: Leak detection (`tests/memory/`) -- **Benchmarks**: Performance testing (`tests/benchmarks/`) +Required: OpenGL 3.3+, GLFW3, GLM, Cairo. +Optional: OpenCV (enables `image`), PCL (enables `pcl_bridge`), +Google Benchmark, Valgrind, lcov. +Bundled in `third_party/`: ImGui, ImPlot, ImPlot3D, STB, Yoga, GoogleTest, GLAD. -### Test Execution ```bash -# Basic tests +git clone --recursive +git submodule update --init --recursive +mkdir build && cd build +cmake .. -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=ON +make -j$(nproc) ctest --output-on-failure - -# Comprehensive test suite -../scripts/run_tests.sh - -# With Valgrind and coverage -../scripts/run_tests.sh -v -c ``` -### Performance Hygiene -- Avoid per-frame heap churn: pre-allocate vectors, reuse temporaries -- Prefer SoA (structure-of-arrays) for large numeric datasets -- Keep shader branches simple; use separate passes for complex modes -- Profile both CPU and GPU; log slowest draw calls in debug - -## Error Handling & Robustness - -- **Structured logs**: Include frame number, pass name, object ID -- **Graceful degradation**: Render fallback (magenta material) on shader/asset failure -- **Debug assertions**: `DCHECK` invariants in debug builds only -- **GL debug context**: Enable in debug builds; treat high severity as test failures - -## External Dependencies & Bridges - -- Put adapters to heavy dependencies behind **small interfaces** -- Keep core build working when optional dependencies are **absent** -- No upstream types in public headers (don't leak `pcl::PointXYZ`) - -## Development Workflow - -### Feature Development -1. Create feature branch from `devel` -2. Implement with tests using established patterns -3. Run `scripts/run_tests.sh` before committing -4. PR to `devel` for review - -### Common Tasks - -**Add New Renderable Object**: -1. Inherit from `OpenGlObject` in `src/gldraw/renderable/` -2. Implement shader loading and VAO/VBO setup -3. Override `OnDraw()` with OpenGL render calls -4. Add to `GlSceneManager` in application - -**Create Custom UI Panel**: -1. Inherit from `Panel` in `src/imview/` -2. Override `Begin()` and `End()` methods with ImGui calls -3. Add panel to `Viewer` or `Box` container - -### Refactor Playbook -1. **Define boundary** (what belongs inside vs. outside) -2. **Write tiny interface** (2-5 functions, minimal templates) -3. **Add facade** that forwards to existing code -4. **Add tests** around facade -5. **Move code** under facade into new module -6. **Delete old paths** once coverage passes -7. **Measure performance** to ensure no regression - -## Decision Heuristics - -- **Expose or hide?** If type couples callers to OpenGL/third-party, **hide** it -- **Template or runtime?** If callers won't benefit from compile-time polymorphism, **prefer runtime** -- **One pass or two?** If branch toggles many states, **split into passes** -- **CPU or GPU?** Precision/topology → **CPU** (BVH/KD); per-pixel labeling → **GPU** (ID buffer) -- **Immediate or queued?** GPU resource allocation should be **queued** to render thread -- **Generic or specific?** Prefer generic robotics/graphics terms over application-specific names to maximize reusability -- **Direct use or extensible?** Simple, common operations should be directly callable; complex customization should use virtual interfaces -- **Framework or library?** Provide building blocks that users compose rather than frameworks that dictate application structure - -## PR Review Checklist - -- [ ] No GL calls off render thread -- [ ] Functions have explicit inputs; no new hidden globals -- [ ] Render paths set depth/blend/cull/program/VAO/FBO explicitly -- [ ] CPU uses double for geometry; GPU uniforms are float -- [ ] Picking reads exactly one pixel; ray logic has tests -- [ ] No raw GL handles in public headers -- [ ] No per-frame allocations on hot paths -- [ ] clang-format/clang-tidy clean; zero new warnings -- [ ] Documentation for non-obvious decisions -- [ ] Generic terminology used (avoid application-specific names) -- [ ] Interface boundaries clearly defined (direct use vs. extensible vs. build-upon) -- [ ] Building blocks remain composable and reusable across different applications - -## Development Rules - -- Remember to update TODO.md after getting approval for new tasks -- Always update TODO.md after finishing tasks -- Document architectural decisions with brief "Why this way?" notes -- Maintain backwards compatibility within major versions -- Prefer measured optimization over premature optimization - -## Platform Support - -- **Linux**: Primary platform (Ubuntu 20.04/22.04/24.04) -- **Windows**: Experimental via vcpkg -- **macOS**: Not officially supported - -## Current Development Focus - -Active areas of development: -- Interactive selection tools -- PCL algorithm result visualization -- Measurement and annotation overlays -- Level-of-detail system for large datasets - -See `TODO.md` for detailed roadmap and implementation status. \ No newline at end of file +Common CMake options: + +- `BUILD_TESTING` (default OFF) — build unit + integration tests +- `ENABLE_AUTO_LAYOUT` (default ON, requires C++20) — Yoga flexbox layout +- `VIEWER_WITH_GLAD` (default ON) — bundle GLAD as the GL loader +- `STATIC_CHECK` (default OFF) — run cppcheck during build + +CI runs the `boundary-check` job before the full build matrix; failing it +blocks the rest of the pipeline. + +--- + +## 6. Code Style + +- **Standard**: C++17 (some C++20 features behind `ENABLE_AUTO_LAYOUT`). +- **Files**: `.cpp` for source, `.hpp` for headers. Snake_case filenames. +- **Style**: Google C++ Style; clang-format applied. Line length 100. +- **Naming**: + - Types: `PascalCase`. Methods: `PascalCase()`. Members: `snake_case_`. + - Implementation prefixes are deliberate signals: `Gl*` means "wraps an + OpenGL handle"; `Cv*` means "uses OpenCV". Don't strip them when a + type genuinely couples to that backend. + - Module directories are snake_case; namespaces are `quickviz::*` (or + a sub-namespace in samples). +- **No `using namespace` in headers.** Inside `.cpp` files, `using + namespace quickviz` is acceptable. +- **Include order**: own header → standard library → third-party → + project headers, separated by blank lines. Each block alphabetized. +- **Header guards**: `QUICKVIZ___HPP` form is preferred; do + not use `#pragma once` in public headers. +- **File size**: aim for ~500 LOC. Files significantly above that are + candidates for splitting along internal seams. + +--- + +## 7. Architecture Patterns + +### Scene rendering +- `OpenGlObject` (`scene/interface/opengl_object.hpp`) is the base for + anything rendered in 3D. Subclasses own GPU resources via RAII. +- `SceneManager` owns OpenGL objects keyed by name; `GlScenePanel` hosts + the scene inside an ImGui window via render-to-texture. +- Per-pass: each draw path explicitly sets program, VAOs, depth, blend, + and cull state — never inherit it from the previous pass. + +### Selection +- Two-stage picking: GPU ID-buffer for object/point ID → CPU raycast for + precise hit. Pick reads exactly one pixel; never large readbacks. +- `SelectionManager` and `PointSelectionTool` provide ready-made + selection without an editor. Selection events are visualization + events; if you want them to be undoable, layer a Command pattern on + top in your app (`sample/editor/` shows how). + +### Tools +- `InteractionTool` registers with `SceneManager`. One active tool at a + time. Tools emit selection / hover / measurement events; they do not + record history. + +### Panels and layout +- `Panel` (in `viewer`) is the ImGui-based base for any UI panel. +- `Box` provides flexbox layout via Yoga (when `ENABLE_AUTO_LAYOUT`). +- For "give me a 3D viewer, fast", use `SceneApp`; for richer layouts, + compose `Viewer` + panels + `Box` directly. + +--- + +## 8. Threading Model + +- **GL main-thread only.** All OpenGL calls and ImGui rendering happen + on the render thread. Never make GL calls from background threads. +- **Background work** (file I/O, decoding, BVH builds, normal generation) + produces immutable CPU buffers and queues a main-thread task to upload + to GPU. +- **No frame stalls.** The render loop must never block on a background + job. Use `core/buffer` (RingBuffer, DoubleBuffer) for handoff. +- `core/event/AsyncEventDispatcher` provides bounded async event delivery + if the app needs it; do not roll a new threading framework into the + library without explicit decision. + +--- + +## 9. API Design Principles + +- **Small surface, strong contracts.** Every public function should have + a clear precondition, postcondition, and ownership story. +- **Explicit inputs.** Functions take `projection`, `view`, sizes, IDs; + no hidden globals. +- **Clear ownership.** Prefer `std::unique_ptr` in APIs; use + `std::shared_ptr` only for true sharing. Return raw pointers/refs only + when ownership is documented as remaining elsewhere. +- **Narrow types.** Prefer `std::span` for read-only bulk data. + Avoid leaking STL container choices in public headers. +- **Unit awareness.** Document meters, seconds, radians. Never assume + degrees or "pixels" for world-scale values. +- **CPU double, GPU float.** Keep CPU transforms in `double`; upload as + `float` to shaders. Caller-visible math is `double` unless documented + otherwise. +- **No upstream types in public headers.** `pcl::*` and `cv::*` types are + hidden behind the bridges/adapters. + +--- + +## 10. Error Handling + +- **Validate at boundaries.** Library entry points check their inputs + and report failures precisely. Internal helpers may trust callers. +- **Fail loud, fail early.** Throw on contract violations; do not return + silently corrupt data. `std::runtime_error` is the default; project + may add specific types where that helps. +- **Graceful rendering degradation.** On shader/asset load failure, log + the error and render a fallback (magenta material) so the rest of the + scene stays visible. +- **No silent error suppression.** `catch(...) {}` requires a comment + explaining why and what's lost. The deleted `SceneManagerBridge` is + the cautionary tale: silent fallbacks that fabricated data hid real + failures. + +--- + +## 11. Decision Heuristics + +When designing or reviewing changes, prefer: + +- **Hide if it leaks.** If a type couples callers to OpenGL or third-party + details, hide it behind an interface. +- **Runtime over compile-time.** Templates earn their keep with concrete + performance or type-safety wins. Otherwise, prefer runtime polymorphism. +- **More passes over more state.** If a render path branches heavily on + state, split it into separate passes. +- **CPU for precision/topology, GPU for per-pixel.** BVH/KD on CPU; ID + buffers and shading on GPU. +- **Queued over immediate** for GPU-resource creation off the main thread. +- **Generic over specific.** Robotics/graphics vocabulary, not + application vocabulary. +- **Library stays a library.** When in doubt, push the feature to + `sample/` and let it prove it belongs in `src/`. + +--- + +## 12. Tests + +- Unit tests live next to the module: `src//test/`. +- Cross-module integration tests live in `tests/integration/`. +- GoogleTest is the framework; new tests follow the patterns of the + existing ones. +- Renderable tests use `SceneApp` as their harness. +- Aim for 80% coverage overall. Designated hot paths should aim for 100%. + +--- + +## 13. Commits & Documentation + +- Commit messages: `type(scope): subject` form. Explain *why* in the + body, not what the diff already shows. One logical change per commit. +- Don't amend pushed commits. Force-push to `main` is forbidden without + explicit approval. +- `TODO.md` tracks active and recent work — keep it terse, factual, + one-bullet-per-outcome. No marketing language. +- `docs/notes/` holds longer design references and historical decisions. +- After completing work, update `TODO.md` in the same change. + +--- + +## 14. Where Things Live + +- **Code by mission**: `src//`, see Module Map above. +- **Reference apps**: `sample/quickstart/` (smallest possible), + `sample/pointcloud_viewer/` (file → render with selection), + `sample/editor/` (vis+editing dogfood check), + `sample/quickviz_demo_app/` (broader app shell demo). +- **Active TODOs**: `TODO.md` (root). +- **Architecture deep-dives**: `docs/notes/`. +- **Build / install**: `README.md`. +- **CI**: `.github/workflows/default.yml` (note: includes a + `boundary-check` job that gates the build matrix). diff --git a/CMakeLists.txt b/CMakeLists.txt index cfad8b8..f94a142 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) @@ -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) diff --git a/README.md b/README.md index aa56017..4fb8501 100644 --- a/README.md +++ b/README.md @@ -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. diff --git a/TODO.md b/TODO.md index 9395b89..099ebed 100644 --- a/TODO.md +++ b/TODO.md @@ -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)` 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` / `core/Replay` + +### 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)` 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 ` 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` +- `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 diff --git a/docs/imview_design.md b/docs/imview_design.md index cf22086..0a51d99 100644 --- a/docs/imview_design.md +++ b/docs/imview_design.md @@ -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 diff --git a/docs/notes/canvas_optimization_analysis.md b/docs/notes/canvas_optimization_analysis.md index 0339ffa..ceb176f 100644 --- a/docs/notes/canvas_optimization_analysis.md +++ b/docs/notes/canvas_optimization_analysis.md @@ -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: @@ -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: @@ -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 @@ -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 @@ -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: diff --git a/docs/notes/core_imview_code_quality.md b/docs/notes/core_imview_code_quality.md index d8aeee6..ccdfe36 100644 --- a/docs/notes/core_imview_code_quality.md +++ b/docs/notes/core_imview_code_quality.md @@ -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 @@ -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`). @@ -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 @@ -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`. diff --git a/docs/notes/input_handling_system_for_gldraw.md b/docs/notes/input_handling_system_for_scene.md similarity index 96% rename from docs/notes/input_handling_system_for_gldraw.md rename to docs/notes/input_handling_system_for_scene.md index 5a8d96b..8c6b3c5 100644 --- a/docs/notes/input_handling_system_for_gldraw.md +++ b/docs/notes/input_handling_system_for_scene.md @@ -1,6 +1,6 @@ -# Input Handling System for gldraw +# Input Handling System for scene -This directory contains a comprehensive input handling system for the gldraw module, providing flexible and extensible user interaction capabilities. +This directory contains a comprehensive input handling system for the scene module, providing flexible and extensible user interaction capabilities. ## Overview @@ -17,9 +17,9 @@ The input handling system is designed around the **InteractionMode** pattern, wh ## Quick Start ```cpp -#include "gldraw/gui/gl_input_handler.hpp" -#include "gldraw/input/camera_interaction_mode.hpp" -#include "gldraw/input/selection_interaction_mode.hpp" +#include "scene/gui/gl_input_handler.hpp" +#include "scene/input/camera_interaction_mode.hpp" +#include "scene/input/selection_interaction_mode.hpp" // Create input handler auto input_handler = std::make_unique(); diff --git a/docs/notes/gldraw_refactor_plan.md b/docs/notes/scene_refactor_plan.md similarity index 98% rename from docs/notes/gldraw_refactor_plan.md rename to docs/notes/scene_refactor_plan.md index baab585..136e89a 100644 --- a/docs/notes/gldraw_refactor_plan.md +++ b/docs/notes/scene_refactor_plan.md @@ -2,7 +2,7 @@ ## Overview -This document outlines a comprehensive refactor plan for the gldraw module to make it high-quality and high-performance for critical use cases, rather than complete but low-quality. The focus is on simplifying the architecture, optimizing performance bottlenecks, and creating a lean, maintainable codebase. +This document outlines a comprehensive refactor plan for the scene module to make it high-quality and high-performance for critical use cases, rather than complete but low-quality. The focus is on simplifying the architecture, optimizing performance bottlenecks, and creating a lean, maintainable codebase. ## Current Architecture Analysis @@ -393,7 +393,7 @@ struct PerformanceConfig { #### 5.1 Streamlined Directory Structure ```cpp -src/gldraw/ +src/scene/ ├── core/ // Essential components only │ ├── renderer.hpp // Main rendering coordinator │ ├── shader_manager.hpp // Cached shader system diff --git a/docs/notes/session_summary_2025-01-28.md b/docs/notes/session_summary_2025-01-28.md index 451cf31..c03bc8d 100644 --- a/docs/notes/session_summary_2025-01-28.md +++ b/docs/notes/session_summary_2025-01-28.md @@ -14,10 +14,10 @@ Comprehensive review of GLDraw module and design of enhanced input handling syst - ⚠️ Selection support needed for other renderables (mesh, cylinder, box, etc.) **Key Files Reviewed**: -- `src/gldraw/include/gldraw/selection_manager.hpp` - Main selection system -- `src/gldraw/include/gldraw/gl_scene_manager.hpp` - Scene management -- `src/gldraw/include/gldraw/renderable/point_cloud.hpp` - Point cloud with layers -- `src/gldraw/include/gldraw/renderable/layer_manager.hpp` - Layer system +- `src/scene/include/scene/selection_manager.hpp` - Main selection system +- `src/scene/include/scene/gl_scene_manager.hpp` - Scene management +- `src/scene/include/scene/renderable/point_cloud.hpp` - Point cloud with layers +- `src/scene/include/scene/renderable/layer_manager.hpp` - Layer system ### 2. Input Handling System Design @@ -42,7 +42,7 @@ Comprehensive review of GLDraw module and design of enhanced input handling syst **DECISION: Use Core Module (Option 1)** - Extend existing `core` module with InputEvent classes - Leverage existing EventDispatcher and thread-safe infrastructure -- Clean dependency: core → imview → gldraw +- Clean dependency: core → viewer → scene **Rationale**: - Reuses robust event system already in core @@ -106,9 +106,9 @@ SelectionManager::Select() ``` InputEvent (core) → InputDispatcher (core) ↓ -InputMapping (imview/gldraw) +InputMapping (viewer/scene) ↓ -SelectionManager handlers (gldraw) +SelectionManager handlers (scene) ↓ Visual feedback via LayerManager ``` @@ -122,8 +122,8 @@ Visual feedback via LayerManager ### 5. Files to Modify - `src/core/CMakeLists.txt` - Add new input files -- `src/gldraw/src/gl_scene_panel.cpp` - Update HandleInput() -- `src/gldraw/src/selection_manager.cpp` - Add multiple handlers +- `src/scene/src/gl_scene_panel.cpp` - Update HandleInput() +- `src/scene/src/selection_manager.cpp` - Add multiple handlers ## Session Metrics - Files reviewed: 15+ diff --git a/docs/notes/shader_compilation_linking_fix.md b/docs/notes/shader_compilation_linking_fix.md index e64ec74..44ecf34 100644 --- a/docs/notes/shader_compilation_linking_fix.md +++ b/docs/notes/shader_compilation_linking_fix.md @@ -392,9 +392,9 @@ The fixes are implemented across multiple files: - **Grid Renderer**: `src/renderer/src/renderable/grid.cpp` (lines 96-118) - **Coordinate Frame**: `src/renderer/src/renderable/coordinate_frame.cpp` (lines 160-182) - **Canvas Background**: `src/renderer/src/renderable/canvas.cpp` (lines 340-364) -- **OpenGL Detection**: `src/imview/src/viewer.cpp` (lines 90-91, 418-451) -- **Capability Checker**: `src/imview/include/imview/opengl_capability_checker.hpp` -- **Window Fallbacks**: `src/imview/src/window.cpp` (lines 35-60) +- **OpenGL Detection**: `src/viewer/src/viewer.cpp` (lines 90-91, 418-451) +- **Capability Checker**: `src/viewer/include/viewer/opengl_capability_checker.hpp` +- **Window Fallbacks**: `src/viewer/src/window.cpp` (lines 35-60) ## References diff --git a/docs/notes/sphere_migration_example.md b/docs/notes/sphere_migration_example.md index 99907a0..aadd7df 100644 --- a/docs/notes/sphere_migration_example.md +++ b/docs/notes/sphere_migration_example.md @@ -13,7 +13,7 @@ This document shows how to migrate the existing Sphere class to inherit from Geo ```cpp // sphere.hpp - Updated to inherit from GeometricPrimitive -#include "gldraw/renderable/geometric_primitive.hpp" +#include "scene/renderable/geometric_primitive.hpp" namespace quickviz { diff --git a/docs/notes/unified_input_architecture.md b/docs/notes/unified_input_architecture.md index d905a85..4c66b0c 100644 --- a/docs/notes/unified_input_architecture.md +++ b/docs/notes/unified_input_architecture.md @@ -144,19 +144,19 @@ Input Source → ImGuiInputUtils → InputEvent → InputDispatcher → InputEve ### Actual Implementation -1. **GamepadManager** (src/imview/input/gamepad_manager.hpp) +1. **GamepadManager** (src/viewer/input/gamepad_manager.hpp) - Meyer's Singleton pattern for thread-safe initialization - Direct GLFW polling for multiple gamepad support - Connection/disconnection monitoring with callbacks - Hardware state caching with GamepadState struct -2. **ImGuiInputUtils::PollGamepadEvents()** (src/imview/input/imgui_input_utils.cpp) +2. **ImGuiInputUtils::PollGamepadEvents()** (src/viewer/input/imgui_input_utils.cpp) - Uses GamepadManager instead of ImGui's gamepad system - Proper state tracking with static map (OUTSIDE loop - critical bug fix) - Handles button count changes for hot-plug support - Generates InputEvent objects for unified processing -3. **Viewer Integration** (src/imview/viewer.cpp) +3. **Viewer Integration** (src/viewer/viewer.cpp) - Polls events AFTER CreateNewImGuiFrame() for valid context - One-time handler registration in AddSceneObject() - Proper cleanup in RemoveSceneObject() and destructor diff --git a/sample/CMakeLists.txt b/sample/CMakeLists.txt index 5e0931e..ce25cb4 100644 --- a/sample/CMakeLists.txt +++ b/sample/CMakeLists.txt @@ -1,5 +1,7 @@ # applications if (ENABLE_AUTO_LAYOUT) + add_subdirectory(quickstart) + add_subdirectory(streaming_demo) add_subdirectory(quickviz_demo_app) # Silence PCL-era policy warnings, but keep modern behavior where safe diff --git a/sample/editor/CMakeLists.txt b/sample/editor/CMakeLists.txt index faaf79c..30fce07 100644 --- a/sample/editor/CMakeLists.txt +++ b/sample/editor/CMakeLists.txt @@ -9,7 +9,7 @@ add_executable(quickviz_editor target_compile_definitions(quickviz_editor PRIVATE ${PCL_DEFINITIONS}) target_link_libraries(quickviz_editor PRIVATE - gldraw + scene pcl_bridge ${PCL_LIBRARIES}) target_include_directories(quickviz_editor PRIVATE diff --git a/sample/editor/README.md b/sample/editor/README.md index 855b702..3ca49ce 100644 --- a/sample/editor/README.md +++ b/sample/editor/README.md @@ -40,5 +40,5 @@ cmake --build build -j ## Boundary rule This directory **may** include from the library's public headers -(`gldraw/`, `imview/`, `pcl_bridge/`, `core/`). It must never be included +(`scene/`, `viewer/`, `pcl_bridge/`, `core/`). It must never be included *by* anything in `src/`. The `boundary-check` CI job enforces this. diff --git a/sample/editor/editor_state.cpp b/sample/editor/editor_state.cpp index 9618417..0c35cc5 100644 --- a/sample/editor/editor_state.cpp +++ b/sample/editor/editor_state.cpp @@ -8,9 +8,9 @@ #include -#include "gldraw/renderable/point_cloud.hpp" -#include "gldraw/selection_manager.hpp" -#include "gldraw/tools/point_selection_tool.hpp" +#include "scene/renderable/point_cloud.hpp" +#include "scene/selection_manager.hpp" +#include "scene/tools/point_selection_tool.hpp" namespace quickviz::editor { diff --git a/sample/editor/editor_viewport.hpp b/sample/editor/editor_viewport.hpp index 8e19e09..1508d0f 100644 --- a/sample/editor/editor_viewport.hpp +++ b/sample/editor/editor_viewport.hpp @@ -15,8 +15,8 @@ #include #include -#include "gldraw/gl_scene_panel.hpp" -#include "gldraw/tools/point_selection_tool.hpp" +#include "scene/gl_scene_panel.hpp" +#include "scene/tools/point_selection_tool.hpp" namespace quickviz::editor { diff --git a/sample/editor/main.cpp b/sample/editor/main.cpp index ed74aa3..4d203ff 100644 --- a/sample/editor/main.cpp +++ b/sample/editor/main.cpp @@ -19,11 +19,11 @@ #include -#include "imview/box.hpp" -#include "imview/viewer.hpp" +#include "viewer/box.hpp" +#include "viewer/viewer.hpp" -#include "gldraw/renderable/grid.hpp" -#include "gldraw/renderable/point_cloud.hpp" +#include "scene/renderable/grid.hpp" +#include "scene/renderable/point_cloud.hpp" #include "pcl_bridge/pcl_loader.hpp" #include "editor_state.hpp" diff --git a/sample/editor/panels/editor_tool_panel.cpp b/sample/editor/panels/editor_tool_panel.cpp index 9e66665..4e6d20a 100644 --- a/sample/editor/panels/editor_tool_panel.cpp +++ b/sample/editor/panels/editor_tool_panel.cpp @@ -10,7 +10,7 @@ #include -#include "gldraw/tools/point_selection_tool.hpp" +#include "scene/tools/point_selection_tool.hpp" #include "../commands/delete_points_command.hpp" #include "../editor_state.hpp" diff --git a/sample/editor/panels/editor_tool_panel.hpp b/sample/editor/panels/editor_tool_panel.hpp index 91ec8fd..8fd1e16 100644 --- a/sample/editor/panels/editor_tool_panel.hpp +++ b/sample/editor/panels/editor_tool_panel.hpp @@ -10,7 +10,7 @@ #include -#include "imview/panel.hpp" +#include "viewer/panel.hpp" namespace quickviz::editor { diff --git a/sample/editor/panels/history_panel.hpp b/sample/editor/panels/history_panel.hpp index a94452a..ff2b741 100644 --- a/sample/editor/panels/history_panel.hpp +++ b/sample/editor/panels/history_panel.hpp @@ -10,7 +10,7 @@ #include -#include "imview/panel.hpp" +#include "viewer/panel.hpp" namespace quickviz::editor { diff --git a/sample/pointcloud_viewer/CMakeLists.txt b/sample/pointcloud_viewer/CMakeLists.txt index 1c29278..0bb6730 100644 --- a/sample/pointcloud_viewer/CMakeLists.txt +++ b/sample/pointcloud_viewer/CMakeLists.txt @@ -4,5 +4,5 @@ add_executable(point_cloud_viewer point_cloud_tool_panel.cpp interactive_scene_manager.cpp) target_compile_definitions(point_cloud_viewer PRIVATE ${PCL_DEFINITIONS}) -target_link_libraries(point_cloud_viewer PRIVATE gldraw pcl_bridge ${PCL_LIBRARIES}) +target_link_libraries(point_cloud_viewer PRIVATE scene pcl_bridge ${PCL_LIBRARIES}) target_include_directories(point_cloud_viewer PRIVATE ${PCL_INCLUDE_DIRS} ${CURRENT_CMAKE_SOURCE_DIR}) diff --git a/sample/pointcloud_viewer/interactive_scene_manager.hpp b/sample/pointcloud_viewer/interactive_scene_manager.hpp index b2cfc09..41f2922 100644 --- a/sample/pointcloud_viewer/interactive_scene_manager.hpp +++ b/sample/pointcloud_viewer/interactive_scene_manager.hpp @@ -9,9 +9,9 @@ #ifndef QUICKVIZ_INTERACTIVE_SCENE_MANAGER_HPP #define QUICKVIZ_INTERACTIVE_SCENE_MANAGER_HPP -#include "gldraw/gl_scene_panel.hpp" -#include "gldraw/renderable/point_cloud.hpp" -#include "gldraw/tools/point_selection_tool.hpp" +#include "scene/gl_scene_panel.hpp" +#include "scene/renderable/point_cloud.hpp" +#include "scene/tools/point_selection_tool.hpp" #include namespace quickviz { diff --git a/sample/pointcloud_viewer/main.cpp b/sample/pointcloud_viewer/main.cpp index 68aa443..462d3ab 100644 --- a/sample/pointcloud_viewer/main.cpp +++ b/sample/pointcloud_viewer/main.cpp @@ -19,13 +19,13 @@ #include #include -#include "imview/box.hpp" -#include "imview/viewer.hpp" -#include "imview/panel.hpp" +#include "viewer/box.hpp" +#include "viewer/viewer.hpp" +#include "viewer/panel.hpp" -#include "gldraw/scene_manager.hpp" -#include "gldraw/renderable/grid.hpp" -#include "gldraw/renderable/point_cloud.hpp" +#include "scene/scene_manager.hpp" +#include "scene/renderable/grid.hpp" +#include "scene/renderable/point_cloud.hpp" #include "pcl_bridge/pcl_loader.hpp" #include "point_cloud_info_panel.hpp" diff --git a/sample/pointcloud_viewer/point_cloud_info_panel.hpp b/sample/pointcloud_viewer/point_cloud_info_panel.hpp index f734e35..50f886f 100644 --- a/sample/pointcloud_viewer/point_cloud_info_panel.hpp +++ b/sample/pointcloud_viewer/point_cloud_info_panel.hpp @@ -9,7 +9,7 @@ #ifndef QUICKVIZ_POINT_CLOUD_INFO_PANEL_HPP #define QUICKVIZ_POINT_CLOUD_INFO_PANEL_HPP -#include "imview/panel.hpp" +#include "viewer/panel.hpp" #include "pcl_bridge/pcl_loader.hpp" namespace quickviz { diff --git a/sample/pointcloud_viewer/point_cloud_tool_panel.hpp b/sample/pointcloud_viewer/point_cloud_tool_panel.hpp index 0060480..e774946 100644 --- a/sample/pointcloud_viewer/point_cloud_tool_panel.hpp +++ b/sample/pointcloud_viewer/point_cloud_tool_panel.hpp @@ -9,9 +9,9 @@ #ifndef QUICKVIZ_POINT_CLOUD_TOOL_PANEL_HPP #define QUICKVIZ_POINT_CLOUD_TOOL_PANEL_HPP -#include "imview/panel.hpp" -#include "gldraw/gl_scene_panel.hpp" -#include "gldraw/tools/point_selection_tool.hpp" +#include "viewer/panel.hpp" +#include "scene/gl_scene_panel.hpp" +#include "scene/tools/point_selection_tool.hpp" namespace quickviz { class InteractiveSceneManager; diff --git a/sample/quickstart/CMakeLists.txt b/sample/quickstart/CMakeLists.txt new file mode 100644 index 0000000..a702677 --- /dev/null +++ b/sample/quickstart/CMakeLists.txt @@ -0,0 +1,5 @@ +add_executable(quickviz_quickstart main.cpp) +target_link_libraries(quickviz_quickstart PRIVATE + core + scene + viewer) diff --git a/sample/quickstart/README.md b/sample/quickstart/README.md new file mode 100644 index 0000000..7d841e6 --- /dev/null +++ b/sample/quickstart/README.md @@ -0,0 +1,75 @@ +# sample/quickstart — the smallest QuickViz program + +This sample exists to prove that QuickViz lets you build a working +visualization tool in roughly thirty lines of code. If you just cloned the +repo and want to know "how do I display *something*", read `main.cpp` — +that's the answer. + +## What it does + +Opens a window, draws a colored helix made of 2000 points in 3D space, lets +you orbit the camera with the mouse. Closes when you close the window. + +## The whole program (with annotations) + +```cpp +#include "core/demo.hpp" // synthetic data generators +#include "scene/renderable/point_cloud.hpp" +#include "scene/scene_app.hpp" // 5-line quickstart facade + +int main() { + quickviz::SceneApp::Config config; // sensible defaults: grid + axes on + config.window_title = "QuickViz Quickstart"; + quickviz::SceneApp app(config); + + app.SetSceneSetup([](quickviz::SceneManager* scene) { + // SceneSetup runs once after the OpenGL context is ready. + auto data = quickviz::demo::SpiralCloud(2000); // synthetic points + auto cloud = std::make_unique(); + cloud->SetPointSize(4.0f); + cloud->SetPoints(data.points, data.colors); + scene->AddOpenGLObject("spiral", std::move(cloud)); + }); + + app.Run(); // blocks until window is closed +} +``` + +That's it. No layout boilerplate, no manual ImGui setup, no GLFW glue, no +shaders to write. + +## What you can change without learning more + +- Swap `SpiralCloud` for `PlanarPointGrid(50, 50, 0.1f)` or + `NoiseCloud(5000, 1.5f)` — see `core/demo.hpp` for the full list. +- Add a `Mesh` instead of (or alongside) the cloud: + + ```cpp + auto mesh_data = quickviz::demo::CubeMesh(glm::vec3{0, 0, 0}, 1.5f); + auto mesh = std::make_unique(); + mesh->SetVertices(mesh_data.vertices); + mesh->SetIndices(mesh_data.indices); + scene->AddOpenGLObject("cube", std::move(mesh)); + ``` +- Toggle the reference grid or coordinate frame via + `config.show_grid = false;` etc. + +## When to drop down from `SceneApp` + +`SceneApp` is the path of least resistance, not the only door. Reach for +`Viewer` + `Panel` directly when you need: + +- Multiple panels (3D + plot + image, tabbed layouts, dockable windows) +- Custom UI panels alongside the scene +- A history / tools / properties sidebar + +Look at `sample/pointcloud_viewer/` and `sample/editor/` for examples that +compose `Viewer` directly. + +## Building & running + +```bash +cmake -S . -B build -DBUILD_TESTING=ON +cmake --build build -j +./build/bin/quickviz_quickstart +``` diff --git a/sample/quickstart/main.cpp b/sample/quickstart/main.cpp new file mode 100644 index 0000000..f4be6b0 --- /dev/null +++ b/sample/quickstart/main.cpp @@ -0,0 +1,30 @@ +/* + * @file main.cpp + * @brief The smallest possible QuickViz program — proves SceneApp delivers + * on its "5-line quickstart" promise. ~25 lines of meaningful code. + * + * Copyright (c) 2026 Ruixiang Du (rdu) + */ + +#include + +#include "core/demo.hpp" +#include "scene/renderable/point_cloud.hpp" +#include "scene/scene_app.hpp" + +int main() { + quickviz::SceneApp::Config config; + config.window_title = "QuickViz Quickstart"; + quickviz::SceneApp app(config); + + app.SetSceneSetup([](quickviz::SceneManager* scene) { + auto data = quickviz::demo::SpiralCloud(/*num_points=*/2000); + auto cloud = std::make_unique(); + cloud->SetPointSize(4.0f); + cloud->SetPoints(data.points, data.colors); + scene->AddOpenGLObject("spiral", std::move(cloud)); + }); + + app.Run(); + return 0; +} diff --git a/sample/quickviz_demo_app/CMakeLists.txt b/sample/quickviz_demo_app/CMakeLists.txt index 8a3bf74..d16b300 100644 --- a/sample/quickviz_demo_app/CMakeLists.txt +++ b/sample/quickviz_demo_app/CMakeLists.txt @@ -8,7 +8,7 @@ if (BUILD_QUICKVIZ_APP) panels/scene_panel.cpp panels/config_panel.cpp panels/console_panel.cpp) - target_link_libraries(quickviz_demo_app PRIVATE imview gldraw pcl_bridge) + target_link_libraries(quickviz_demo_app PRIVATE viewer scene pcl_bridge) target_include_directories(quickviz_demo_app PRIVATE .) install(TARGETS quickviz_demo_app diff --git a/sample/quickviz_demo_app/main.cpp b/sample/quickviz_demo_app/main.cpp index a98ddb6..939f107 100644 --- a/sample/quickviz_demo_app/main.cpp +++ b/sample/quickviz_demo_app/main.cpp @@ -8,7 +8,7 @@ #include -#include "imview/viewer.hpp" +#include "viewer/viewer.hpp" #include "quickviz_application.hpp" diff --git a/sample/quickviz_demo_app/panels/config_panel.cpp b/sample/quickviz_demo_app/panels/config_panel.cpp index 9d9f812..6ec23f8 100644 --- a/sample/quickviz_demo_app/panels/config_panel.cpp +++ b/sample/quickviz_demo_app/panels/config_panel.cpp @@ -8,7 +8,7 @@ #include "panels/config_panel.hpp" -#include "imview/fonts.hpp" +#include "viewer/fonts.hpp" namespace quickviz { ConfigPanel::ConfigPanel(std::string name) : Panel(name) { diff --git a/sample/quickviz_demo_app/panels/config_panel.hpp b/sample/quickviz_demo_app/panels/config_panel.hpp index c1fa2b0..0a4c67e 100644 --- a/sample/quickviz_demo_app/panels/config_panel.hpp +++ b/sample/quickviz_demo_app/panels/config_panel.hpp @@ -9,7 +9,7 @@ #ifndef QUICKVIZ_CONFIG_PANEL_HPP #define QUICKVIZ_CONFIG_PANEL_HPP -#include "imview/panel.hpp" +#include "viewer/panel.hpp" namespace quickviz { class ConfigPanel : public Panel { diff --git a/sample/quickviz_demo_app/panels/console_panel.cpp b/sample/quickviz_demo_app/panels/console_panel.cpp index 96ea474..543b503 100644 --- a/sample/quickviz_demo_app/panels/console_panel.cpp +++ b/sample/quickviz_demo_app/panels/console_panel.cpp @@ -8,8 +8,8 @@ #include "panels/console_panel.hpp" -#include "imview/fonts.hpp" -#include "imview/logging/app_log_handler.hpp" +#include "viewer/fonts.hpp" +#include "viewer/logging/app_log_handler.hpp" namespace quickviz { ConsolePanel::ConsolePanel(std::string name) : Panel(name) { diff --git a/sample/quickviz_demo_app/panels/console_panel.hpp b/sample/quickviz_demo_app/panels/console_panel.hpp index ddd9152..a9fba1e 100644 --- a/sample/quickviz_demo_app/panels/console_panel.hpp +++ b/sample/quickviz_demo_app/panels/console_panel.hpp @@ -9,7 +9,7 @@ #ifndef QUICKVIZ_CONSOLE_PANEL_HPP #define QUICKVIZ_CONSOLE_PANEL_HPP -#include "imview/panel.hpp" +#include "viewer/panel.hpp" namespace quickviz { class ConsolePanel : public Panel { diff --git a/sample/quickviz_demo_app/panels/main_docking_panel.hpp b/sample/quickviz_demo_app/panels/main_docking_panel.hpp index 0177805..a5db58b 100644 --- a/sample/quickviz_demo_app/panels/main_docking_panel.hpp +++ b/sample/quickviz_demo_app/panels/main_docking_panel.hpp @@ -9,7 +9,7 @@ #ifndef QUICKVIZ_MAIN_DOCKING_PANEL_HPP #define QUICKVIZ_MAIN_DOCKING_PANEL_HPP -#include "imview/panel.hpp" +#include "viewer/panel.hpp" #include "panels/menu_bar.hpp" #include "panels/config_panel.hpp" diff --git a/sample/quickviz_demo_app/panels/menu_bar.hpp b/sample/quickviz_demo_app/panels/menu_bar.hpp index 0eae9ae..c5a96aa 100644 --- a/sample/quickviz_demo_app/panels/menu_bar.hpp +++ b/sample/quickviz_demo_app/panels/menu_bar.hpp @@ -11,7 +11,7 @@ #include -#include "imview/panel.hpp" +#include "viewer/panel.hpp" namespace quickviz { class MenuBar : public Panel { diff --git a/sample/quickviz_demo_app/panels/scene_panel.cpp b/sample/quickviz_demo_app/panels/scene_panel.cpp index d61c600..06c6f90 100644 --- a/sample/quickviz_demo_app/panels/scene_panel.cpp +++ b/sample/quickviz_demo_app/panels/scene_panel.cpp @@ -13,7 +13,7 @@ #include #include -#include "imview/logging/app_log_handler.hpp" +#include "viewer/logging/app_log_handler.hpp" namespace quickviz { ScenePanel::ScenePanel(const std::string& panel_name) diff --git a/sample/quickviz_demo_app/panels/scene_panel.hpp b/sample/quickviz_demo_app/panels/scene_panel.hpp index 98a3ab9..fa73164 100644 --- a/sample/quickviz_demo_app/panels/scene_panel.hpp +++ b/sample/quickviz_demo_app/panels/scene_panel.hpp @@ -11,8 +11,8 @@ #include -#include "imview/component/opengl/renderer/grid.hpp" -#include "imview/component/opengl/gl_scene_manager.hpp" +#include "viewer/component/opengl/renderer/grid.hpp" +#include "viewer/component/opengl/gl_scene_manager.hpp" namespace quickviz { class ScenePanel : public GlSceneManager { diff --git a/sample/quickviz_demo_app/quickviz_application.hpp b/sample/quickviz_demo_app/quickviz_application.hpp index 17a302e..3ede94c 100644 --- a/sample/quickviz_demo_app/quickviz_application.hpp +++ b/sample/quickviz_demo_app/quickviz_application.hpp @@ -9,8 +9,8 @@ #ifndef QUICKVIZ_QUICKVIZ_APPLICATION_HPP #define QUICKVIZ_QUICKVIZ_APPLICATION_HPP -#include "imview/viewer.hpp" -#include "imview/box.hpp" +#include "viewer/viewer.hpp" +#include "viewer/box.hpp" #include "panels/main_docking_panel.hpp" #include "data_reader.hpp" diff --git a/sample/streaming_demo/CMakeLists.txt b/sample/streaming_demo/CMakeLists.txt new file mode 100644 index 0000000..3950996 --- /dev/null +++ b/sample/streaming_demo/CMakeLists.txt @@ -0,0 +1,5 @@ +add_executable(quickviz_streaming_demo main.cpp) +target_link_libraries(quickviz_streaming_demo PRIVATE + core + scene + viewer) diff --git a/sample/streaming_demo/README.md b/sample/streaming_demo/README.md new file mode 100644 index 0000000..93e915e --- /dev/null +++ b/sample/streaming_demo/README.md @@ -0,0 +1,99 @@ +# sample/streaming_demo — sensor data into a 3D scene, the right way + +The canonical pattern for bringing data from a background thread (sensor +driver, ROS subscriber, network socket, processing pipeline) into a +QuickViz scene. Read `main.cpp` before you write your first sensor +callback — the same shape applies. + +## What it does + +Opens a window. A background thread generates a 2000-point colored +helix that rotates around the vertical axis at ~30 Hz and pushes each +new cloud into a `DataStream`. The render thread pulls the latest +cloud once per frame and updates a single `PointCloud` renderable. You +see a smoothly spinning spiral. + +Close the window — the producer thread shuts down cleanly. + +## The threading model + +``` + ┌──────────────────┐ ┌──────────────────┐ + │ producer thread │ │ render thread │ + │ (sensor / ROS / │ Push(PointCloudData) │ (GLFW + GL) │ + │ driver / your │ ────────────────────────► │ │ + │ callback) │ │ TryPull(out) │ + └──────────────────┘ │ SetPoints(out) │ + DataStream └──────────────────┘ + (latest-only, + lossy, never + blocks the + render loop) +``` + +Three rules captured by this layout: + +1. **All OpenGL calls happen on the render thread.** The producer never + touches GL or the renderable directly. It only writes to `stream`. +2. **The render thread never blocks waiting for data.** `TryPull` + returns immediately with either the latest sample or "nothing new" + — in the latter case the previous frame's cloud is reused. +3. **Intermediate samples are dropped silently.** If the producer + pushes 30 clouds per second but the render loop runs at 144 Hz (or + stutters under load), you only ever see the most recent cloud. + Visualization rarely cares about yesterday's frame; this is what + you want. + +## When `DataStream` is right + +Use `DataStream` when: + +- You only care about the **latest** value (poses, sensor frames, + status updates, processed outputs). +- The producer thread should **not block** on the consumer — losing + intermediate values is acceptable. +- The data type is **trivially copyable / movable** as a whole unit + (a struct, a `std::vector`, a small POD). Don't push references. + +Use `RingBuffer` (in `core/buffer/`) instead when: + +- You need to **see every sample** (plotting time-series, replaying, + recording, integration over time). +- The consumer should be able to fall behind without losing data + (within the buffer's capacity). +- Order matters and you process samples one-by-one. + +For most "show me the sensor on screen" robotics workflows, use +`DataStream`. + +## How to adapt this to a real sensor + +Replace the synthetic producer (the `std::thread` block) with whatever +delivers your data: + +```cpp +// instead of a synthetic loop, your driver/ROS callback pushes: +my_sensor.OnFrame([&stream](const RawFrame& frame) { + auto cloud = ConvertToPointCloudData(frame); + stream.Push(std::move(cloud)); +}); +``` + +Everything below the producer stays the same: one `DataStream`, +one `SetPreDrawCallback` doing `TryPull` + `SetPoints`. The renderer +doesn't know or care where the data came from. + +The forthcoming `bridges/ros2/` module will give you ready-made +producers for `sensor_msgs::PointCloud2`, `geometry_msgs::PoseStamped`, +and similar — so the boilerplate disappears for ROS2 users. + +## Building & running + +```bash +cmake -S . -B build -DBUILD_TESTING=ON +cmake --build build -j +./build/bin/quickviz_streaming_demo +``` + +No external data files needed; all data is synthetic via +`quickviz::demo::SpiralCloud`. diff --git a/sample/streaming_demo/main.cpp b/sample/streaming_demo/main.cpp new file mode 100644 index 0000000..bd02e7d --- /dev/null +++ b/sample/streaming_demo/main.cpp @@ -0,0 +1,89 @@ +/* + * @file main.cpp + * @brief Canonical streaming pattern: background producer → DataStream → + * render thread → renderable. + * + * Demonstrates the recommended way to bring sensor-rate data into a + * QuickViz scene without blocking the render loop. Read this file before + * writing your first ROS2 / sensor callback — the same shape applies. + * + * Copyright (c) 2026 Ruixiang Du (rdu) + */ + +#include +#include +#include +#include +#include + +#include "core/data_stream.hpp" +#include "core/demo.hpp" +#include "scene/renderable/point_cloud.hpp" +#include "scene/scene_app.hpp" + +int main() { + using namespace quickviz; + + // The single shared channel between producer and renderer. + // Latest-only / lossy: if the producer outpaces the renderer, the + // intermediate clouds are silently dropped — usually what you want. + DataStream stream; + + // Producer thread: simulates a 30 Hz sensor producing a spiral cloud + // that rotates around the Z axis. In a real app this is your driver + // callback or ROS2 subscriber. + std::atomic stop{false}; + std::thread producer([&]() { + const auto t0 = std::chrono::steady_clock::now(); + while (!stop.load()) { + const float t = std::chrono::duration( + std::chrono::steady_clock::now() - t0).count(); + const float angle = 0.5f * t; // rad/s + const float ca = std::cos(angle); + const float sa = std::sin(angle); + + auto data = demo::SpiralCloud(2000); + for (auto& p : data.points) { + const float x = p.x * ca - p.y * sa; + const float y = p.x * sa + p.y * ca; + p.x = x; + p.y = y; + } + stream.Push(std::move(data)); + + std::this_thread::sleep_for(std::chrono::milliseconds(33)); + } + }); + + SceneApp::Config config; + config.window_title = "QuickViz Streaming Demo"; + SceneApp app(config); + + // Wire up the scene: a single empty point cloud, plus a pre-draw + // callback that drains the stream once per frame. + PointCloud* cloud = nullptr; + app.SetSceneSetup([&](SceneManager* scene) { + auto pc = std::make_unique(); + pc->SetPointSize(4.0f); + cloud = pc.get(); + scene->AddOpenGLObject("stream", std::move(pc)); + + // Pre-draw callback runs on the render thread, just before the + // scene is rendered. Non-blocking; if no fresh value is available, + // the previous frame's cloud is rendered again. + scene->SetPreDrawCallback([&]() { + demo::PointCloudData latest; + if (stream.TryPull(latest)) { + cloud->SetPoints(latest.points, latest.colors); + } + }); + }); + + app.Run(); + + // Clean shutdown: stop the producer before the stream goes out of + // scope. Order matters — the producer holds a reference to `stream`. + stop.store(true); + producer.join(); + return 0; +} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index dc88f02..c15536a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,11 +1,20 @@ -# core modules +# Library modules — visualization-first. +# +# Module layout (one job each): +# core — events, buffers, threading helpers +# viewer — window + panels + layout +# scene — interactive 3D scene rendering (OpenGL) +# plot — data charts (ImPlot 2D + ImPlot3D) +# canvas — 2D vector drawing (Cairo) +# image — image display & annotation (OpenCV, optional) +# pcl_bridge — PCL adapter +# +# Editor / undo / project-files / app frameworks are NOT in scope here; +# they live in sample/ on top of this library. CI enforces the boundary. add_subdirectory(core) -add_subdirectory(imview) -add_subdirectory(widget) -add_subdirectory(gldraw) +add_subdirectory(viewer) +add_subdirectory(scene) +add_subdirectory(plot) +add_subdirectory(canvas) +add_subdirectory(image) # internally returns early if OpenCV is missing add_subdirectory(pcl_bridge) - -find_package(OpenCV QUIET) -if (OpenCV_FOUND) - add_subdirectory(cvdraw) -endif () diff --git a/src/canvas/CMakeLists.txt b/src/canvas/CMakeLists.txt new file mode 100644 index 0000000..9128dc3 --- /dev/null +++ b/src/canvas/CMakeLists.txt @@ -0,0 +1,43 @@ +# find dependency +find_package(PkgConfig REQUIRED) +pkg_check_modules(Cairo REQUIRED IMPORTED_TARGET cairo) +pkg_check_modules(Fontconfig REQUIRED IMPORTED_TARGET fontconfig) + +find_package(Threads REQUIRED) +find_package(OpenGL REQUIRED) + +# add library +# +# `canvas` provides 2D vector drawing and immediate widgets backed by +# Cairo. Use this module for custom 2D figures, plots-as-pictures, and +# annotations rendered into a panel as a texture. +add_library(canvas + src/details/cairo_context.cpp + src/details/cairo_draw.cpp + src/cairo_widget.cpp) +target_link_libraries(canvas PUBLIC + core + imcore + viewer + PkgConfig::Cairo + PkgConfig::Fontconfig + Threads::Threads + OpenGL::GL) +target_include_directories(canvas PUBLIC + $ + $ + PRIVATE src) + +if(BUILD_TESTING) + add_subdirectory(test) +endif() + +install(TARGETS canvas + EXPORT quickvizTargets + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib + RUNTIME DESTINATION bin + INCLUDES DESTINATION include) + +install(DIRECTORY include/ + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) diff --git a/src/widget/include/widget/cairo_widget.hpp b/src/canvas/include/canvas/cairo_widget.hpp similarity index 92% rename from src/widget/include/widget/cairo_widget.hpp rename to src/canvas/include/canvas/cairo_widget.hpp index 61b1a13..020ae34 100644 --- a/src/widget/include/widget/cairo_widget.hpp +++ b/src/canvas/include/canvas/cairo_widget.hpp @@ -20,9 +20,9 @@ #include "imgui.h" -#include "imview/panel.hpp" -#include "widget/details/cairo_context.hpp" -#include "widget/details/cairo_draw.hpp" +#include "viewer/panel.hpp" +#include "canvas/details/cairo_context.hpp" +#include "canvas/details/cairo_draw.hpp" namespace quickviz { class CairoWidget : public Panel { diff --git a/src/widget/include/widget/details/cairo_context.hpp b/src/canvas/include/canvas/details/cairo_context.hpp similarity index 100% rename from src/widget/include/widget/details/cairo_context.hpp rename to src/canvas/include/canvas/details/cairo_context.hpp diff --git a/src/widget/include/widget/details/cairo_draw.hpp b/src/canvas/include/canvas/details/cairo_draw.hpp similarity index 100% rename from src/widget/include/widget/details/cairo_draw.hpp rename to src/canvas/include/canvas/details/cairo_draw.hpp diff --git a/src/widget/src/cairo_widget.cpp b/src/canvas/src/cairo_widget.cpp similarity index 98% rename from src/widget/src/cairo_widget.cpp rename to src/canvas/src/cairo_widget.cpp index f79b477..0546fea 100644 --- a/src/widget/src/cairo_widget.cpp +++ b/src/canvas/src/cairo_widget.cpp @@ -7,7 +7,7 @@ * Copyright (c) 2021 Ruixiang Du (rdu) */ -#include "widget/cairo_widget.hpp" +#include "canvas/cairo_widget.hpp" #include #include diff --git a/src/widget/src/details/cairo_context.cpp b/src/canvas/src/details/cairo_context.cpp similarity index 98% rename from src/widget/src/details/cairo_context.cpp rename to src/canvas/src/details/cairo_context.cpp index 94cd2ec..d423481 100644 --- a/src/widget/src/details/cairo_context.cpp +++ b/src/canvas/src/details/cairo_context.cpp @@ -7,7 +7,7 @@ * Copyright (c) 2021 Ruixiang Du (rdu) */ -#include "widget/details/cairo_context.hpp" +#include "canvas/details/cairo_context.hpp" #include diff --git a/src/widget/src/details/cairo_draw.cpp b/src/canvas/src/details/cairo_draw.cpp similarity index 99% rename from src/widget/src/details/cairo_draw.cpp rename to src/canvas/src/details/cairo_draw.cpp index d121e04..783e075 100644 --- a/src/widget/src/details/cairo_draw.cpp +++ b/src/canvas/src/details/cairo_draw.cpp @@ -7,7 +7,7 @@ * Copyright (c) 2021 Ruixiang Du (rdu) */ -#include "widget/details/cairo_draw.hpp" +#include "canvas/details/cairo_draw.hpp" #include diff --git a/src/canvas/test/CMakeLists.txt b/src/canvas/test/CMakeLists.txt new file mode 100644 index 0000000..d0aadc8 --- /dev/null +++ b/src/canvas/test/CMakeLists.txt @@ -0,0 +1,2 @@ +add_executable(test_cairo_widget test_cairo_widget.cpp) +target_link_libraries(test_cairo_widget PRIVATE canvas) diff --git a/src/widget/test/test_cairo_widget.cpp b/src/canvas/test/test_cairo_widget.cpp similarity index 97% rename from src/widget/test/test_cairo_widget.cpp rename to src/canvas/test/test_cairo_widget.cpp index a771f24..12d5b8c 100644 --- a/src/widget/test/test_cairo_widget.cpp +++ b/src/canvas/test/test_cairo_widget.cpp @@ -10,8 +10,8 @@ #include #include -#include "imview/viewer.hpp" -#include "widget/cairo_widget.hpp" +#include "viewer/viewer.hpp" +#include "canvas/cairo_widget.hpp" #ifndef M_PI #define M_PI 3.14159265358979323846 diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index fb78e0c..4011443 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -3,10 +3,10 @@ find_package(Threads REQUIRED) # add library add_library(core - # widgets src/buffer/buffer_registry.cpp src/event/async_event_dispatcher.cpp - src/event/input_mapping.cpp) + src/event/input_mapping.cpp + src/demo.cpp) target_link_libraries(core PUBLIC Threads::Threads imcore) target_include_directories(core PUBLIC $ diff --git a/src/core/include/core/data_stream.hpp b/src/core/include/core/data_stream.hpp new file mode 100644 index 0000000..af7585e --- /dev/null +++ b/src/core/include/core/data_stream.hpp @@ -0,0 +1,91 @@ +/* + * @file data_stream.hpp + * @brief Latest-only producer/consumer channel for streaming data + * + * `DataStream` is the recommended way to bring sensor data, robot poses, + * point clouds, or any other periodically-updated value from a background + * thread to the render thread. It exposes a tiny stream-shaped API on top + * of the existing `DoubleBuffer` primitive: + * + * - Producer thread calls `Push(value)` whenever a new sample arrives. + * - Render thread calls `TryPull()` once per frame and updates the + * renderable if a fresh value is available. + * + * Semantics: "latest-only, lossy." The consumer always sees the most + * recent value; intermediate pushes between two pulls are silently + * dropped. This is what visualization usually wants — yesterday's frame + * is not interesting if today's is already in hand. + * + * The render thread never blocks. Push and Pull are thread-safe. + * + * For lossless delivery (e.g. accumulating every sample for a plot), + * use `RingBuffer` directly instead. + * + * Copyright (c) 2026 Ruixiang Du (rdu) + */ + +#ifndef QUICKVIZ_CORE_DATA_STREAM_HPP +#define QUICKVIZ_CORE_DATA_STREAM_HPP + +#include +#include + +#include "core/buffer/double_buffer.hpp" + +namespace quickviz { + +template +class DataStream { + public: + DataStream() = default; + ~DataStream() = default; + + // Non-copyable; the underlying buffer holds mutex/condvar state. + // Movable for placement in containers if useful. + DataStream(const DataStream&) = delete; + DataStream& operator=(const DataStream&) = delete; + + /** + * @brief Publish a new value. Replaces any unread previous value. + * + * Safe to call from any thread, including concurrently with `TryPull`. + * The previous unread value (if any) is discarded — only the most + * recent push is retained. This is the lossy semantics that streaming + * visualization expects. + */ + void Push(const T& value) { buffer_.Write(value); } + void Push(T&& value) { buffer_.Write(std::move(value)); } + + /** + * @brief Consume the latest value, if a fresh one is available. + * + * @param out Receives the latest value when this call returns true. + * Untouched otherwise. + * @return true if a fresh value was available and copied into `out`; + * false if no new value has been pushed since the last + * successful pull. + * + * Non-blocking. Safe to call once per frame on the render thread. + */ + bool TryPull(T& out) { return buffer_.TryRead(out); } + + /** + * @brief Same as `TryPull(T&)` but returns the value by std::optional. + * + * Convenient for `if (auto v = stream.TryPull()) { ... }` patterns. + * Slightly less efficient when T is large because it copies into + * `optional`'s storage; for hot paths prefer the out-param overload. + */ + std::optional TryPull() { + T value; + if (!buffer_.TryRead(value)) return std::nullopt; + return value; + } + + private: + DoubleBuffer buffer_; +}; + +} // namespace quickviz + +#endif // QUICKVIZ_CORE_DATA_STREAM_HPP diff --git a/src/core/include/core/demo.hpp b/src/core/include/core/demo.hpp new file mode 100644 index 0000000..d1e1063 --- /dev/null +++ b/src/core/include/core/demo.hpp @@ -0,0 +1,114 @@ +/* + * @file demo.hpp + * @brief Synthetic data generators for quickstarts, tutorials, and tests + * + * `quickviz::demo` provides small, deterministic data generators so users + * can explore the library without supplying their own data files. Returned + * structures match the shapes expected by the library's renderables — pass + * a `PointCloudData` straight into `PointCloud::SetPoints`, a `MeshData` + * straight into `Mesh::SetVertices`/`SetIndices`. + * + * All generators are pure functions of their inputs: no global state, no + * I/O, deterministic for the seeds you provide. + * + * Copyright (c) 2026 Ruixiang Du (rdu) + */ + +#ifndef QUICKVIZ_CORE_DEMO_HPP +#define QUICKVIZ_CORE_DEMO_HPP + +#include +#include +#include + +#include + +namespace quickviz::demo { + +/** + * @brief Result of a point-cloud generator: positions + per-point RGB. + * + * `points` and `colors` are always the same size. Pass directly into + * `PointCloud::SetPoints(points, colors)`. + */ +struct PointCloudData { + std::vector points; + std::vector colors; +}; + +/** + * @brief Result of a mesh generator: vertex positions + triangle indices. + * + * Pass `vertices` to `Mesh::SetVertices` and `indices` to `Mesh::SetIndices`. + * Indices are 32-bit unsigned for direct compatibility with the GL element + * buffer format used by the `Mesh` renderable. + */ +struct MeshData { + std::vector vertices; + std::vector indices; +}; + +/** + * @brief Generate a vertical helix of coloured points. + * + * Useful as the canonical "hello, world" point cloud — visually + * distinctive, deterministic, and small. Color is HSV-derived from the + * height parameter so the result is colorful without needing extra + * configuration. + * + * @param num_points Number of points along the helix (≥ 1). + * @param radius Maximum spiral radius in world units. + * @param height Total vertical extent (the spiral spans ±height/2). + * @param turns How many full revolutions across the height. + */ +PointCloudData SpiralCloud(std::size_t num_points, + float radius = 3.0f, + float height = 6.0f, + float turns = 8.0f); + +/** + * @brief Generate a regular grid of points lying in the Z=0 plane. + * + * Colors interpolate diagonally so adjacent points are distinguishable. + * + * @param rows Number of grid rows (>= 1). + * @param cols Number of grid columns (>= 1). + * @param spacing Distance between neighbouring points in world units. + */ +PointCloudData PlanarPointGrid(std::size_t rows, + std::size_t cols, + float spacing = 0.1f); + +/** + * @brief Generate a Gaussian-noise point cloud centred on the origin. + * + * @param num_points Number of points. + * @param sigma Standard deviation along each axis in world units. + * @param seed Seed for reproducibility (0 = use a fixed default). + */ +PointCloudData NoiseCloud(std::size_t num_points, + float sigma = 1.0f, + unsigned seed = 0); + +/** + * @brief Generate a unit cube mesh centred on `center` with the given size. + * + * 8 vertices, 12 triangles (36 indices). Suitable as a basic Mesh demo. + */ +MeshData CubeMesh(glm::vec3 center = glm::vec3(0.0f), float size = 1.0f); + +/** + * @brief Generate a smooth synthetic 3D trajectory. + * + * The trajectory is a Lissajous-like curve in 3D — useful for showing + * line strips and path renderables without needing real robot data. + * + * @param num_points Number of samples along the trajectory. + * @param scale Overall extent in world units. + */ +std::vector Trajectory(std::size_t num_points, + float scale = 5.0f); + +} // namespace quickviz::demo + +#endif // QUICKVIZ_CORE_DEMO_HPP diff --git a/src/core/include/core/event/input_event.hpp b/src/core/include/core/event/input_event.hpp index 701d8aa..1d5f40e 100644 --- a/src/core/include/core/event/input_event.hpp +++ b/src/core/include/core/event/input_event.hpp @@ -56,7 +56,7 @@ struct ModifierKeys { bool IsEmpty() const { return !ctrl && !shift && !alt && !super; } }; -// Use existing MouseButton enum from imview/input/mouse.hpp +// Use existing MouseButton enum from viewer/input/mouse.hpp // No need to redefine it here class InputEvent : public BaseEvent { diff --git a/src/core/include/core/event/input_mapping.hpp b/src/core/include/core/event/input_mapping.hpp index f3c5be2..cb4cfec 100644 --- a/src/core/include/core/event/input_mapping.hpp +++ b/src/core/include/core/event/input_mapping.hpp @@ -228,7 +228,7 @@ class InputMapping { private: void SetupDefaultMappings() { - // Mouse button constants (from imview/input/mouse.hpp) + // Mouse button constants (from viewer/input/mouse.hpp) const int kLeft = 0; const int kRight = 1; const int kMiddle = 2; diff --git a/src/core/src/demo.cpp b/src/core/src/demo.cpp new file mode 100644 index 0000000..30eca68 --- /dev/null +++ b/src/core/src/demo.cpp @@ -0,0 +1,141 @@ +/* + * @file demo.cpp + * + * Copyright (c) 2026 Ruixiang Du (rdu) + */ + +#include "core/demo.hpp" + +#include +#include + +namespace quickviz::demo { + +namespace { + +// HSV → RGB with H in [0,1), S = V = 1. +glm::vec3 HueToRgb(float h) { + const float r = std::abs(h * 6.0f - 3.0f) - 1.0f; + const float g = 2.0f - std::abs(h * 6.0f - 2.0f); + const float b = 2.0f - std::abs(h * 6.0f - 4.0f); + return glm::clamp(glm::vec3{r, g, b}, 0.0f, 1.0f); +} + +constexpr float kPi = 3.14159265358979323846f; + +} // namespace + +PointCloudData SpiralCloud(std::size_t num_points, + float radius, + float height, + float turns) { + PointCloudData out; + if (num_points == 0) return out; + + out.points.reserve(num_points); + out.colors.reserve(num_points); + + const float denom = static_cast(num_points - 1); + for (std::size_t i = 0; i < num_points; ++i) { + const float t = (num_points == 1) ? 0.0f : static_cast(i) / denom; + const float angle = t * 2.0f * kPi * turns; + const float r = t * radius; + const float z = (t - 0.5f) * height; + out.points.emplace_back(r * std::cos(angle), r * std::sin(angle), z); + out.colors.push_back(HueToRgb(t)); + } + return out; +} + +PointCloudData PlanarPointGrid(std::size_t rows, + std::size_t cols, + float spacing) { + PointCloudData out; + if (rows == 0 || cols == 0) return out; + + const std::size_t n = rows * cols; + out.points.reserve(n); + out.colors.reserve(n); + + const float row_denom = (rows == 1) ? 1.0f : static_cast(rows - 1); + const float col_denom = (cols == 1) ? 1.0f : static_cast(cols - 1); + const float origin_x = -0.5f * static_cast(cols - 1) * spacing; + const float origin_y = -0.5f * static_cast(rows - 1) * spacing; + + for (std::size_t r = 0; r < rows; ++r) { + for (std::size_t c = 0; c < cols; ++c) { + out.points.emplace_back(origin_x + static_cast(c) * spacing, + origin_y + static_cast(r) * spacing, + 0.0f); + const float t = + 0.5f * (static_cast(r) / row_denom + + static_cast(c) / col_denom); + out.colors.push_back(HueToRgb(t)); + } + } + return out; +} + +PointCloudData NoiseCloud(std::size_t num_points, float sigma, unsigned seed) { + PointCloudData out; + if (num_points == 0) return out; + + std::mt19937 rng(seed == 0 ? 0xC0FFEEu : seed); + std::normal_distribution dist(0.0f, sigma); + + out.points.reserve(num_points); + out.colors.reserve(num_points); + for (std::size_t i = 0; i < num_points; ++i) { + out.points.emplace_back(dist(rng), dist(rng), dist(rng)); + // Color encodes distance from origin so denser clusters read visually. + const float d = + glm::length(out.points.back()) / (3.0f * std::max(sigma, 1e-6f)); + out.colors.push_back(HueToRgb(glm::clamp(d, 0.0f, 1.0f))); + } + return out; +} + +MeshData CubeMesh(glm::vec3 center, float size) { + MeshData out; + const float h = 0.5f * size; + + out.vertices = { + // 0..3: -Z face + center + glm::vec3{-h, -h, -h}, center + glm::vec3{ h, -h, -h}, + center + glm::vec3{ h, h, -h}, center + glm::vec3{-h, h, -h}, + // 4..7: +Z face + center + glm::vec3{-h, -h, h}, center + glm::vec3{ h, -h, h}, + center + glm::vec3{ h, h, h}, center + glm::vec3{-h, h, h}, + }; + + // 12 triangles, CCW when viewed from outside. + out.indices = { + 0, 2, 1, 0, 3, 2, // -Z + 4, 5, 6, 4, 6, 7, // +Z + 0, 1, 5, 0, 5, 4, // -Y + 1, 2, 6, 1, 6, 5, // +X + 2, 3, 7, 2, 7, 6, // +Y + 3, 0, 4, 3, 4, 7, // -X + }; + return out; +} + +std::vector Trajectory(std::size_t num_points, float scale) { + std::vector out; + if (num_points == 0) return out; + + out.reserve(num_points); + const float denom = (num_points == 1) ? 1.0f + : static_cast(num_points - 1); + for (std::size_t i = 0; i < num_points; ++i) { + const float t = static_cast(i) / denom; + const float angle = t * 2.0f * kPi; + // 3:2:1 Lissajous in 3D. + out.emplace_back(scale * std::sin(3.0f * angle), + scale * std::sin(2.0f * angle), + 0.5f * scale * std::sin(angle)); + } + return out; +} + +} // namespace quickviz::demo diff --git a/src/core/test/CMakeLists.txt b/src/core/test/CMakeLists.txt index 8201c31..20e8ace 100644 --- a/src/core/test/CMakeLists.txt +++ b/src/core/test/CMakeLists.txt @@ -3,16 +3,16 @@ add_subdirectory(unit_test) add_executable(test_event test_event.cpp) -target_link_libraries(test_event PRIVATE imview) +target_link_libraries(test_event PRIVATE viewer) add_executable(test_async_event test_async_event.cpp) -target_link_libraries(test_async_event PRIVATE imview) +target_link_libraries(test_async_event PRIVATE viewer) find_package(OpenCV QUIET) if (OpenCV_FOUND) add_executable(test_double_buffer test_double_buffer.cpp) - target_link_libraries(test_double_buffer PRIVATE imview ${OpenCV_LIBS}) + target_link_libraries(test_double_buffer PRIVATE viewer ${OpenCV_LIBS}) add_executable(test_ring_buffer test_ring_buffer.cpp) - target_link_libraries(test_ring_buffer PRIVATE imview ${OpenCV_LIBS}) + target_link_libraries(test_ring_buffer PRIVATE viewer ${OpenCV_LIBS}) endif () \ No newline at end of file diff --git a/src/core/test/unit_test/CMakeLists.txt b/src/core/test/unit_test/CMakeLists.txt index b570bc6..9a2a05e 100644 --- a/src/core/test/unit_test/CMakeLists.txt +++ b/src/core/test/unit_test/CMakeLists.txt @@ -5,9 +5,11 @@ add_executable(core_unit_tests test_input_event.cpp test_event_system.cpp test_thread_safe_queue.cpp - test_buffer_registry.cpp) -target_link_libraries(core_unit_tests PRIVATE gtest_main gmock imview) -# get_target_property(PRIVATE_HEADERS imview INCLUDE_DIRECTORIES) + test_buffer_registry.cpp + test_demo.cpp + test_data_stream.cpp) +target_link_libraries(core_unit_tests PRIVATE gtest_main gmock viewer) +# get_target_property(PRIVATE_HEADERS viewer INCLUDE_DIRECTORIES) target_include_directories(core_unit_tests PRIVATE ${PRIVATE_HEADERS}) gtest_discover_tests(core_unit_tests) diff --git a/src/core/test/unit_test/test_data_stream.cpp b/src/core/test/unit_test/test_data_stream.cpp new file mode 100644 index 0000000..b22e78d --- /dev/null +++ b/src/core/test/unit_test/test_data_stream.cpp @@ -0,0 +1,103 @@ +/* + * @file test_data_stream.cpp + * + * Copyright (c) 2026 Ruixiang Du (rdu) + */ + +#include +#include +#include + +#include + +#include "core/data_stream.hpp" + +namespace quickviz { +namespace { + +TEST(DataStreamTest, EmptyPullReturnsFalse) { + DataStream stream; + int out = -1; + EXPECT_FALSE(stream.TryPull(out)); + EXPECT_EQ(out, -1); // out untouched on empty +} + +TEST(DataStreamTest, OptionalApiReturnsNulloptWhenEmpty) { + DataStream stream; + EXPECT_FALSE(stream.TryPull().has_value()); +} + +TEST(DataStreamTest, PushThenPullDeliversValue) { + DataStream stream; + stream.Push(42); + int out = 0; + ASSERT_TRUE(stream.TryPull(out)); + EXPECT_EQ(out, 42); +} + +TEST(DataStreamTest, PullReturnsFalseAfterFirstSuccessUntilNextPush) { + DataStream stream; + stream.Push(7); + int out = 0; + ASSERT_TRUE(stream.TryPull(out)); + EXPECT_FALSE(stream.TryPull(out)); // already consumed +} + +TEST(DataStreamTest, IntermediatePushesAreDropped) { + // Latest-only semantics: if the producer pushes faster than the + // consumer pulls, only the most recent value reaches the consumer. + DataStream stream; + for (int i = 1; i <= 5; ++i) stream.Push(i); + int out = 0; + ASSERT_TRUE(stream.TryPull(out)); + EXPECT_EQ(out, 5); + EXPECT_FALSE(stream.TryPull(out)); +} + +TEST(DataStreamTest, MoveOverloadCompiles) { + DataStream stream; + std::string s = "hello"; + stream.Push(std::move(s)); + std::string out; + ASSERT_TRUE(stream.TryPull(out)); + EXPECT_EQ(out, "hello"); +} + +TEST(DataStreamTest, ProducerConsumerThreadsConcurrent) { + // Background producer pushes a counter; foreground "renderer" polls it + // and verifies it always sees a non-decreasing snapshot. This is the + // headline use case: render thread never blocks, never sees torn data. + DataStream stream; + std::atomic stop{false}; + std::atomic last_pulled{-1}; + + std::thread producer([&]() { + for (int i = 0; i < 1000 && !stop.load(); ++i) { + stream.Push(i); + std::this_thread::yield(); + } + }); + + // Pull-loop on the test thread (acts as render thread). + int observed_max = -1; + while (observed_max < 999) { + int out = -1; + if (stream.TryPull(out)) { + ASSERT_GE(out, observed_max); // never goes backwards + observed_max = out; + } + if (last_pulled.load() == 999) break; + if (out >= 0) last_pulled.store(out); + } + stop.store(true); + producer.join(); + + // Once producer is done, one final value should be available + // (or already have been pulled). Either way, observed_max should + // have reached the producer's last value at some point. + EXPECT_GE(observed_max, 0); + EXPECT_LE(observed_max, 999); +} + +} // namespace +} // namespace quickviz diff --git a/src/core/test/unit_test/test_demo.cpp b/src/core/test/unit_test/test_demo.cpp new file mode 100644 index 0000000..ea09b5e --- /dev/null +++ b/src/core/test/unit_test/test_demo.cpp @@ -0,0 +1,84 @@ +/* + * @file test_demo.cpp + * + * Copyright (c) 2026 Ruixiang Du (rdu) + */ + +#include + +#include + +#include "core/demo.hpp" + +namespace quickviz::demo { +namespace { + +TEST(DemoSpiralCloud, SizesMatchAndAreNonEmpty) { + auto result = SpiralCloud(/*num_points=*/100); + EXPECT_EQ(result.points.size(), 100u); + EXPECT_EQ(result.colors.size(), 100u); +} + +TEST(DemoSpiralCloud, ZeroPointsReturnsEmpty) { + auto result = SpiralCloud(0); + EXPECT_TRUE(result.points.empty()); + EXPECT_TRUE(result.colors.empty()); +} + +TEST(DemoSpiralCloud, FillsRequestedHeightRange) { + constexpr float kHeight = 4.0f; + auto result = SpiralCloud(64, /*radius=*/1.0f, kHeight, /*turns=*/2.0f); + ASSERT_FALSE(result.points.empty()); + EXPECT_NEAR(result.points.front().z, -kHeight * 0.5f, 1e-5f); + EXPECT_NEAR(result.points.back().z, kHeight * 0.5f, 1e-5f); +} + +TEST(DemoPlanarPointGrid, GridShape) { + auto result = PlanarPointGrid(3, 4, 0.1f); + EXPECT_EQ(result.points.size(), 12u); + EXPECT_EQ(result.colors.size(), 12u); + // Every point lies in the Z=0 plane. + for (const auto& p : result.points) EXPECT_FLOAT_EQ(p.z, 0.0f); +} + +TEST(DemoNoiseCloud, IsDeterministicForSameSeed) { + auto a = NoiseCloud(50, 1.0f, /*seed=*/42); + auto b = NoiseCloud(50, 1.0f, /*seed=*/42); + ASSERT_EQ(a.points.size(), b.points.size()); + for (std::size_t i = 0; i < a.points.size(); ++i) { + EXPECT_FLOAT_EQ(a.points[i].x, b.points[i].x); + EXPECT_FLOAT_EQ(a.points[i].y, b.points[i].y); + EXPECT_FLOAT_EQ(a.points[i].z, b.points[i].z); + } +} + +TEST(DemoCubeMesh, HasEightVerticesAndTwelveTriangles) { + auto mesh = CubeMesh(); + EXPECT_EQ(mesh.vertices.size(), 8u); + EXPECT_EQ(mesh.indices.size(), 36u); // 12 triangles × 3 indices + for (auto idx : mesh.indices) EXPECT_LT(idx, 8u); +} + +TEST(DemoCubeMesh, RespectsCenterAndSize) { + auto mesh = CubeMesh(glm::vec3{1.0f, 2.0f, 3.0f}, 2.0f); + // All vertices should sit on the bounding box of the requested cube. + for (const auto& v : mesh.vertices) { + EXPECT_NEAR(std::abs(v.x - 1.0f), 1.0f, 1e-5f); + EXPECT_NEAR(std::abs(v.y - 2.0f), 1.0f, 1e-5f); + EXPECT_NEAR(std::abs(v.z - 3.0f), 1.0f, 1e-5f); + } +} + +TEST(DemoTrajectory, HasRequestedSizeAndIsBounded) { + constexpr float kScale = 5.0f; + auto traj = Trajectory(200, kScale); + EXPECT_EQ(traj.size(), 200u); + for (const auto& p : traj) { + EXPECT_LE(std::abs(p.x), kScale + 1e-4f); + EXPECT_LE(std::abs(p.y), kScale + 1e-4f); + EXPECT_LE(std::abs(p.z), 0.5f * kScale + 1e-4f); + } +} + +} // namespace +} // namespace quickviz::demo diff --git a/src/cvdraw/CMakeLists.txt b/src/cvdraw/CMakeLists.txt deleted file mode 100644 index 79bd220..0000000 --- a/src/cvdraw/CMakeLists.txt +++ /dev/null @@ -1,28 +0,0 @@ -## Dependency libraries -find_package(OpenCV REQUIRED) - -## Add libraries -add_library(cvdraw src/cv_colors.cpp - src/color_maps.cpp - src/cv_canvas.cpp - src/cv_io.cpp) -target_link_libraries(cvdraw ${OpenCV_LIBS}) -target_include_directories(cvdraw PUBLIC - $ - $ - PRIVATE src) - -# Add executables -if(BUILD_TESTING) - add_subdirectory(test) -endif() - -install(TARGETS cvdraw - EXPORT quickvizTargets - LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib - RUNTIME DESTINATION bin - INCLUDES DESTINATION include) - -install(DIRECTORY include/ - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) \ No newline at end of file diff --git a/src/cvdraw/basic_colors.png b/src/cvdraw/basic_colors.png deleted file mode 100644 index bb6056e..0000000 Binary files a/src/cvdraw/basic_colors.png and /dev/null differ diff --git a/src/cvdraw/draw_demo.png b/src/cvdraw/draw_demo.png deleted file mode 100644 index dcff951..0000000 Binary files a/src/cvdraw/draw_demo.png and /dev/null differ diff --git a/src/cvdraw/function_plot_demo.png b/src/cvdraw/function_plot_demo.png deleted file mode 100644 index 0683e93..0000000 Binary files a/src/cvdraw/function_plot_demo.png and /dev/null differ diff --git a/src/cvdraw/test/CMakeLists.txt b/src/cvdraw/test/CMakeLists.txt deleted file mode 100644 index c3ba37b..0000000 --- a/src/cvdraw/test/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -# Dependency libraries -#find_package(LIBRARY_NAME REQUIRED) - -## tests -add_executable(test_image_rw test_image_rw.cpp) -target_link_libraries(test_image_rw PUBLIC cvdraw) - -add_executable(test_cv_canvas test_cv_canvas.cpp) -target_link_libraries(test_cv_canvas PUBLIC cvdraw) - -add_executable(test_cv_drawmode test_cv_drawmode.cpp) -target_link_libraries(test_cv_drawmode PUBLIC cvdraw) - -add_executable(test_cv_drawfunc test_cv_drawfunc.cpp) -target_link_libraries(test_cv_drawfunc PUBLIC cvdraw) \ No newline at end of file diff --git a/src/gldraw/test/renderable/CMakeLists.txt b/src/gldraw/test/renderable/CMakeLists.txt deleted file mode 100644 index b4d2414..0000000 --- a/src/gldraw/test/renderable/CMakeLists.txt +++ /dev/null @@ -1,52 +0,0 @@ -add_executable(test_arrow test_arrow.cpp) -target_link_libraries(test_arrow PRIVATE gldraw) - -add_executable(test_billboard test_billboard.cpp) -target_link_libraries(test_billboard PRIVATE gldraw) - -add_executable(test_bounding_box test_bounding_box.cpp) -target_link_libraries(test_bounding_box PRIVATE gldraw) - -add_executable(test_canvas test_canvas.cpp) -target_link_libraries(test_canvas PRIVATE gldraw) - -add_executable(test_coordinate_frame test_coordinate_frame.cpp) -target_link_libraries(test_coordinate_frame PRIVATE gldraw) - -add_executable(test_cylinder test_cylinder.cpp) -target_link_libraries(test_cylinder PRIVATE gldraw) - -add_executable(test_frustum test_frustum.cpp) -target_link_libraries(test_frustum PRIVATE gldraw) - -add_executable(test_grid test_grid.cpp) -target_link_libraries(test_grid PRIVATE gldraw) - -add_executable(test_line_strip test_line_strip.cpp) -target_link_libraries(test_line_strip PRIVATE gldraw) - -add_executable(test_mesh test_mesh.cpp) -target_link_libraries(test_mesh PRIVATE gldraw) - -add_executable(test_point_cloud test_point_cloud.cpp) -target_link_libraries(test_point_cloud PRIVATE gldraw) - -add_executable(test_path test_path.cpp) -target_link_libraries(test_path PRIVATE gldraw) - -add_executable(test_plane test_plane.cpp) -target_link_libraries(test_plane PRIVATE gldraw) - -add_executable(test_pose test_pose.cpp) -target_link_libraries(test_pose PRIVATE gldraw) - -add_executable(test_sphere test_sphere.cpp) -target_link_libraries(test_sphere PRIVATE gldraw) - - -add_executable(test_texture test_texture.cpp) -target_link_libraries(test_texture PRIVATE gldraw) - -add_executable(test_triangle test_triangle.cpp) -target_link_libraries(test_triangle PRIVATE gldraw) - diff --git a/src/image/CMakeLists.txt b/src/image/CMakeLists.txt new file mode 100644 index 0000000..68c3086 --- /dev/null +++ b/src/image/CMakeLists.txt @@ -0,0 +1,49 @@ +# `image` provides image display and annotation widgets backed by OpenCV. +# Use this module to show camera frames, debug images, or annotated cv::Mat +# data inside a panel. For 2D vector drawing or charts, see canvas/ or plot/. +# +# OpenCV is required. If absent, the module is skipped quietly. + +find_package(OpenCV QUIET) +if(NOT OpenCV_FOUND) + message(STATUS "OpenCV not found — skipping image/ module") + return() +endif() + +find_package(Threads REQUIRED) +find_package(OpenGL REQUIRED) + +add_library(image + src/cv_io.cpp + src/cv_canvas.cpp + src/cv_colors.cpp + src/color_maps.cpp + src/details/image_utils.cpp + src/cv_image_widget.cpp + src/buffered_cv_image_widget.cpp) +target_link_libraries(image PUBLIC + core + imcore + viewer + stb + Threads::Threads + OpenGL::GL + ${OpenCV_LIBS}) +target_include_directories(image PUBLIC + $ + $ + PRIVATE src ${OpenCV_INCLUDE_DIRS}) + +if(BUILD_TESTING) + add_subdirectory(test) +endif() + +install(TARGETS image + EXPORT quickvizTargets + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib + RUNTIME DESTINATION bin + INCLUDES DESTINATION include) + +install(DIRECTORY include/ + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) diff --git a/src/widget/include/widget/buffered_cv_image_widget.hpp b/src/image/include/image/buffered_cv_image_widget.hpp similarity index 96% rename from src/widget/include/widget/buffered_cv_image_widget.hpp rename to src/image/include/image/buffered_cv_image_widget.hpp index dcbdb50..f327fab 100644 --- a/src/widget/include/widget/buffered_cv_image_widget.hpp +++ b/src/image/include/image/buffered_cv_image_widget.hpp @@ -17,7 +17,7 @@ #include "glad/glad.h" -#include "imview/panel.hpp" +#include "viewer/panel.hpp" namespace quickviz { class BufferedCvImageWidget : public Panel { diff --git a/src/cvdraw/include/cvdraw/color_maps.hpp b/src/image/include/image/color_maps.hpp similarity index 100% rename from src/cvdraw/include/cvdraw/color_maps.hpp rename to src/image/include/image/color_maps.hpp diff --git a/src/cvdraw/include/cvdraw/cv_canvas.hpp b/src/image/include/image/cv_canvas.hpp similarity index 99% rename from src/cvdraw/include/cvdraw/cv_canvas.hpp rename to src/image/include/image/cv_canvas.hpp index 81e6af7..65e5d10 100644 --- a/src/cvdraw/include/cvdraw/cv_canvas.hpp +++ b/src/image/include/image/cv_canvas.hpp @@ -18,7 +18,7 @@ #include -#include "cvdraw/cv_colors.hpp" +#include "image/cv_colors.hpp" namespace quickviz { struct CPoint { diff --git a/src/cvdraw/include/cvdraw/cv_colors.hpp b/src/image/include/image/cv_colors.hpp similarity index 100% rename from src/cvdraw/include/cvdraw/cv_colors.hpp rename to src/image/include/image/cv_colors.hpp diff --git a/src/widget/include/widget/cv_image_widget.hpp b/src/image/include/image/cv_image_widget.hpp similarity index 96% rename from src/widget/include/widget/cv_image_widget.hpp rename to src/image/include/image/cv_image_widget.hpp index d1075c2..488519d 100644 --- a/src/widget/include/widget/cv_image_widget.hpp +++ b/src/image/include/image/cv_image_widget.hpp @@ -14,7 +14,7 @@ #include -#include "imview/panel.hpp" +#include "viewer/panel.hpp" namespace quickviz { class CvImageWidget : public Panel { diff --git a/src/cvdraw/include/cvdraw/cv_io.hpp b/src/image/include/image/cv_io.hpp similarity index 89% rename from src/cvdraw/include/cvdraw/cv_io.hpp rename to src/image/include/image/cv_io.hpp index 6e8c54d..4c3036d 100644 --- a/src/cvdraw/include/cvdraw/cv_io.hpp +++ b/src/image/include/image/cv_io.hpp @@ -14,9 +14,9 @@ #include -#include "cvdraw/cv_colors.hpp" -#include "cvdraw/color_maps.hpp" -#include "cvdraw/cv_canvas.hpp" +#include "image/cv_colors.hpp" +#include "image/color_maps.hpp" +#include "image/cv_canvas.hpp" namespace quickviz { namespace CvIO { diff --git a/src/widget/include/widget/details/image_utils.hpp b/src/image/include/image/details/image_utils.hpp similarity index 100% rename from src/widget/include/widget/details/image_utils.hpp rename to src/image/include/image/details/image_utils.hpp diff --git a/src/cvdraw/include/cvdraw/cvdraw.hpp b/src/image/include/image/image.hpp similarity index 59% rename from src/cvdraw/include/cvdraw/cvdraw.hpp rename to src/image/include/image/image.hpp index bf0f172..5e12597 100644 --- a/src/cvdraw/include/cvdraw/cvdraw.hpp +++ b/src/image/include/image/image.hpp @@ -10,9 +10,9 @@ #ifndef CV_DRAW_HPP #define CV_DRAW_HPP -#include "cvdraw/cv_io.hpp" -#include "cvdraw/cv_canvas.hpp" -#include "cvdraw/cv_colors.hpp" -#include "cvdraw/color_maps.hpp" +#include "image/cv_io.hpp" +#include "image/cv_canvas.hpp" +#include "image/cv_colors.hpp" +#include "image/color_maps.hpp" #endif /* CV_DRAW_HPP */ diff --git a/src/widget/src/buffered_cv_image_widget.cpp b/src/image/src/buffered_cv_image_widget.cpp similarity index 96% rename from src/widget/src/buffered_cv_image_widget.cpp rename to src/image/src/buffered_cv_image_widget.cpp index c7fc144..28b8464 100644 --- a/src/widget/src/buffered_cv_image_widget.cpp +++ b/src/image/src/buffered_cv_image_widget.cpp @@ -6,9 +6,9 @@ * @copyright Copyright (c) 2024 Ruixiang Du (rdu) */ -#include "widget/buffered_cv_image_widget.hpp" +#include "image/buffered_cv_image_widget.hpp" -#include "widget/details/image_utils.hpp" +#include "image/details/image_utils.hpp" namespace quickviz { BufferedCvImageWidget::BufferedCvImageWidget(const std::string& widget_name, diff --git a/src/cvdraw/src/color_maps.cpp b/src/image/src/color_maps.cpp similarity index 97% rename from src/cvdraw/src/color_maps.cpp rename to src/image/src/color_maps.cpp index 814635a..79ab5a9 100644 --- a/src/cvdraw/src/color_maps.cpp +++ b/src/image/src/color_maps.cpp @@ -7,7 +7,7 @@ * Copyright (c) 2019 Ruixiang Du (rdu) */ -#include "cvdraw/color_maps.hpp" +#include "image/color_maps.hpp" using namespace cv; diff --git a/src/cvdraw/src/cv_canvas.cpp b/src/image/src/cv_canvas.cpp similarity index 99% rename from src/cvdraw/src/cv_canvas.cpp rename to src/image/src/cv_canvas.cpp index ec28fa0..8d414b1 100644 --- a/src/cvdraw/src/cv_canvas.cpp +++ b/src/image/src/cv_canvas.cpp @@ -7,7 +7,7 @@ * Copyright (c) 2019 Ruixiang Du (rdu) */ -#include "cvdraw/cv_canvas.hpp" +#include "image/cv_canvas.hpp" #include #include diff --git a/src/cvdraw/src/cv_colors.cpp b/src/image/src/cv_colors.cpp similarity index 98% rename from src/cvdraw/src/cv_colors.cpp rename to src/image/src/cv_colors.cpp index 609665c..49d55c1 100644 --- a/src/cvdraw/src/cv_colors.cpp +++ b/src/image/src/cv_colors.cpp @@ -7,7 +7,7 @@ * Copyright (c) 2019 Ruixiang Du (rdu) */ -#include "cvdraw/cv_colors.hpp" +#include "image/cv_colors.hpp" using namespace quickviz; using namespace cv; diff --git a/src/widget/src/cv_image_widget.cpp b/src/image/src/cv_image_widget.cpp similarity index 96% rename from src/widget/src/cv_image_widget.cpp rename to src/image/src/cv_image_widget.cpp index 82a48e8..392ea27 100644 --- a/src/widget/src/cv_image_widget.cpp +++ b/src/image/src/cv_image_widget.cpp @@ -6,10 +6,10 @@ * @copyright Copyright (c) 2024 Ruixiang Du (rdu) */ -#include "widget/cv_image_widget.hpp" +#include "image/cv_image_widget.hpp" #include "glad/glad.h" -#include "widget/details/image_utils.hpp" +#include "image/details/image_utils.hpp" namespace quickviz { CvImageWidget::CvImageWidget(const std::string& widget_name) diff --git a/src/cvdraw/src/cv_io.cpp b/src/image/src/cv_io.cpp similarity index 97% rename from src/cvdraw/src/cv_io.cpp rename to src/image/src/cv_io.cpp index a8dcd85..d3e8d83 100644 --- a/src/cvdraw/src/cv_io.cpp +++ b/src/image/src/cv_io.cpp @@ -7,7 +7,7 @@ * Copyright (c) 2018 Ruixiang Du (rdu) */ -#include "cvdraw/cv_io.hpp" +#include "image/cv_io.hpp" #include #include diff --git a/src/widget/src/details/image_utils.cpp b/src/image/src/details/image_utils.cpp similarity index 96% rename from src/widget/src/details/image_utils.cpp rename to src/image/src/details/image_utils.cpp index 22b6161..02913c7 100644 --- a/src/widget/src/details/image_utils.cpp +++ b/src/image/src/details/image_utils.cpp @@ -6,7 +6,7 @@ * @copyright Copyright (c) 2024 Ruixiang Du (rdu) */ -#include "widget/details/image_utils.hpp" +#include "image/details/image_utils.hpp" namespace quickviz { cv::Mat GenerateRandomMat(int width, int height) { diff --git a/src/image/test/CMakeLists.txt b/src/image/test/CMakeLists.txt new file mode 100644 index 0000000..9fb0480 --- /dev/null +++ b/src/image/test/CMakeLists.txt @@ -0,0 +1,17 @@ +add_executable(test_image_rw test_image_rw.cpp) +target_link_libraries(test_image_rw PUBLIC image) + +add_executable(test_cv_canvas test_cv_canvas.cpp) +target_link_libraries(test_cv_canvas PUBLIC image) + +add_executable(test_cv_drawmode test_cv_drawmode.cpp) +target_link_libraries(test_cv_drawmode PUBLIC image) + +add_executable(test_cv_drawfunc test_cv_drawfunc.cpp) +target_link_libraries(test_cv_drawfunc PUBLIC image) + +add_executable(test_cv_image_widget test_cv_image_widget.cpp) +target_link_libraries(test_cv_image_widget PUBLIC image) + +add_executable(test_buffered_cv_image_widget test_buffered_cv_image_widget.cpp) +target_link_libraries(test_buffered_cv_image_widget PUBLIC image) diff --git a/src/widget/test/test_buffered_cv_image_widget.cpp b/src/image/test/test_buffered_cv_image_widget.cpp similarity index 95% rename from src/widget/test/test_buffered_cv_image_widget.cpp rename to src/image/test/test_buffered_cv_image_widget.cpp index de9ff41..1a6dcbf 100644 --- a/src/widget/test/test_buffered_cv_image_widget.cpp +++ b/src/image/test/test_buffered_cv_image_widget.cpp @@ -16,11 +16,11 @@ #include "core/buffer/ring_buffer.hpp" #include "core/buffer/double_buffer.hpp" -#include "imview/viewer.hpp" -#include "imview/box.hpp" +#include "viewer/viewer.hpp" +#include "viewer/box.hpp" // #include "scene_objects/gl_triangle_scene_object.hpp" -#include "widget/buffered_cv_image_widget.hpp" +#include "image/buffered_cv_image_widget.hpp" using namespace quickviz; diff --git a/src/cvdraw/test/test_cv_canvas.cpp b/src/image/test/test_cv_canvas.cpp similarity index 95% rename from src/cvdraw/test/test_cv_canvas.cpp rename to src/image/test/test_cv_canvas.cpp index f823a19..66a3f51 100644 --- a/src/cvdraw/test/test_cv_canvas.cpp +++ b/src/image/test/test_cv_canvas.cpp @@ -1,6 +1,6 @@ #include -#include "cvdraw/cv_canvas.hpp" +#include "image/cv_canvas.hpp" using namespace quickviz; diff --git a/src/cvdraw/test/test_cv_drawfunc.cpp b/src/image/test/test_cv_drawfunc.cpp similarity index 97% rename from src/cvdraw/test/test_cv_drawfunc.cpp rename to src/image/test/test_cv_drawfunc.cpp index bf7a18e..b88f3b8 100644 --- a/src/cvdraw/test/test_cv_drawfunc.cpp +++ b/src/image/test/test_cv_drawfunc.cpp @@ -1,6 +1,6 @@ #include -#include "cvdraw/cvdraw.hpp" +#include "image/image.hpp" using namespace quickviz; diff --git a/src/cvdraw/test/test_cv_drawmode.cpp b/src/image/test/test_cv_drawmode.cpp similarity index 99% rename from src/cvdraw/test/test_cv_drawmode.cpp rename to src/image/test/test_cv_drawmode.cpp index 6df182e..074c3f4 100644 --- a/src/cvdraw/test/test_cv_drawmode.cpp +++ b/src/image/test/test_cv_drawmode.cpp @@ -1,6 +1,6 @@ #include -#include "cvdraw/cvdraw.hpp" +#include "image/image.hpp" using namespace quickviz; diff --git a/src/widget/test/test_cv_image_widget.cpp b/src/image/test/test_cv_image_widget.cpp similarity index 95% rename from src/widget/test/test_cv_image_widget.cpp rename to src/image/test/test_cv_image_widget.cpp index 6f4a46b..f68b41d 100644 --- a/src/widget/test/test_cv_image_widget.cpp +++ b/src/image/test/test_cv_image_widget.cpp @@ -12,8 +12,8 @@ #include -#include "imview/viewer.hpp" -#include "widget/cv_image_widget.hpp" +#include "viewer/viewer.hpp" +#include "image/cv_image_widget.hpp" // #include "scene_objects/gl_triangle_scene_object.hpp" diff --git a/src/cvdraw/test/test_image_rw.cpp b/src/image/test/test_image_rw.cpp similarity index 91% rename from src/cvdraw/test/test_image_rw.cpp rename to src/image/test/test_image_rw.cpp index a18b124..ffcb934 100644 --- a/src/cvdraw/test/test_image_rw.cpp +++ b/src/image/test/test_image_rw.cpp @@ -1,6 +1,6 @@ #include -#include "cvdraw/cvdraw.hpp" +#include "image/image.hpp" using namespace quickviz; diff --git a/src/pcl_bridge/CMakeLists.txt b/src/pcl_bridge/CMakeLists.txt index c799eb3..205096a 100644 --- a/src/pcl_bridge/CMakeLists.txt +++ b/src/pcl_bridge/CMakeLists.txt @@ -1,11 +1,11 @@ -# Create visualization library -add_library(pcl_bridge - # PCL bridge utilities (optional, depends on PCL) -) - # Check for PCL and conditionally compile PCL bridge find_package(PCL QUIET COMPONENTS common io) if(PCL_FOUND) + # Create visualization library + add_library(pcl_bridge + # PCL bridge utilities (optional, depends on PCL) + ) + message(STATUS "Found PCL: ${PCL_VERSION} - enabling PCL bridge utilities") target_sources(pcl_bridge PRIVATE src/pcl_conversions.cpp @@ -15,34 +15,34 @@ if(PCL_FOUND) target_include_directories(pcl_bridge PRIVATE ${PCL_INCLUDE_DIRS}) target_link_libraries(pcl_bridge PRIVATE ${PCL_LIBRARIES}) target_compile_definitions(pcl_bridge PUBLIC QUICKVIZ_WITH_PCL PRIVATE ${PCL_DEFINITIONS}) -else() - message(STATUS "PCL not found - PCL bridge utilities will not be available") -endif() -# Link with gldraw for rendering capabilities -target_link_libraries(pcl_bridge PUBLIC gldraw) + # Link with scene for rendering capabilities + target_link_libraries(pcl_bridge PUBLIC scene) -# Include directories -target_include_directories(pcl_bridge PUBLIC - $ - $ - PRIVATE src -) + # Include directories + target_include_directories(pcl_bridge PUBLIC + $ + $ + PRIVATE src + ) -# Tests for pcl_bridge module -if (BUILD_TESTING) - add_subdirectory(test) -endif () + # Tests for pcl_bridge module + if (BUILD_TESTING) + add_subdirectory(test) + endif () -# Installation -install(TARGETS pcl_bridge - EXPORT quickvizTargets - LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib - RUNTIME DESTINATION bin - INCLUDES DESTINATION include -) + # Installation + install(TARGETS pcl_bridge + EXPORT quickvizTargets + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib + RUNTIME DESTINATION bin + INCLUDES DESTINATION include + ) -install(DIRECTORY include/ - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} -) \ No newline at end of file + install(DIRECTORY include/ + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + ) +else() + message(STATUS "PCL not found - PCL bridge utilities will not be available") +endif() \ No newline at end of file diff --git a/src/pcl_bridge/include/pcl_bridge/pcl_conversions.hpp b/src/pcl_bridge/include/pcl_bridge/pcl_conversions.hpp index 0692079..ac4892a 100644 --- a/src/pcl_bridge/include/pcl_bridge/pcl_conversions.hpp +++ b/src/pcl_bridge/include/pcl_bridge/pcl_conversions.hpp @@ -13,7 +13,7 @@ #include #include #include -#include "gldraw/renderable/point_cloud.hpp" +#include "scene/renderable/point_cloud.hpp" // Forward declarations for PCL types to avoid requiring PCL headers in this file namespace pcl { diff --git a/src/pcl_bridge/src/pcl_conversions.cpp b/src/pcl_bridge/src/pcl_conversions.cpp index bdc5897..2b41b91 100644 --- a/src/pcl_bridge/src/pcl_conversions.cpp +++ b/src/pcl_bridge/src/pcl_conversions.cpp @@ -7,7 +7,7 @@ */ #include "pcl_bridge/pcl_conversions.hpp" -#include "gldraw/renderable/point_cloud.hpp" +#include "scene/renderable/point_cloud.hpp" // Include PCL headers only in implementation #include diff --git a/src/pcl_bridge/src/pcl_loader.cpp b/src/pcl_bridge/src/pcl_loader.cpp index d4aa9b7..7f3e091 100644 --- a/src/pcl_bridge/src/pcl_loader.cpp +++ b/src/pcl_bridge/src/pcl_loader.cpp @@ -8,7 +8,7 @@ #include "pcl_bridge/pcl_loader.hpp" #include "pcl_bridge/pcl_conversions.hpp" -#include "gldraw/renderable/point_cloud.hpp" +#include "scene/renderable/point_cloud.hpp" #include #include diff --git a/src/pcl_bridge/src/pcl_visualization.cpp b/src/pcl_bridge/src/pcl_visualization.cpp index 54c78b2..56e8eb2 100644 --- a/src/pcl_bridge/src/pcl_visualization.cpp +++ b/src/pcl_bridge/src/pcl_visualization.cpp @@ -7,7 +7,7 @@ */ #include "pcl_bridge/pcl_visualization.hpp" -#include "gldraw/renderable/point_cloud.hpp" +#include "scene/renderable/point_cloud.hpp" #include #include diff --git a/src/pcl_bridge/test/CMakeLists.txt b/src/pcl_bridge/test/CMakeLists.txt index c3d99ed..593c9a2 100644 --- a/src/pcl_bridge/test/CMakeLists.txt +++ b/src/pcl_bridge/test/CMakeLists.txt @@ -11,23 +11,23 @@ if(PCL_FOUND) add_executable(test_pcd test_pcd.cpp) target_include_directories(test_pcd PRIVATE ${PCL_INCLUDE_DIRS}) - target_link_libraries(test_pcd PRIVATE gldraw pcl_bridge ${PCL_LIBRARIES}) + target_link_libraries(test_pcd PRIVATE scene pcl_bridge ${PCL_LIBRARIES}) target_compile_definitions(test_pcd PRIVATE ${PCL_DEFINITIONS}) add_executable(test_pcl_bridge test_pcl_bridge.cpp) target_include_directories(test_pcl_bridge PRIVATE ${PCL_INCLUDE_DIRS}) - target_link_libraries(test_pcl_bridge PRIVATE gldraw pcl_bridge ${PCL_LIBRARIES}) + target_link_libraries(test_pcl_bridge PRIVATE scene pcl_bridge ${PCL_LIBRARIES}) target_compile_definitions(test_pcl_bridge PRIVATE ${PCL_DEFINITIONS}) # add_executable(test_pcl_loader unit_test/test_pcl_loader.cpp) # target_include_directories(test_pcl_loader PRIVATE ${PCL_INCLUDE_DIRS}) -# target_link_libraries(test_pcl_loader PRIVATE gldraw ${PCL_LIBRARIES} gtest_main) +# target_link_libraries(test_pcl_loader PRIVATE scene ${PCL_LIBRARIES} gtest_main) # target_compile_definitions(test_pcl_loader PRIVATE ${PCL_DEFINITIONS}) add_executable(test_pcl_loader_render test_pcl_loader_render.cpp) target_include_directories(test_pcl_loader_render PRIVATE ${PCL_INCLUDE_DIRS}) - target_link_libraries(test_pcl_loader_render PRIVATE gldraw pcl_bridge ${PCL_LIBRARIES}) + target_link_libraries(test_pcl_loader_render PRIVATE scene pcl_bridge ${PCL_LIBRARIES}) target_compile_definitions(test_pcl_loader_render PRIVATE ${PCL_DEFINITIONS}) diff --git a/src/pcl_bridge/test/test_pcd.cpp b/src/pcl_bridge/test/test_pcd.cpp index 243896e..34844a6 100644 --- a/src/pcl_bridge/test/test_pcd.cpp +++ b/src/pcl_bridge/test/test_pcd.cpp @@ -16,12 +16,12 @@ #include #include -#include "imview/box.hpp" -#include "imview/viewer.hpp" +#include "viewer/box.hpp" +#include "viewer/viewer.hpp" -#include "gldraw/gl_scene_panel.hpp" -#include "gldraw/renderable/grid.hpp" -#include "gldraw/renderable/point_cloud.hpp" +#include "scene/gl_scene_panel.hpp" +#include "scene/renderable/grid.hpp" +#include "scene/renderable/point_cloud.hpp" using namespace quickviz; diff --git a/src/pcl_bridge/test/test_pcl_bridge.cpp b/src/pcl_bridge/test/test_pcl_bridge.cpp index fd2905d..8bd8771 100644 --- a/src/pcl_bridge/test/test_pcl_bridge.cpp +++ b/src/pcl_bridge/test/test_pcl_bridge.cpp @@ -11,11 +11,11 @@ #include #include -#include "imview/viewer.hpp" -#include "imview/box.hpp" -#include "gldraw/gl_scene_panel.hpp" -#include "gldraw/renderable/grid.hpp" -#include "gldraw/renderable/point_cloud.hpp" +#include "viewer/viewer.hpp" +#include "viewer/box.hpp" +#include "scene/gl_scene_panel.hpp" +#include "scene/renderable/grid.hpp" +#include "scene/renderable/point_cloud.hpp" #ifdef QUICKVIZ_WITH_PCL #include diff --git a/src/pcl_bridge/test/test_pcl_loader_render.cpp b/src/pcl_bridge/test/test_pcl_loader_render.cpp index 61c3d36..9cd567f 100644 --- a/src/pcl_bridge/test/test_pcl_loader_render.cpp +++ b/src/pcl_bridge/test/test_pcl_loader_render.cpp @@ -18,13 +18,13 @@ #include #include -#include "imview/box.hpp" -#include "imview/viewer.hpp" -#include "imview/panel.hpp" +#include "viewer/box.hpp" +#include "viewer/viewer.hpp" +#include "viewer/panel.hpp" -#include "gldraw/gl_scene_panel.hpp" -#include "gldraw/renderable/grid.hpp" -#include "gldraw/renderable/point_cloud.hpp" +#include "scene/gl_scene_panel.hpp" +#include "scene/renderable/grid.hpp" +#include "scene/renderable/point_cloud.hpp" #include "pcl_bridge/pcl_loader.hpp" using namespace quickviz; diff --git a/src/pcl_bridge/test/unit_test/CMakeLists.txt b/src/pcl_bridge/test/unit_test/CMakeLists.txt index 97f942e..9b7914c 100644 --- a/src/pcl_bridge/test/unit_test/CMakeLists.txt +++ b/src/pcl_bridge/test/unit_test/CMakeLists.txt @@ -1,9 +1,9 @@ # add unit tests -add_executable(gldraw_unit_tests +add_executable(scene_unit_tests test_pcl_loader.cpp) -target_link_libraries(gldraw_unit_tests PRIVATE gtest_main gmock imview gldraw pcl_bridge ${PCL_LIBRARIES}) -# get_target_property(PRIVATE_HEADERS imview INCLUDE_DIRECTORIES) -target_include_directories(gldraw_unit_tests PRIVATE ${PRIVATE_HEADERS}) +target_link_libraries(scene_unit_tests PRIVATE gtest_main gmock viewer scene pcl_bridge ${PCL_LIBRARIES}) +# get_target_property(PRIVATE_HEADERS viewer INCLUDE_DIRECTORIES) +target_include_directories(scene_unit_tests PRIVATE ${PRIVATE_HEADERS}) -gtest_discover_tests(gldraw_unit_tests) -add_test(NAME gtest_all COMMAND gldraw_unit_tests) +gtest_discover_tests(scene_unit_tests) +add_test(NAME gtest_all COMMAND scene_unit_tests) diff --git a/src/pcl_bridge/test/unit_test/test_pcl_loader.cpp b/src/pcl_bridge/test/unit_test/test_pcl_loader.cpp index f683a1c..92bc113 100644 --- a/src/pcl_bridge/test/unit_test/test_pcl_loader.cpp +++ b/src/pcl_bridge/test/unit_test/test_pcl_loader.cpp @@ -12,7 +12,7 @@ #include #include "pcl_bridge/pcl_loader.hpp" -#include "gldraw/renderable/point_cloud.hpp" +#include "scene/renderable/point_cloud.hpp" #ifdef QUICKVIZ_WITH_PCL #include diff --git a/src/plot/CMakeLists.txt b/src/plot/CMakeLists.txt new file mode 100644 index 0000000..aee9d32 --- /dev/null +++ b/src/plot/CMakeLists.txt @@ -0,0 +1,35 @@ +# find dependency +find_package(Threads REQUIRED) + +# add library +# +# `plot` provides QuickViz wrappers around ImPlot (2D) and ImPlot3D (3D). +# The umbrella headers `plot/plot2d.hpp` and `plot/plot3d.hpp` simply +# re-export the underlying upstream APIs; concrete widgets like +# `rt_line_plot_widget` build on top of them. +add_library(plot + src/details/scrolling_plot_buffer.cpp + src/rt_line_plot_widget.cpp) +target_link_libraries(plot PUBLIC + core + imcore + viewer + Threads::Threads) +target_include_directories(plot PUBLIC + $ + $ + PRIVATE src) + +if(BUILD_TESTING) + add_subdirectory(test) +endif() + +install(TARGETS plot + EXPORT quickvizTargets + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib + RUNTIME DESTINATION bin + INCLUDES DESTINATION include) + +install(DIRECTORY include/ + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) diff --git a/src/widget/include/widget/details/scrolling_plot_buffer.hpp b/src/plot/include/plot/details/scrolling_plot_buffer.hpp similarity index 100% rename from src/widget/include/widget/details/scrolling_plot_buffer.hpp rename to src/plot/include/plot/details/scrolling_plot_buffer.hpp diff --git a/src/plot/include/plot/plot2d.hpp b/src/plot/include/plot/plot2d.hpp new file mode 100644 index 0000000..a30e940 --- /dev/null +++ b/src/plot/include/plot/plot2d.hpp @@ -0,0 +1,17 @@ +/* + * @file plot2d.hpp + * @brief Re-export of ImPlot for 2D charting inside QuickViz panels + * + * Use this header when you want to draw a 2D chart (line, scatter, bar, etc.) + * directly into an ImGui window via ImPlot's immediate-mode API. For a + * ready-made real-time line plot widget, see rt_line_plot_widget.hpp. + * + * Copyright (c) 2026 Ruixiang Du (rdu) + */ + +#ifndef QUICKVIZ_PLOT_PLOT2D_HPP +#define QUICKVIZ_PLOT_PLOT2D_HPP + +#include "implot/implot.h" + +#endif // QUICKVIZ_PLOT_PLOT2D_HPP diff --git a/src/plot/include/plot/plot3d.hpp b/src/plot/include/plot/plot3d.hpp new file mode 100644 index 0000000..4d9b7d5 --- /dev/null +++ b/src/plot/include/plot/plot3d.hpp @@ -0,0 +1,18 @@ +/* + * @file plot3d.hpp + * @brief Re-export of ImPlot3D for 3D charting inside QuickViz panels + * + * Use this header when you want to draw a 3D chart (scatter, surface, mesh, + * lines) directly into an ImGui window via ImPlot3D's immediate-mode API. + * Distinct from the `scene` module: `scene` builds a persistent, interactive + * 3D world; `plot3d` draws a 3D *chart* of data inside an ImGui window. + * + * Copyright (c) 2026 Ruixiang Du (rdu) + */ + +#ifndef QUICKVIZ_PLOT_PLOT3D_HPP +#define QUICKVIZ_PLOT_PLOT3D_HPP + +#include "implot3d/implot3d.h" + +#endif // QUICKVIZ_PLOT_PLOT3D_HPP diff --git a/src/widget/include/widget/rt_line_plot_widget.hpp b/src/plot/include/plot/rt_line_plot_widget.hpp similarity index 95% rename from src/widget/include/widget/rt_line_plot_widget.hpp rename to src/plot/include/plot/rt_line_plot_widget.hpp index c7b908c..a99aac2 100644 --- a/src/widget/include/widget/rt_line_plot_widget.hpp +++ b/src/plot/include/plot/rt_line_plot_widget.hpp @@ -14,9 +14,9 @@ #include "core/buffer/buffer_registry.hpp" -#include "imview/panel.hpp" +#include "viewer/panel.hpp" -#include "widget/details/scrolling_plot_buffer.hpp" +#include "plot/details/scrolling_plot_buffer.hpp" namespace quickviz { class RtLinePlotWidget : public Panel { diff --git a/src/widget/src/details/scrolling_plot_buffer.cpp b/src/plot/src/details/scrolling_plot_buffer.cpp similarity index 95% rename from src/widget/src/details/scrolling_plot_buffer.cpp rename to src/plot/src/details/scrolling_plot_buffer.cpp index 502dad9..b44b3db 100644 --- a/src/widget/src/details/scrolling_plot_buffer.cpp +++ b/src/plot/src/details/scrolling_plot_buffer.cpp @@ -7,7 +7,7 @@ * Copyright (c) 2021 Ruixiang Du (rdu) */ -#include "widget/details/scrolling_plot_buffer.hpp" +#include "plot/details/scrolling_plot_buffer.hpp" #include diff --git a/src/widget/src/rt_line_plot_widget.cpp b/src/plot/src/rt_line_plot_widget.cpp similarity index 99% rename from src/widget/src/rt_line_plot_widget.cpp rename to src/plot/src/rt_line_plot_widget.cpp index d2fd1cd..77e68c2 100644 --- a/src/widget/src/rt_line_plot_widget.cpp +++ b/src/plot/src/rt_line_plot_widget.cpp @@ -6,7 +6,7 @@ * @copyright Copyright (c) 2024 Ruixiang Du (rdu) */ -#include "widget/rt_line_plot_widget.hpp" +#include "plot/rt_line_plot_widget.hpp" #include #include diff --git a/src/plot/test/CMakeLists.txt b/src/plot/test/CMakeLists.txt new file mode 100644 index 0000000..d9eb262 --- /dev/null +++ b/src/plot/test/CMakeLists.txt @@ -0,0 +1,3 @@ +add_executable(test_implot_widget test_implot_widget.cpp) +target_link_libraries(test_implot_widget PRIVATE plot) + diff --git a/src/widget/test/test_implot_widget.cpp b/src/plot/test/test_implot_widget.cpp similarity index 97% rename from src/widget/test/test_implot_widget.cpp rename to src/plot/test/test_implot_widget.cpp index 16e1a9a..125e475 100644 --- a/src/widget/test/test_implot_widget.cpp +++ b/src/plot/test/test_implot_widget.cpp @@ -14,8 +14,8 @@ #include "core/buffer/buffer_registry.hpp" #include "core/buffer/ring_buffer.hpp" -#include "imview/viewer.hpp" -#include "widget/rt_line_plot_widget.hpp" +#include "viewer/viewer.hpp" +#include "plot/rt_line_plot_widget.hpp" // #include "scene_objects/imtext_panel.hpp" // #include "scene_objects/gl_triangle_scene_object.hpp" diff --git a/src/gldraw/CMakeLists.txt b/src/scene/CMakeLists.txt similarity index 85% rename from src/gldraw/CMakeLists.txt rename to src/scene/CMakeLists.txt index 2bddbae..aae95c9 100644 --- a/src/gldraw/CMakeLists.txt +++ b/src/scene/CMakeLists.txt @@ -3,10 +3,10 @@ find_package(Threads REQUIRED) find_package(OpenGL REQUIRED) # add library -add_library(gldraw +add_library(scene ## gui integration src/gl_scene_panel.cpp - src/gl_viewer.cpp + src/scene_app.cpp ## core rendering components src/shader.cpp src/shader_program.cpp @@ -26,7 +26,7 @@ add_library(gldraw src/renderable/details/canvas_data_manager.cpp src/renderable/details/point_layer_manager.cpp src/renderable/grid.cpp - src/renderable/triangle.cpp + src/renderable/occupancy_grid.cpp src/renderable/point_cloud.cpp src/renderable/canvas.cpp src/renderable/coordinate_frame.cpp @@ -44,6 +44,7 @@ add_library(gldraw src/renderable/plane.cpp src/renderable/pose.cpp src/renderable/path.cpp + src/renderable/tf_frame_tree.cpp ## feedback system src/feedback/visual_feedback_system.cpp src/feedback/point_cloud_feedback_handler.cpp @@ -52,14 +53,14 @@ add_library(gldraw src/tools/interaction_tool.cpp src/tools/point_selection_tool.cpp ) -target_link_libraries(gldraw PUBLIC core imcore imview stb +target_link_libraries(scene PUBLIC core imcore viewer stb Threads::Threads OpenGL::GL) -if (IMVIEW_WITH_GLAD) - target_link_libraries(gldraw PUBLIC glad) - target_compile_definitions(gldraw PUBLIC IMVIEW_WITH_GLAD) +if (VIEWER_WITH_GLAD) + target_link_libraries(scene PUBLIC glad) + target_compile_definitions(scene PUBLIC VIEWER_WITH_GLAD) endif () -target_include_directories(gldraw PUBLIC +target_include_directories(scene PUBLIC $ $ PRIVATE src) @@ -68,7 +69,7 @@ if (BUILD_TESTING) add_subdirectory(test) endif () -install(TARGETS gldraw +install(TARGETS scene EXPORT quickvizTargets LIBRARY DESTINATION lib ARCHIVE DESTINATION lib diff --git a/src/gldraw/include/gldraw/camera.hpp b/src/scene/include/scene/camera.hpp similarity index 100% rename from src/gldraw/include/gldraw/camera.hpp rename to src/scene/include/scene/camera.hpp diff --git a/src/gldraw/include/gldraw/camera_control_config.hpp b/src/scene/include/scene/camera_control_config.hpp similarity index 97% rename from src/gldraw/include/gldraw/camera_control_config.hpp rename to src/scene/include/scene/camera_control_config.hpp index 2beaf02..735074d 100644 --- a/src/gldraw/include/gldraw/camera_control_config.hpp +++ b/src/scene/include/scene/camera_control_config.hpp @@ -6,10 +6,10 @@ * @copyright Copyright (c) 2025 Ruixiang Du (rdu) */ -#ifndef GLDRAW_CAMERA_CONTROL_CONFIG_HPP -#define GLDRAW_CAMERA_CONTROL_CONFIG_HPP +#ifndef SCENE_CAMERA_CONTROL_CONFIG_HPP +#define SCENE_CAMERA_CONTROL_CONFIG_HPP -#include "imview/input/input_types.hpp" +#include "viewer/input/input_types.hpp" #include "core/event/input_event.hpp" namespace quickviz { @@ -210,4 +210,4 @@ struct CameraControlConfig { } // namespace quickviz -#endif // GLDRAW_CAMERA_CONTROL_CONFIG_HPP \ No newline at end of file +#endif // SCENE_CAMERA_CONTROL_CONFIG_HPP \ No newline at end of file diff --git a/src/gldraw/include/gldraw/camera_controller.hpp b/src/scene/include/scene/camera_controller.hpp similarity index 99% rename from src/gldraw/include/gldraw/camera_controller.hpp rename to src/scene/include/scene/camera_controller.hpp index 52f5d20..9dac979 100644 --- a/src/gldraw/include/gldraw/camera_controller.hpp +++ b/src/scene/include/scene/camera_controller.hpp @@ -9,7 +9,7 @@ #ifndef QUICKVIZ_CAMERA_CONTROLLER_HPP #define QUICKVIZ_CAMERA_CONTROLLER_HPP -#include "gldraw/camera.hpp" +#include "scene/camera.hpp" #include #include #include diff --git a/src/gldraw/include/gldraw/coordinate_transformer.hpp b/src/scene/include/scene/coordinate_transformer.hpp similarity index 100% rename from src/gldraw/include/gldraw/coordinate_transformer.hpp rename to src/scene/include/scene/coordinate_transformer.hpp diff --git a/src/gldraw/include/gldraw/feedback/object_feedback_handler.hpp b/src/scene/include/scene/feedback/object_feedback_handler.hpp similarity index 99% rename from src/gldraw/include/gldraw/feedback/object_feedback_handler.hpp rename to src/scene/include/scene/feedback/object_feedback_handler.hpp index 877d717..702dac6 100644 --- a/src/gldraw/include/gldraw/feedback/object_feedback_handler.hpp +++ b/src/scene/include/scene/feedback/object_feedback_handler.hpp @@ -21,7 +21,7 @@ #include #include -#include "gldraw/feedback/visual_feedback_system.hpp" +#include "scene/feedback/visual_feedback_system.hpp" // Forward declarations namespace quickviz { diff --git a/src/gldraw/include/gldraw/feedback/point_cloud_feedback_handler.hpp b/src/scene/include/scene/feedback/point_cloud_feedback_handler.hpp similarity index 97% rename from src/gldraw/include/gldraw/feedback/point_cloud_feedback_handler.hpp rename to src/scene/include/scene/feedback/point_cloud_feedback_handler.hpp index 0bdfd7d..24f0abc 100644 --- a/src/gldraw/include/gldraw/feedback/point_cloud_feedback_handler.hpp +++ b/src/scene/include/scene/feedback/point_cloud_feedback_handler.hpp @@ -20,8 +20,8 @@ #include -#include "gldraw/feedback/visual_feedback_system.hpp" -#include "gldraw/renderable/details/point_layer_manager.hpp" +#include "scene/feedback/visual_feedback_system.hpp" +#include "scene/renderable/details/point_layer_manager.hpp" // Forward declarations namespace quickviz { diff --git a/src/gldraw/include/gldraw/feedback/visual_feedback_system.hpp b/src/scene/include/scene/feedback/visual_feedback_system.hpp similarity index 100% rename from src/gldraw/include/gldraw/feedback/visual_feedback_system.hpp rename to src/scene/include/scene/feedback/visual_feedback_system.hpp diff --git a/src/gldraw/include/gldraw/font_renderer.hpp b/src/scene/include/scene/font_renderer.hpp similarity index 100% rename from src/gldraw/include/gldraw/font_renderer.hpp rename to src/scene/include/scene/font_renderer.hpp diff --git a/src/gldraw/include/gldraw/frame_buffer.hpp b/src/scene/include/scene/frame_buffer.hpp similarity index 100% rename from src/gldraw/include/gldraw/frame_buffer.hpp rename to src/scene/include/scene/frame_buffer.hpp diff --git a/src/gldraw/include/gldraw/gl_scene_panel.hpp b/src/scene/include/scene/gl_scene_panel.hpp similarity index 95% rename from src/gldraw/include/gldraw/gl_scene_panel.hpp rename to src/scene/include/scene/gl_scene_panel.hpp index 930a2aa..146083a 100644 --- a/src/gldraw/include/gldraw/gl_scene_panel.hpp +++ b/src/scene/include/scene/gl_scene_panel.hpp @@ -16,12 +16,12 @@ #include -#include "imview/panel.hpp" -#include "gldraw/scene_manager.hpp" -#include "gldraw/interface/opengl_object.hpp" -#include "gldraw/camera.hpp" -#include "gldraw/camera_controller.hpp" -#include "gldraw/selection_manager.hpp" +#include "viewer/panel.hpp" +#include "scene/scene_manager.hpp" +#include "scene/interface/opengl_object.hpp" +#include "scene/camera.hpp" +#include "scene/camera_controller.hpp" +#include "scene/selection_manager.hpp" #include "scene_input_handler.hpp" // Forward declarations @@ -195,7 +195,7 @@ class GlScenePanel : public Panel { // UI state bool show_rendering_info_ = true; - // Modern imview-based input system - all input goes through this handler + // Modern viewer-based input system - all input goes through this handler std::shared_ptr scene_input_handler_; // Cached content position and size for coordinate conversion diff --git a/src/gldraw/include/gldraw/interface/opengl_object.hpp b/src/scene/include/scene/interface/opengl_object.hpp similarity index 100% rename from src/gldraw/include/gldraw/interface/opengl_object.hpp rename to src/scene/include/scene/interface/opengl_object.hpp diff --git a/src/gldraw/include/gldraw/renderable/arrow.hpp b/src/scene/include/scene/renderable/arrow.hpp similarity index 98% rename from src/gldraw/include/gldraw/renderable/arrow.hpp rename to src/scene/include/scene/renderable/arrow.hpp index 7301a6e..975a7ef 100644 --- a/src/gldraw/include/gldraw/renderable/arrow.hpp +++ b/src/scene/include/scene/renderable/arrow.hpp @@ -13,7 +13,7 @@ #include #include -#include "gldraw/interface/opengl_object.hpp" +#include "scene/interface/opengl_object.hpp" #include "../shader_program.hpp" namespace quickviz { diff --git a/src/gldraw/include/gldraw/renderable/billboard.hpp b/src/scene/include/scene/renderable/billboard.hpp similarity index 98% rename from src/gldraw/include/gldraw/renderable/billboard.hpp rename to src/scene/include/scene/renderable/billboard.hpp index 7522f14..99027fb 100644 --- a/src/gldraw/include/gldraw/renderable/billboard.hpp +++ b/src/scene/include/scene/renderable/billboard.hpp @@ -15,8 +15,8 @@ #include #include -#include "gldraw/interface/opengl_object.hpp" -#include "gldraw/font_renderer.hpp" +#include "scene/interface/opengl_object.hpp" +#include "scene/font_renderer.hpp" #include "../shader_program.hpp" namespace quickviz { diff --git a/src/gldraw/include/gldraw/renderable/bounding_box.hpp b/src/scene/include/scene/renderable/bounding_box.hpp similarity index 98% rename from src/gldraw/include/gldraw/renderable/bounding_box.hpp rename to src/scene/include/scene/renderable/bounding_box.hpp index f25ab20..a7d5f30 100644 --- a/src/gldraw/include/gldraw/renderable/bounding_box.hpp +++ b/src/scene/include/scene/renderable/bounding_box.hpp @@ -13,7 +13,7 @@ #include #include -#include "gldraw/renderable/geometric_primitive.hpp" +#include "scene/renderable/geometric_primitive.hpp" #include "../shader_program.hpp" namespace quickviz { diff --git a/src/gldraw/include/gldraw/renderable/canvas.hpp b/src/scene/include/scene/renderable/canvas.hpp similarity index 98% rename from src/gldraw/include/gldraw/renderable/canvas.hpp rename to src/scene/include/scene/renderable/canvas.hpp index fa17e56..1415f73 100644 --- a/src/gldraw/include/gldraw/renderable/canvas.hpp +++ b/src/scene/include/scene/renderable/canvas.hpp @@ -22,11 +22,11 @@ #include -#include "gldraw/interface/opengl_object.hpp" +#include "scene/interface/opengl_object.hpp" #include "../shader_program.hpp" -#include "gldraw/renderable/types.hpp" -#include "gldraw/renderable/details/canvas_batching.hpp" -#include "gldraw/renderable/details/canvas_performance.hpp" +#include "scene/renderable/types.hpp" +#include "scene/renderable/details/canvas_batching.hpp" +#include "scene/renderable/details/canvas_performance.hpp" // Forward declarations for internal components namespace quickviz { diff --git a/src/gldraw/include/gldraw/renderable/coordinate_frame.hpp b/src/scene/include/scene/renderable/coordinate_frame.hpp similarity index 97% rename from src/gldraw/include/gldraw/renderable/coordinate_frame.hpp rename to src/scene/include/scene/renderable/coordinate_frame.hpp index fee2070..e64ea54 100644 --- a/src/gldraw/include/gldraw/renderable/coordinate_frame.hpp +++ b/src/scene/include/scene/renderable/coordinate_frame.hpp @@ -14,7 +14,7 @@ #include #include -#include "gldraw/interface/opengl_object.hpp" +#include "scene/interface/opengl_object.hpp" #include "../shader_program.hpp" namespace quickviz { diff --git a/src/gldraw/include/gldraw/renderable/cylinder.hpp b/src/scene/include/scene/renderable/cylinder.hpp similarity index 99% rename from src/gldraw/include/gldraw/renderable/cylinder.hpp rename to src/scene/include/scene/renderable/cylinder.hpp index d578f0b..5fbab9e 100644 --- a/src/gldraw/include/gldraw/renderable/cylinder.hpp +++ b/src/scene/include/scene/renderable/cylinder.hpp @@ -13,7 +13,7 @@ #include #include -#include "gldraw/renderable/geometric_primitive.hpp" +#include "scene/renderable/geometric_primitive.hpp" #include "../shader_program.hpp" namespace quickviz { diff --git a/src/gldraw/include/gldraw/renderable/details/canvas_batching.hpp b/src/scene/include/scene/renderable/details/canvas_batching.hpp similarity index 98% rename from src/gldraw/include/gldraw/renderable/details/canvas_batching.hpp rename to src/scene/include/scene/renderable/details/canvas_batching.hpp index a2f4d77..8aee1fd 100644 --- a/src/gldraw/include/gldraw/renderable/details/canvas_batching.hpp +++ b/src/scene/include/scene/renderable/details/canvas_batching.hpp @@ -13,7 +13,7 @@ #include #include #include -#include "gldraw/renderable/types.hpp" +#include "scene/renderable/types.hpp" namespace quickviz { diff --git a/src/gldraw/include/gldraw/renderable/details/canvas_performance.hpp b/src/scene/include/scene/renderable/details/canvas_performance.hpp similarity index 100% rename from src/gldraw/include/gldraw/renderable/details/canvas_performance.hpp rename to src/scene/include/scene/renderable/details/canvas_performance.hpp diff --git a/src/gldraw/include/gldraw/renderable/details/point_layer_manager.hpp b/src/scene/include/scene/renderable/details/point_layer_manager.hpp similarity index 100% rename from src/gldraw/include/gldraw/renderable/details/point_layer_manager.hpp rename to src/scene/include/scene/renderable/details/point_layer_manager.hpp diff --git a/src/gldraw/include/gldraw/renderable/frustum.hpp b/src/scene/include/scene/renderable/frustum.hpp similarity index 99% rename from src/gldraw/include/gldraw/renderable/frustum.hpp rename to src/scene/include/scene/renderable/frustum.hpp index 9ff4e25..b8009bd 100644 --- a/src/gldraw/include/gldraw/renderable/frustum.hpp +++ b/src/scene/include/scene/renderable/frustum.hpp @@ -13,7 +13,7 @@ #include #include -#include "gldraw/interface/opengl_object.hpp" +#include "scene/interface/opengl_object.hpp" #include "../shader_program.hpp" namespace quickviz { diff --git a/src/gldraw/include/gldraw/renderable/geometric_primitive.hpp b/src/scene/include/scene/renderable/geometric_primitive.hpp similarity index 99% rename from src/gldraw/include/gldraw/renderable/geometric_primitive.hpp rename to src/scene/include/scene/renderable/geometric_primitive.hpp index f90b1f2..29c9efc 100644 --- a/src/gldraw/include/gldraw/renderable/geometric_primitive.hpp +++ b/src/scene/include/scene/renderable/geometric_primitive.hpp @@ -18,7 +18,7 @@ #include #include -#include "gldraw/interface/opengl_object.hpp" +#include "scene/interface/opengl_object.hpp" #include "../shader_program.hpp" namespace quickviz { diff --git a/src/gldraw/include/gldraw/renderable/grid.hpp b/src/scene/include/scene/renderable/grid.hpp similarity index 96% rename from src/gldraw/include/gldraw/renderable/grid.hpp rename to src/scene/include/scene/renderable/grid.hpp index aeeca35..0f6ee17 100644 --- a/src/gldraw/include/gldraw/renderable/grid.hpp +++ b/src/scene/include/scene/renderable/grid.hpp @@ -14,7 +14,7 @@ #include -#include "gldraw/interface/opengl_object.hpp" +#include "scene/interface/opengl_object.hpp" #include "../shader_program.hpp" namespace quickviz { diff --git a/src/gldraw/include/gldraw/renderable/line_strip.hpp b/src/scene/include/scene/renderable/line_strip.hpp similarity index 97% rename from src/gldraw/include/gldraw/renderable/line_strip.hpp rename to src/scene/include/scene/renderable/line_strip.hpp index e8f4462..7fc9708 100644 --- a/src/gldraw/include/gldraw/renderable/line_strip.hpp +++ b/src/scene/include/scene/renderable/line_strip.hpp @@ -13,9 +13,9 @@ #include #include -#include "gldraw/interface/opengl_object.hpp" +#include "scene/interface/opengl_object.hpp" #include "../shader_program.hpp" -#include "gldraw/renderable/types.hpp" +#include "scene/renderable/types.hpp" namespace quickviz { diff --git a/src/gldraw/include/gldraw/renderable/mesh.hpp b/src/scene/include/scene/renderable/mesh.hpp similarity index 98% rename from src/gldraw/include/gldraw/renderable/mesh.hpp rename to src/scene/include/scene/renderable/mesh.hpp index 6d1420c..d58ecf0 100644 --- a/src/gldraw/include/gldraw/renderable/mesh.hpp +++ b/src/scene/include/scene/renderable/mesh.hpp @@ -13,7 +13,7 @@ #include #include -#include "gldraw/interface/opengl_object.hpp" +#include "scene/interface/opengl_object.hpp" #include "../shader_program.hpp" namespace quickviz { diff --git a/src/scene/include/scene/renderable/occupancy_grid.hpp b/src/scene/include/scene/renderable/occupancy_grid.hpp new file mode 100644 index 0000000..927bcfc --- /dev/null +++ b/src/scene/include/scene/renderable/occupancy_grid.hpp @@ -0,0 +1,109 @@ +/** + * @file occupancy_grid.hpp + * @brief 2D occupancy-grid renderable + * + * Renders a 2D probabilistic occupancy grid as a textured quad lying in + * the XY plane (Z = 0 in the local frame). Designed to consume ROS-style + * data without lossy conversion: cells are int8_t in the range + * `[-1, 100]`, where `-1` is unknown and `0..100` is the probability + * (percent) of occupancy. + * + * The renderable does not interpret or transform the grid origin + * pose-wise — pass world-space `origin` and `resolution`, or use the + * `SetTransform` machinery on `OpenGlObject` for richer placement. + * + * Copyright (c) 2026 Ruixiang Du (rdu) + */ + +#ifndef QUICKVIZ_OCCUPANCY_GRID_HPP +#define QUICKVIZ_OCCUPANCY_GRID_HPP + +#include +#include + +#include + +#include "scene/interface/opengl_object.hpp" +#include "../shader_program.hpp" + +namespace quickviz { + +class OccupancyGrid : public OpenGlObject { + public: + OccupancyGrid(); + ~OccupancyGrid(); + + // === Data === + + /** + * @brief Set the grid contents. + * + * @param width Number of cells along the X axis. + * @param height Number of cells along the Y axis. + * @param resolution World-space size of a single cell, in meters. + * @param origin World-space position of cell `(0, 0)`. The grid + * spans from `origin` to + * `origin + (width, height) * resolution` in XY. + * @param values Row-major occupancy values. Size must be + * `width * height`. ROS convention: + * -1 → unknown + * 0..100 → probability of occupancy (percent) + * + * Safe to call repeatedly; the texture is updated in place when the + * dimensions don't change. Grid resizes do reallocate the texture. + * Must be called on the render thread. + */ + void SetGrid(uint32_t width, uint32_t height, float resolution, + const glm::vec3& origin, const std::vector& values); + + // === Appearance === + + /// Color used for cells with occupancy = 0 (free). Default: light gray. + void SetFreeColor(const glm::vec4& color) { free_color_ = color; } + /// Color used for cells with occupancy = 100 (occupied). Default: black. + void SetOccupiedColor(const glm::vec4& color) { occupied_color_ = color; } + /// Color used for cells flagged unknown (-1). Default: medium gray. + void SetUnknownColor(const glm::vec4& color) { unknown_color_ = color; } + + // === Inspection === + + uint32_t GetWidth() const { return width_; } + uint32_t GetHeight() const { return height_; } + float GetResolution() const { return resolution_; } + const glm::vec3& GetOrigin() const { return origin_; } + + // === OpenGlObject interface === + + void AllocateGpuResources() override; + void ReleaseGpuResources() noexcept override; + void OnDraw(const glm::mat4& projection, const glm::mat4& view, + const glm::mat4& coord_transform = glm::mat4(1.0f)) override; + bool IsGpuResourcesAllocated() const noexcept override { + return vao_ != 0; + } + + private: + void EnsureTextureSize(uint32_t width, uint32_t height); + void UploadTexel(const std::vector& values); + + // Grid metadata + uint32_t width_ = 0; + uint32_t height_ = 0; + float resolution_ = 1.0f; + glm::vec3 origin_ = glm::vec3(0.0f); + + // Color configuration (sane defaults). + glm::vec4 free_color_ = glm::vec4(0.85f, 0.85f, 0.85f, 1.0f); + glm::vec4 occupied_color_ = glm::vec4(0.05f, 0.05f, 0.05f, 1.0f); + glm::vec4 unknown_color_ = glm::vec4(0.45f, 0.45f, 0.45f, 1.0f); + + // GL resources + uint32_t vao_ = 0; + uint32_t vbo_ = 0; + uint32_t texture_id_ = 0; + ShaderProgram shader_; +}; + +} // namespace quickviz + +#endif // QUICKVIZ_OCCUPANCY_GRID_HPP diff --git a/src/gldraw/include/gldraw/renderable/path.hpp b/src/scene/include/scene/renderable/path.hpp similarity index 73% rename from src/gldraw/include/gldraw/renderable/path.hpp rename to src/scene/include/scene/renderable/path.hpp index efad7f0..1581a95 100644 --- a/src/gldraw/include/gldraw/renderable/path.hpp +++ b/src/scene/include/scene/renderable/path.hpp @@ -13,8 +13,9 @@ #include #include #include +#include -#include "gldraw/interface/opengl_object.hpp" +#include "scene/interface/opengl_object.hpp" #include "../shader_program.hpp" namespace quickviz { @@ -59,7 +60,11 @@ class Path : public OpenGlObject { kEndpoints, // Arrows at start and end only kRegular, // Arrows at regular intervals kCurvature, // Arrows at high curvature points - kAll // Arrow at every path point + kAll, // Arrow at every path point (path tangent) + kPoseArrows // Arrow at every control point oriented by + // orientations_[i]; falls back to tangent when + // orientations_ is empty or shorter than + // control_points_. }; Path(); @@ -69,10 +74,36 @@ class Path : public OpenGlObject { // Path definition void SetPoints(const std::vector& points); void AddPoint(const glm::vec3& point); + /// Streaming overload: append a point together with its scalar value + /// (used by kVelocity / kTime / kCost color modes). Keeps scalar_values_ + /// aligned with control_points_ for live-trajectory use cases. + void AddPoint(const glm::vec3& point, float scalar); + /// Streaming overload: append a pose. Keeps orientations_ aligned + /// with control_points_ for live oriented-trajectory feeds (ROS2 + /// `geometry_msgs::PoseStamped` / `nav_msgs::Path`). + void AddPoint(const glm::vec3& point, const glm::quat& orientation); + /// Append a full pose with a scalar sample. + void AddPoint(const glm::vec3& point, const glm::quat& orientation, + float scalar); void InsertPoint(size_t index, const glm::vec3& point); void RemovePoint(size_t index); void ClearPath(); + // === Per-point orientation (optional) === + + /// Set per-control-point orientations. `orientations.size()` should + /// match the current `control_points_` size; shorter or empty input + /// is allowed (missing orientations fall back to identity when + /// drawing pose arrows). + void SetOrientations(const std::vector& orientations); + /// True if any orientations are stored. + bool HasOrientations() const { return !orientations_.empty(); } + /// Remove all stored orientations. Position data is unchanged. + void ClearOrientations(); + const std::vector& GetOrientations() const { + return orientations_; + } + const std::vector& GetPoints() const { return control_points_; } size_t GetPointCount() const { return control_points_.size(); } @@ -96,6 +127,13 @@ class Path : public OpenGlObject { ColorMode GetColorMode() const { return color_mode_; } glm::vec3 GetColor() const { return base_color_; } + /// When enabled, the color range used for kVelocity/kTime/kCost is + /// computed from `scalar_values_` (min/max) before each color update. + /// Off by default; enable for streaming trajectories so the color + /// mapping adapts as new samples arrive. + void EnableAutoColorRange(bool enable); + bool IsAutoColorRangeEnabled() const { return auto_color_range_; } + // Directional arrows void SetArrowMode(ArrowMode mode); void SetArrowSize(float size); @@ -145,6 +183,11 @@ class Path : public OpenGlObject { // Control points std::vector control_points_; + + // Optional per-control-point orientations. Empty means "no + // orientation data"; size mismatched with control_points_ is + // tolerated (missing entries treated as identity at draw time). + std::vector orientations_; // Path properties PathType path_type_; @@ -165,6 +208,7 @@ class Path : public OpenGlObject { std::vector custom_colors_; std::vector scalar_values_; glm::vec2 color_range_; + bool auto_color_range_ = false; // Arrow properties ArrowMode arrow_mode_; diff --git a/src/gldraw/include/gldraw/renderable/plane.hpp b/src/scene/include/scene/renderable/plane.hpp similarity index 98% rename from src/gldraw/include/gldraw/renderable/plane.hpp rename to src/scene/include/scene/renderable/plane.hpp index b5ee57a..37dd5b5 100644 --- a/src/gldraw/include/gldraw/renderable/plane.hpp +++ b/src/scene/include/scene/renderable/plane.hpp @@ -13,7 +13,7 @@ #include #include -#include "gldraw/interface/opengl_object.hpp" +#include "scene/interface/opengl_object.hpp" #include "../shader_program.hpp" namespace quickviz { diff --git a/src/gldraw/include/gldraw/renderable/point_cloud.hpp b/src/scene/include/scene/renderable/point_cloud.hpp similarity index 98% rename from src/gldraw/include/gldraw/renderable/point_cloud.hpp rename to src/scene/include/scene/renderable/point_cloud.hpp index 46d6ed1..32e62bd 100644 --- a/src/gldraw/include/gldraw/renderable/point_cloud.hpp +++ b/src/scene/include/scene/renderable/point_cloud.hpp @@ -16,9 +16,9 @@ #include -#include "gldraw/interface/opengl_object.hpp" +#include "scene/interface/opengl_object.hpp" #include "../shader_program.hpp" -#include "gldraw/renderable/types.hpp" +#include "scene/renderable/types.hpp" #include "details/point_layer_manager.hpp" namespace quickviz { diff --git a/src/gldraw/include/gldraw/renderable/pose.hpp b/src/scene/include/scene/renderable/pose.hpp similarity index 99% rename from src/gldraw/include/gldraw/renderable/pose.hpp rename to src/scene/include/scene/renderable/pose.hpp index 0fa2d24..947ffb1 100644 --- a/src/gldraw/include/gldraw/renderable/pose.hpp +++ b/src/scene/include/scene/renderable/pose.hpp @@ -15,7 +15,7 @@ #include #include -#include "gldraw/interface/opengl_object.hpp" +#include "scene/interface/opengl_object.hpp" #include "../shader_program.hpp" namespace quickviz { diff --git a/src/gldraw/include/gldraw/renderable/sphere.hpp b/src/scene/include/scene/renderable/sphere.hpp similarity index 99% rename from src/gldraw/include/gldraw/renderable/sphere.hpp rename to src/scene/include/scene/renderable/sphere.hpp index 6a45c55..512e04e 100644 --- a/src/gldraw/include/gldraw/renderable/sphere.hpp +++ b/src/scene/include/scene/renderable/sphere.hpp @@ -13,7 +13,7 @@ #include #include -#include "gldraw/renderable/geometric_primitive.hpp" +#include "scene/renderable/geometric_primitive.hpp" #include "../shader_program.hpp" namespace quickviz { diff --git a/src/gldraw/include/gldraw/renderable/texture.hpp b/src/scene/include/scene/renderable/texture.hpp similarity index 98% rename from src/gldraw/include/gldraw/renderable/texture.hpp rename to src/scene/include/scene/renderable/texture.hpp index b42ebd8..5264219 100644 --- a/src/gldraw/include/gldraw/renderable/texture.hpp +++ b/src/scene/include/scene/renderable/texture.hpp @@ -16,7 +16,7 @@ #include -#include "gldraw/interface/opengl_object.hpp" +#include "scene/interface/opengl_object.hpp" #include "../shader_program.hpp" namespace quickviz { diff --git a/src/scene/include/scene/renderable/tf_frame_tree.hpp b/src/scene/include/scene/renderable/tf_frame_tree.hpp new file mode 100644 index 0000000..50769ce --- /dev/null +++ b/src/scene/include/scene/renderable/tf_frame_tree.hpp @@ -0,0 +1,139 @@ +/** + * @file tf_frame_tree.hpp + * @brief Renderable tree of named coordinate frames + * + * Visualizes a hierarchy of coordinate frames analogous to ROS tf2: each + * frame has a name and a transform expressed in its parent's frame. World + * transforms are computed by walking parent chains. + * + * Each frame renders as a small RGB axis triplet (X=red, Y=green, + * Z=blue). Parent → child connection lines are drawn in gray when + * enabled, giving a quick visual of tree topology. + * + * Threading: `SetFrame`, `RemoveFrame`, and `Clear` mutate internal + * state and rebuild the GPU vertex buffer; they must be called on the + * render thread. `OnDraw` is called by the scene manager. + * + * Copyright (c) 2026 Ruixiang Du (rdu) + */ + +#ifndef QUICKVIZ_TF_FRAME_TREE_HPP +#define QUICKVIZ_TF_FRAME_TREE_HPP + +#include +#include +#include +#include + +#include + +#include "scene/interface/opengl_object.hpp" +#include "../shader_program.hpp" + +namespace quickviz { + +class TfFrameTree : public OpenGlObject { + public: + explicit TfFrameTree(float axis_length = 0.3f); + ~TfFrameTree(); + + // === Frame management === + + /** + * @brief Add or update a frame. + * + * @param name Unique frame identifier. + * @param parent Parent frame name, or empty string for a + * root frame (rooted in world). + * @param transform_in_parent 4x4 transform of `name` in `parent`'s + * coordinates (or world if no parent). + * + * If `name` already exists, its parent and transform are updated; + * children are re-rooted automatically because they reference by + * parent name. + */ + void SetFrame(const std::string& name, const std::string& parent, + const glm::mat4& transform_in_parent); + + /** + * @brief Remove a frame and all its descendants. + * @return Number of frames removed. + */ + std::size_t RemoveFrame(const std::string& name); + + /// Remove all frames. + void Clear(); + + /// Number of frames currently in the tree. + std::size_t GetFrameCount() const { return frames_.size(); } + + /// Returns true if the frame exists in the tree. + bool HasFrame(const std::string& name) const; + + /** + * @brief World-space transform for a named frame. + * + * Walks parents until a root is reached. Returns identity if the + * frame doesn't exist or has a broken parent chain. + */ + glm::mat4 GetWorldTransform(const std::string& name) const; + + // === Appearance === + + /// Length (world units) of each axis line. Default: 0.3. + void SetAxisLength(float length); + + /// Whether to draw lines connecting parent origins to child origins. + void SetShowConnections(bool show) { show_connections_ = show; dirty_ = true; } + bool GetShowConnections() const { return show_connections_; } + + /// Color of parent→child connection lines. Default: medium gray. + void SetConnectionColor(const glm::vec3& color) { + connection_color_ = color; + dirty_ = true; + } + + // === OpenGlObject interface === + + void AllocateGpuResources() override; + void ReleaseGpuResources() noexcept override; + void OnDraw(const glm::mat4& projection, const glm::mat4& view, + const glm::mat4& coord_transform = glm::mat4(1.0f)) override; + bool IsGpuResourcesAllocated() const noexcept override { + return vao_ != 0; + } + + private: + struct Frame { + std::string parent; // empty == world root + glm::mat4 local{1.0f}; // transform in parent's frame + }; + + struct Vertex { + glm::vec3 position; + glm::vec3 color; + }; + + // Recompute the vertex buffer from the current tree state. Called + // lazily before drawing if dirty_ is set. + void RebuildVertices(); + + std::unordered_map frames_; + float axis_length_ = 0.3f; + bool show_connections_ = true; + glm::vec3 connection_color_ = glm::vec3(0.5f, 0.5f, 0.5f); + + // GL resources + uint32_t vao_ = 0; + uint32_t vbo_ = 0; + ShaderProgram shader_; + + // CPU-side vertex cache (rebuilt when tree changes). + std::vector vertices_; + bool dirty_ = true; + std::size_t buffer_capacity_ = 0; +}; + +} // namespace quickviz + +#endif // QUICKVIZ_TF_FRAME_TREE_HPP diff --git a/src/gldraw/include/gldraw/renderable/types.hpp b/src/scene/include/scene/renderable/types.hpp similarity index 100% rename from src/gldraw/include/gldraw/renderable/types.hpp rename to src/scene/include/scene/renderable/types.hpp diff --git a/src/gldraw/include/gldraw/gl_viewer.hpp b/src/scene/include/scene/scene_app.hpp similarity index 60% rename from src/gldraw/include/gldraw/gl_viewer.hpp rename to src/scene/include/scene/scene_app.hpp index 865f82b..7927202 100644 --- a/src/gldraw/include/gldraw/gl_viewer.hpp +++ b/src/scene/include/scene/scene_app.hpp @@ -1,17 +1,33 @@ /* - * @file gl_viewer.hpp + * @file scene_app.hpp * @author Ruixiang Du (ruixiang.du@gmail.com) * @date 2025-08-23 - * @brief Reusable OpenGL view class for testing renderable objects + * @brief Five-line quickstart for a 3D viewer * - * This class handles the common boilerplate code for setting up OpenGL rendering tests, - * allowing test cases to focus on creating and configuring renderable objects. + * `SceneApp` is the smallest entry point QuickViz offers for building a + * 3D viewer. It wraps a `Viewer` and a `GlScenePanel`, sets up sensible + * defaults (grid + coordinate frame), and runs the event loop. The + * scene is populated through a callback the caller provides. + * + * Typical use: + * + * quickviz::SceneApp app({.window_title = "My Tool"}); + * app.SetSceneSetup([](SceneManager* scene) { + * scene->AddOpenGLObject("cloud", std::make_unique(...)); + * }); + * app.Run(); + * + * For more control (multiple panels, side widgets, plot/canvas/image + * panels alongside the 3D scene) drop down to `Viewer` directly. SceneApp + * is the path of least resistance, not the only door. + * + * Internally also used by the renderable unit tests in scene/test/. * * Copyright (c) 2025 Ruixiang Du (rdu) */ -#ifndef QUICKVIZ_GLVIEW_HPP -#define QUICKVIZ_GLVIEW_HPP +#ifndef QUICKVIZ_SCENE_APP_HPP +#define QUICKVIZ_SCENE_APP_HPP #include #include @@ -20,29 +36,32 @@ #include -#include "imview/viewer.hpp" -#include "imview/box.hpp" -#include "gldraw/gl_scene_panel.hpp" -#include "gldraw/renderable/grid.hpp" -#include "gldraw/renderable/coordinate_frame.hpp" +#include "viewer/viewer.hpp" +#include "viewer/box.hpp" +#include "scene/gl_scene_panel.hpp" +#include "scene/renderable/grid.hpp" +#include "scene/renderable/coordinate_frame.hpp" namespace quickviz { /** - * @brief Reusable OpenGL viewer for testing renderable objects - * - * This class encapsulates the common setup and management code needed for - * OpenGL rendering tests. It provides: - * - Automatic viewer and scene manager setup - * - Optional grid and coordinate frame - * - Scene population callback system - * - Standard camera controls and help text - * - Exception handling and error reporting + * @brief Quickstart facade for building a 3D viewer in a few lines + * + * Provides: + * - `Viewer` + `GlScenePanel` set up with sane defaults + * - Optional reference grid and coordinate frame + * - A `SceneSetupCallback` for populating the scene + * - Standard camera controls (inherited from `GlScenePanel`) + * - Optional help-text overlay + * + * For applications that need multiple panels (plots, image views, custom + * UI) compose `Viewer` and the panel classes directly — `SceneApp` is a + * convenience layer, not a base class to extend. */ -class GlViewer { +class SceneApp { public: /** - * @brief Configuration structure for GlView + * @brief Configuration for the SceneApp */ struct Config { std::string window_title; @@ -78,20 +97,20 @@ class GlViewer { * * @param config Configuration for the view */ - explicit GlViewer(const Config& config = Config{}); + explicit SceneApp(const Config& config = Config{}); /** * @brief Destructor */ - ~GlViewer() = default; + ~SceneApp() = default; // Disable copy construction and assignment - GlViewer(const GlViewer&) = delete; - GlViewer& operator=(const GlViewer&) = delete; + SceneApp(const SceneApp&) = delete; + SceneApp& operator=(const SceneApp&) = delete; // Enable move construction and assignment - GlViewer(GlViewer&&) = default; - GlViewer& operator=(GlViewer&&) = default; + SceneApp(SceneApp&&) = default; + SceneApp& operator=(SceneApp&&) = default; /** * @brief Set the scene setup callback @@ -158,4 +177,4 @@ class GlViewer { } // namespace quickviz -#endif // QUICKVIZ_GLVIEW_HPP +#endif // QUICKVIZ_SCENE_APP_HPP diff --git a/src/gldraw/include/gldraw/scene_input_handler.hpp b/src/scene/include/scene/scene_input_handler.hpp similarity index 90% rename from src/gldraw/include/gldraw/scene_input_handler.hpp rename to src/scene/include/scene/scene_input_handler.hpp index e4b020e..60f3e71 100644 --- a/src/gldraw/include/gldraw/scene_input_handler.hpp +++ b/src/scene/include/scene/scene_input_handler.hpp @@ -1,23 +1,23 @@ /* * @file scene_input_handler.hpp * @date 9/1/25 - * @brief Bridge between imview input system and gldraw 3D interactions + * @brief Bridge between viewer input system and scene 3D interactions * * @copyright Copyright (c) 2025 Ruixiang Du (rdu) */ -#ifndef GLDRAW_SCENE_INPUT_HANDLER_HPP -#define GLDRAW_SCENE_INPUT_HANDLER_HPP +#ifndef SCENE_SCENE_INPUT_HANDLER_HPP +#define SCENE_SCENE_INPUT_HANDLER_HPP #include #include -#include "imview/input/input_dispatcher.hpp" +#include "viewer/input/input_dispatcher.hpp" #include "core/event/input_event.hpp" -#include "gldraw/camera.hpp" -#include "gldraw/camera_controller.hpp" -#include "gldraw/selection_manager.hpp" -#include "gldraw/camera_control_config.hpp" +#include "scene/camera.hpp" +#include "scene/camera_controller.hpp" +#include "scene/selection_manager.hpp" +#include "scene/camera_control_config.hpp" namespace quickviz { @@ -27,7 +27,7 @@ class SceneManager; /** * @brief Input handler bridge for 3D scene interactions * - * Bridges imview's InputEventHandler system with gldraw's 3D-specific + * Bridges viewer's InputEventHandler system with scene's 3D-specific * functionality like camera control and object selection. */ class SceneInputHandler : public InputEventHandler { @@ -149,4 +149,4 @@ class SceneInputHandlerFactory { } // namespace quickviz -#endif // GLDRAW_SCENE_INPUT_HANDLER_HPP \ No newline at end of file +#endif // SCENE_SCENE_INPUT_HANDLER_HPP \ No newline at end of file diff --git a/src/gldraw/include/gldraw/scene_manager.hpp b/src/scene/include/scene/scene_manager.hpp similarity index 96% rename from src/gldraw/include/gldraw/scene_manager.hpp rename to src/scene/include/scene/scene_manager.hpp index 604d73f..5e4f37f 100644 --- a/src/gldraw/include/gldraw/scene_manager.hpp +++ b/src/scene/include/scene/scene_manager.hpp @@ -18,13 +18,13 @@ #include #include -#include "gldraw/interface/opengl_object.hpp" +#include "scene/interface/opengl_object.hpp" -#include "gldraw/frame_buffer.hpp" -#include "gldraw/camera.hpp" -#include "gldraw/camera_controller.hpp" -#include "gldraw/coordinate_transformer.hpp" -#include "gldraw/selection_manager.hpp" +#include "scene/frame_buffer.hpp" +#include "scene/camera.hpp" +#include "scene/camera_controller.hpp" +#include "scene/coordinate_transformer.hpp" +#include "scene/selection_manager.hpp" // Forward declarations namespace quickviz { diff --git a/src/gldraw/include/gldraw/selection_manager.hpp b/src/scene/include/scene/selection_manager.hpp similarity index 99% rename from src/gldraw/include/gldraw/selection_manager.hpp rename to src/scene/include/scene/selection_manager.hpp index fc1a446..73fb14e 100644 --- a/src/gldraw/include/gldraw/selection_manager.hpp +++ b/src/scene/include/scene/selection_manager.hpp @@ -19,7 +19,7 @@ #include #include -#include "gldraw/interface/opengl_object.hpp" +#include "scene/interface/opengl_object.hpp" namespace quickviz { diff --git a/src/gldraw/include/gldraw/shader.hpp b/src/scene/include/scene/shader.hpp similarity index 100% rename from src/gldraw/include/gldraw/shader.hpp rename to src/scene/include/scene/shader.hpp diff --git a/src/gldraw/include/gldraw/shader_program.hpp b/src/scene/include/scene/shader_program.hpp similarity index 100% rename from src/gldraw/include/gldraw/shader_program.hpp rename to src/scene/include/scene/shader_program.hpp diff --git a/src/gldraw/include/gldraw/tools/interaction_tool.hpp b/src/scene/include/scene/tools/interaction_tool.hpp similarity index 99% rename from src/gldraw/include/gldraw/tools/interaction_tool.hpp rename to src/scene/include/scene/tools/interaction_tool.hpp index 9860b11..d3e00e4 100644 --- a/src/gldraw/include/gldraw/tools/interaction_tool.hpp +++ b/src/scene/include/scene/tools/interaction_tool.hpp @@ -14,7 +14,7 @@ #include #include -#include "imview/input/input_dispatcher.hpp" +#include "viewer/input/input_dispatcher.hpp" #include "core/event/input_event.hpp" namespace quickviz { diff --git a/src/gldraw/include/gldraw/tools/point_selection_tool.hpp b/src/scene/include/scene/tools/point_selection_tool.hpp similarity index 99% rename from src/gldraw/include/gldraw/tools/point_selection_tool.hpp rename to src/scene/include/scene/tools/point_selection_tool.hpp index 43a1d03..8a692cd 100644 --- a/src/gldraw/include/gldraw/tools/point_selection_tool.hpp +++ b/src/scene/include/scene/tools/point_selection_tool.hpp @@ -14,8 +14,8 @@ #include #include -#include "gldraw/tools/interaction_tool.hpp" -#include "gldraw/selection_manager.hpp" +#include "scene/tools/interaction_tool.hpp" +#include "scene/selection_manager.hpp" namespace quickviz { diff --git a/src/gldraw/src/camera.cpp b/src/scene/src/camera.cpp similarity index 99% rename from src/gldraw/src/camera.cpp rename to src/scene/src/camera.cpp index 10b5049..a10d71f 100644 --- a/src/gldraw/src/camera.cpp +++ b/src/scene/src/camera.cpp @@ -6,7 +6,7 @@ * @copyright Copyright (c) 2024 Ruixiang Du (rdu) */ -#include "gldraw/camera.hpp" +#include "scene/camera.hpp" #include diff --git a/src/gldraw/src/camera_controller.cpp b/src/scene/src/camera_controller.cpp similarity index 99% rename from src/gldraw/src/camera_controller.cpp rename to src/scene/src/camera_controller.cpp index 837ef53..375485c 100644 --- a/src/gldraw/src/camera_controller.cpp +++ b/src/scene/src/camera_controller.cpp @@ -6,7 +6,7 @@ * @copyright Copyright (c) 2024 Ruixiang Du (rdu) */ -#include "gldraw/camera_controller.hpp" +#include "scene/camera_controller.hpp" namespace quickviz { diff --git a/src/gldraw/src/feedback/object_feedback_handler.cpp b/src/scene/src/feedback/object_feedback_handler.cpp similarity index 98% rename from src/gldraw/src/feedback/object_feedback_handler.cpp rename to src/scene/src/feedback/object_feedback_handler.cpp index 1c59f78..87dcd20 100644 --- a/src/gldraw/src/feedback/object_feedback_handler.cpp +++ b/src/scene/src/feedback/object_feedback_handler.cpp @@ -10,14 +10,14 @@ * @copyright Copyright (c) 2025 Ruixiang Du (rdu) */ -#include "gldraw/feedback/object_feedback_handler.hpp" +#include "scene/feedback/object_feedback_handler.hpp" #include #include #include -#include "gldraw/scene_manager.hpp" -#include "gldraw/renderable/sphere.hpp" +#include "scene/scene_manager.hpp" +#include "scene/renderable/sphere.hpp" namespace quickviz { diff --git a/src/gldraw/src/feedback/point_cloud_feedback_handler.cpp b/src/scene/src/feedback/point_cloud_feedback_handler.cpp similarity index 98% rename from src/gldraw/src/feedback/point_cloud_feedback_handler.cpp rename to src/scene/src/feedback/point_cloud_feedback_handler.cpp index d38ef30..e006305 100644 --- a/src/gldraw/src/feedback/point_cloud_feedback_handler.cpp +++ b/src/scene/src/feedback/point_cloud_feedback_handler.cpp @@ -10,13 +10,13 @@ * @copyright Copyright (c) 2025 Ruixiang Du (rdu) */ -#include "gldraw/feedback/point_cloud_feedback_handler.hpp" +#include "scene/feedback/point_cloud_feedback_handler.hpp" #include #include #include -#include "gldraw/renderable/point_cloud.hpp" +#include "scene/renderable/point_cloud.hpp" namespace quickviz { diff --git a/src/gldraw/src/feedback/visual_feedback_system.cpp b/src/scene/src/feedback/visual_feedback_system.cpp similarity index 97% rename from src/gldraw/src/feedback/visual_feedback_system.cpp rename to src/scene/src/feedback/visual_feedback_system.cpp index 17fcf03..1520952 100644 --- a/src/gldraw/src/feedback/visual_feedback_system.cpp +++ b/src/scene/src/feedback/visual_feedback_system.cpp @@ -6,14 +6,14 @@ * @copyright Copyright (c) 2025 Ruixiang Du (rdu) */ -#include "gldraw/feedback/visual_feedback_system.hpp" -#include "gldraw/feedback/point_cloud_feedback_handler.hpp" -#include "gldraw/feedback/object_feedback_handler.hpp" - -#include "gldraw/scene_manager.hpp" -#include "gldraw/selection_manager.hpp" -#include "gldraw/renderable/point_cloud.hpp" -#include "gldraw/interface/opengl_object.hpp" +#include "scene/feedback/visual_feedback_system.hpp" +#include "scene/feedback/point_cloud_feedback_handler.hpp" +#include "scene/feedback/object_feedback_handler.hpp" + +#include "scene/scene_manager.hpp" +#include "scene/selection_manager.hpp" +#include "scene/renderable/point_cloud.hpp" +#include "scene/interface/opengl_object.hpp" #include #include diff --git a/src/gldraw/src/font_renderer.cpp b/src/scene/src/font_renderer.cpp similarity index 99% rename from src/gldraw/src/font_renderer.cpp rename to src/scene/src/font_renderer.cpp index f566959..c73ad57 100644 --- a/src/gldraw/src/font_renderer.cpp +++ b/src/scene/src/font_renderer.cpp @@ -7,7 +7,7 @@ * Copyright (c) 2025 Ruixiang Du (rdu) */ -#include "gldraw/font_renderer.hpp" +#include "scene/font_renderer.hpp" #include #include diff --git a/src/gldraw/src/frame_buffer.cpp b/src/scene/src/frame_buffer.cpp similarity index 99% rename from src/gldraw/src/frame_buffer.cpp rename to src/scene/src/frame_buffer.cpp index f8a9da6..9e9c41a 100644 --- a/src/gldraw/src/frame_buffer.cpp +++ b/src/scene/src/frame_buffer.cpp @@ -6,7 +6,7 @@ * @copyright Copyright (c) 2024 Ruixiang Du (rdu) */ -#include "gldraw/frame_buffer.hpp" +#include "scene/frame_buffer.hpp" #include #include diff --git a/src/gldraw/src/gl_scene_panel.cpp b/src/scene/src/gl_scene_panel.cpp similarity index 96% rename from src/gldraw/src/gl_scene_panel.cpp rename to src/scene/src/gl_scene_panel.cpp index 7e533c8..49b5ea0 100644 --- a/src/gldraw/src/gl_scene_panel.cpp +++ b/src/scene/src/gl_scene_panel.cpp @@ -7,18 +7,18 @@ * Copyright (c) 2025 Ruixiang Du (rdu) */ -#include "gldraw/gl_scene_panel.hpp" +#include "scene/gl_scene_panel.hpp" #include #include #include "imgui.h" -#include "imview/fonts.hpp" -#include "imview/input/input_policy.hpp" +#include "viewer/fonts.hpp" +#include "viewer/input/input_policy.hpp" -#include "gldraw/renderable/point_cloud.hpp" -#include "gldraw/selection_manager.hpp" -#include "gldraw/feedback/visual_feedback_system.hpp" +#include "scene/renderable/point_cloud.hpp" +#include "scene/selection_manager.hpp" +#include "scene/feedback/visual_feedback_system.hpp" namespace quickviz { @@ -221,7 +221,7 @@ void GlScenePanel::RenderInfoOverlay(const ImVec2& content_size, draw_list->AddText(text_pos, text_color, fps_text); } -// New imview-based input handling methods +// New viewer-based input handling methods bool GlScenePanel::OnInputEvent(const InputEvent& event) { if (scene_input_handler_) { // Update viewport size for the handler diff --git a/src/gldraw/src/renderable/arrow.cpp b/src/scene/src/renderable/arrow.cpp similarity index 99% rename from src/gldraw/src/renderable/arrow.cpp rename to src/scene/src/renderable/arrow.cpp index f3caa5a..5876c44 100644 --- a/src/gldraw/src/renderable/arrow.cpp +++ b/src/scene/src/renderable/arrow.cpp @@ -7,7 +7,7 @@ * Copyright (c) 2025 Ruixiang Du (rdu) */ -#include "gldraw/renderable/arrow.hpp" +#include "scene/renderable/arrow.hpp" #include #include @@ -17,7 +17,7 @@ #include #include -#include "gldraw/shader.hpp" +#include "scene/shader.hpp" namespace quickviz { diff --git a/src/gldraw/src/renderable/billboard.cpp b/src/scene/src/renderable/billboard.cpp similarity index 99% rename from src/gldraw/src/renderable/billboard.cpp rename to src/scene/src/renderable/billboard.cpp index 98c3e1f..747e5c2 100644 --- a/src/gldraw/src/renderable/billboard.cpp +++ b/src/scene/src/renderable/billboard.cpp @@ -7,7 +7,7 @@ * Copyright (c) 2025 Ruixiang Du (rdu) */ -#include "gldraw/renderable/billboard.hpp" +#include "scene/renderable/billboard.hpp" #include #include @@ -18,7 +18,7 @@ #include #include -#include "gldraw/shader.hpp" +#include "scene/shader.hpp" namespace quickviz { diff --git a/src/gldraw/src/renderable/bounding_box.cpp b/src/scene/src/renderable/bounding_box.cpp similarity index 99% rename from src/gldraw/src/renderable/bounding_box.cpp rename to src/scene/src/renderable/bounding_box.cpp index e5cfadf..63a3348 100644 --- a/src/gldraw/src/renderable/bounding_box.cpp +++ b/src/scene/src/renderable/bounding_box.cpp @@ -7,7 +7,7 @@ * Copyright (c) 2025 Ruixiang Du (rdu) */ -#include "gldraw/renderable/bounding_box.hpp" +#include "scene/renderable/bounding_box.hpp" #include @@ -15,7 +15,7 @@ #include #include -#include "gldraw/shader.hpp" +#include "scene/shader.hpp" namespace quickviz { diff --git a/src/gldraw/src/renderable/canvas.cpp b/src/scene/src/renderable/canvas.cpp similarity index 99% rename from src/gldraw/src/renderable/canvas.cpp rename to src/scene/src/renderable/canvas.cpp index 61b50af..0a822b0 100644 --- a/src/gldraw/src/renderable/canvas.cpp +++ b/src/scene/src/renderable/canvas.cpp @@ -7,7 +7,7 @@ * Copyright (c) 2025 Ruixiang Du (rdu) */ -#include "gldraw/renderable/canvas.hpp" +#include "scene/renderable/canvas.hpp" #include #include @@ -22,8 +22,8 @@ #include #include "renderable/details/canvas_data.hpp" -#include "gldraw/renderable/details/canvas_batching.hpp" -#include "gldraw/renderable/details/canvas_performance.hpp" +#include "scene/renderable/details/canvas_batching.hpp" +#include "scene/renderable/details/canvas_performance.hpp" #include "renderable/details/render_strategy.hpp" #include "renderable/details/batched_render_strategy.hpp" #include "renderable/details/individual_render_strategy.hpp" diff --git a/src/gldraw/src/renderable/coordinate_frame.cpp b/src/scene/src/renderable/coordinate_frame.cpp similarity index 99% rename from src/gldraw/src/renderable/coordinate_frame.cpp rename to src/scene/src/renderable/coordinate_frame.cpp index 52b8113..e8f6899 100644 --- a/src/gldraw/src/renderable/coordinate_frame.cpp +++ b/src/scene/src/renderable/coordinate_frame.cpp @@ -7,7 +7,7 @@ * Copyright (c) 2025 Ruixiang Du (rdu) */ -#include "gldraw/renderable/coordinate_frame.hpp" +#include "scene/renderable/coordinate_frame.hpp" #include #include diff --git a/src/gldraw/src/renderable/cylinder.cpp b/src/scene/src/renderable/cylinder.cpp similarity index 99% rename from src/gldraw/src/renderable/cylinder.cpp rename to src/scene/src/renderable/cylinder.cpp index 1b891c8..1734ba3 100644 --- a/src/gldraw/src/renderable/cylinder.cpp +++ b/src/scene/src/renderable/cylinder.cpp @@ -7,7 +7,7 @@ * Copyright (c) 2025 Ruixiang Du (rdu) */ -#include "gldraw/renderable/cylinder.hpp" +#include "scene/renderable/cylinder.hpp" #include #include @@ -16,7 +16,7 @@ #include #include -#include "gldraw/shader.hpp" +#include "scene/shader.hpp" namespace quickviz { diff --git a/src/gldraw/src/renderable/details/batched_render_strategy.cpp b/src/scene/src/renderable/details/batched_render_strategy.cpp similarity index 98% rename from src/gldraw/src/renderable/details/batched_render_strategy.cpp rename to src/scene/src/renderable/details/batched_render_strategy.cpp index 32a2543..8398c03 100644 --- a/src/gldraw/src/renderable/details/batched_render_strategy.cpp +++ b/src/scene/src/renderable/details/batched_render_strategy.cpp @@ -12,8 +12,8 @@ #include #include "glad/glad.h" -#include "gldraw/shader_program.hpp" -#include "gldraw/renderable/canvas.hpp" +#include "scene/shader_program.hpp" +#include "scene/renderable/canvas.hpp" #include "canvas_data.hpp" namespace quickviz { diff --git a/src/gldraw/src/renderable/details/batched_render_strategy.hpp b/src/scene/src/renderable/details/batched_render_strategy.hpp similarity index 98% rename from src/gldraw/src/renderable/details/batched_render_strategy.hpp rename to src/scene/src/renderable/details/batched_render_strategy.hpp index e031cdc..6c04977 100644 --- a/src/gldraw/src/renderable/details/batched_render_strategy.hpp +++ b/src/scene/src/renderable/details/batched_render_strategy.hpp @@ -13,7 +13,7 @@ #include #include "render_strategy.hpp" #include "shape_renderer.hpp" -#include "gldraw/renderable/types.hpp" +#include "scene/renderable/types.hpp" namespace quickviz { diff --git a/src/gldraw/src/renderable/details/canvas_data.hpp b/src/scene/src/renderable/details/canvas_data.hpp similarity index 99% rename from src/gldraw/src/renderable/details/canvas_data.hpp rename to src/scene/src/renderable/details/canvas_data.hpp index 157e20e..1812771 100644 --- a/src/gldraw/src/renderable/details/canvas_data.hpp +++ b/src/scene/src/renderable/details/canvas_data.hpp @@ -15,7 +15,7 @@ #include #include "glad/glad.h" -#include "gldraw/renderable/types.hpp" +#include "scene/renderable/types.hpp" namespace quickviz { diff --git a/src/gldraw/src/renderable/details/canvas_data_manager.cpp b/src/scene/src/renderable/details/canvas_data_manager.cpp similarity index 100% rename from src/gldraw/src/renderable/details/canvas_data_manager.cpp rename to src/scene/src/renderable/details/canvas_data_manager.cpp diff --git a/src/gldraw/src/renderable/details/canvas_data_manager.hpp b/src/scene/src/renderable/details/canvas_data_manager.hpp similarity index 98% rename from src/gldraw/src/renderable/details/canvas_data_manager.hpp rename to src/scene/src/renderable/details/canvas_data_manager.hpp index f9759fc..78e650b 100644 --- a/src/gldraw/src/renderable/details/canvas_data_manager.hpp +++ b/src/scene/src/renderable/details/canvas_data_manager.hpp @@ -18,9 +18,9 @@ #include #include -#include "gldraw/renderable/types.hpp" +#include "scene/renderable/types.hpp" #include "canvas_data.hpp" -#include "gldraw/renderable/details/canvas_batching.hpp" +#include "scene/renderable/details/canvas_batching.hpp" namespace quickviz { namespace internal { diff --git a/src/gldraw/src/renderable/details/individual_render_strategy.cpp b/src/scene/src/renderable/details/individual_render_strategy.cpp similarity index 99% rename from src/gldraw/src/renderable/details/individual_render_strategy.cpp rename to src/scene/src/renderable/details/individual_render_strategy.cpp index 3ff7e65..f65375a 100644 --- a/src/gldraw/src/renderable/details/individual_render_strategy.cpp +++ b/src/scene/src/renderable/details/individual_render_strategy.cpp @@ -13,7 +13,7 @@ #include #include #include "glad/glad.h" -#include "gldraw/shader_program.hpp" +#include "scene/shader_program.hpp" #include "canvas_data.hpp" namespace quickviz { diff --git a/src/gldraw/src/renderable/details/individual_render_strategy.hpp b/src/scene/src/renderable/details/individual_render_strategy.hpp similarity index 100% rename from src/gldraw/src/renderable/details/individual_render_strategy.hpp rename to src/scene/src/renderable/details/individual_render_strategy.hpp diff --git a/src/gldraw/src/renderable/details/opengl_resource_pool.cpp b/src/scene/src/renderable/details/opengl_resource_pool.cpp similarity index 100% rename from src/gldraw/src/renderable/details/opengl_resource_pool.cpp rename to src/scene/src/renderable/details/opengl_resource_pool.cpp diff --git a/src/gldraw/src/renderable/details/opengl_resource_pool.hpp b/src/scene/src/renderable/details/opengl_resource_pool.hpp similarity index 100% rename from src/gldraw/src/renderable/details/opengl_resource_pool.hpp rename to src/scene/src/renderable/details/opengl_resource_pool.hpp diff --git a/src/gldraw/src/renderable/details/point_layer_manager.cpp b/src/scene/src/renderable/details/point_layer_manager.cpp similarity index 99% rename from src/gldraw/src/renderable/details/point_layer_manager.cpp rename to src/scene/src/renderable/details/point_layer_manager.cpp index be615e9..2d4ff0a 100644 --- a/src/gldraw/src/renderable/details/point_layer_manager.cpp +++ b/src/scene/src/renderable/details/point_layer_manager.cpp @@ -6,7 +6,7 @@ * @copyright Copyright (c) 2024 Ruixiang Du (rdu) */ -#include "../../../include/gldraw/renderable/details/point_layer_manager.hpp" +#include "../../../include/scene/renderable/details/point_layer_manager.hpp" #include #include #include diff --git a/src/gldraw/src/renderable/details/render_strategy.hpp b/src/scene/src/renderable/details/render_strategy.hpp similarity index 100% rename from src/gldraw/src/renderable/details/render_strategy.hpp rename to src/scene/src/renderable/details/render_strategy.hpp diff --git a/src/gldraw/src/renderable/details/shape_generators.cpp b/src/scene/src/renderable/details/shape_generators.cpp similarity index 100% rename from src/gldraw/src/renderable/details/shape_generators.cpp rename to src/scene/src/renderable/details/shape_generators.cpp diff --git a/src/gldraw/src/renderable/details/shape_generators.hpp b/src/scene/src/renderable/details/shape_generators.hpp similarity index 100% rename from src/gldraw/src/renderable/details/shape_generators.hpp rename to src/scene/src/renderable/details/shape_generators.hpp diff --git a/src/gldraw/src/renderable/details/shape_renderer.cpp b/src/scene/src/renderable/details/shape_renderer.cpp similarity index 99% rename from src/gldraw/src/renderable/details/shape_renderer.cpp rename to src/scene/src/renderable/details/shape_renderer.cpp index 5536587..8f238dc 100644 --- a/src/gldraw/src/renderable/details/shape_renderer.cpp +++ b/src/scene/src/renderable/details/shape_renderer.cpp @@ -8,7 +8,7 @@ */ #include "shape_renderer.hpp" -#include "gldraw/shader_program.hpp" +#include "scene/shader_program.hpp" #include namespace quickviz { diff --git a/src/gldraw/src/renderable/details/shape_renderer.hpp b/src/scene/src/renderable/details/shape_renderer.hpp similarity index 100% rename from src/gldraw/src/renderable/details/shape_renderer.hpp rename to src/scene/src/renderable/details/shape_renderer.hpp diff --git a/src/gldraw/src/renderable/details/shape_renderer_utils.cpp b/src/scene/src/renderable/details/shape_renderer_utils.cpp similarity index 99% rename from src/gldraw/src/renderable/details/shape_renderer_utils.cpp rename to src/scene/src/renderable/details/shape_renderer_utils.cpp index ebcdd74..536d3a0 100644 --- a/src/gldraw/src/renderable/details/shape_renderer_utils.cpp +++ b/src/scene/src/renderable/details/shape_renderer_utils.cpp @@ -11,7 +11,7 @@ #include #include #include "glad/glad.h" -#include "gldraw/shader_program.hpp" +#include "scene/shader_program.hpp" namespace quickviz { namespace internal { diff --git a/src/gldraw/src/renderable/details/shape_renderer_utils.hpp b/src/scene/src/renderable/details/shape_renderer_utils.hpp similarity index 99% rename from src/gldraw/src/renderable/details/shape_renderer_utils.hpp rename to src/scene/src/renderable/details/shape_renderer_utils.hpp index afb78c0..752d68c 100644 --- a/src/gldraw/src/renderable/details/shape_renderer_utils.hpp +++ b/src/scene/src/renderable/details/shape_renderer_utils.hpp @@ -13,7 +13,7 @@ #include #include #include -#include "gldraw/renderable/types.hpp" +#include "scene/renderable/types.hpp" #include "opengl_resource_pool.hpp" namespace quickviz { diff --git a/src/gldraw/src/renderable/frustum.cpp b/src/scene/src/renderable/frustum.cpp similarity index 99% rename from src/gldraw/src/renderable/frustum.cpp rename to src/scene/src/renderable/frustum.cpp index bdcfd6d..7935da6 100644 --- a/src/gldraw/src/renderable/frustum.cpp +++ b/src/scene/src/renderable/frustum.cpp @@ -7,14 +7,14 @@ * Copyright (c) 2025 Ruixiang Du (rdu) */ -#include "gldraw/renderable/frustum.hpp" +#include "scene/renderable/frustum.hpp" #include #include #include #include #include #include -#include "gldraw/shader.hpp" +#include "scene/shader.hpp" namespace quickviz { diff --git a/src/gldraw/src/renderable/geometric_primitive.cpp b/src/scene/src/renderable/geometric_primitive.cpp similarity index 99% rename from src/gldraw/src/renderable/geometric_primitive.cpp rename to src/scene/src/renderable/geometric_primitive.cpp index d68062a..5f585cf 100644 --- a/src/gldraw/src/renderable/geometric_primitive.cpp +++ b/src/scene/src/renderable/geometric_primitive.cpp @@ -7,13 +7,13 @@ * Copyright (c) 2025 Ruixiang Du (rdu) */ -#include "gldraw/renderable/geometric_primitive.hpp" +#include "scene/renderable/geometric_primitive.hpp" #include #include #include -#include "gldraw/shader.hpp" +#include "scene/shader.hpp" namespace quickviz { diff --git a/src/gldraw/src/renderable/grid.cpp b/src/scene/src/renderable/grid.cpp similarity index 98% rename from src/gldraw/src/renderable/grid.cpp rename to src/scene/src/renderable/grid.cpp index e754e8b..7551112 100644 --- a/src/gldraw/src/renderable/grid.cpp +++ b/src/scene/src/renderable/grid.cpp @@ -7,13 +7,13 @@ * Copyright (c) 2025 Ruixiang Du (rdu) */ -#include "gldraw/renderable/grid.hpp" +#include "scene/renderable/grid.hpp" #include #include "glad/glad.h" #include -#include "gldraw/shader.hpp" +#include "scene/shader.hpp" namespace quickviz { namespace { diff --git a/src/gldraw/src/renderable/line_strip.cpp b/src/scene/src/renderable/line_strip.cpp similarity index 99% rename from src/gldraw/src/renderable/line_strip.cpp rename to src/scene/src/renderable/line_strip.cpp index 8c575f5..459bff3 100644 --- a/src/gldraw/src/renderable/line_strip.cpp +++ b/src/scene/src/renderable/line_strip.cpp @@ -7,7 +7,7 @@ * Copyright (c) 2025 Ruixiang Du (rdu) */ -#include "gldraw/renderable/line_strip.hpp" +#include "scene/renderable/line_strip.hpp" #include #include @@ -17,7 +17,7 @@ #include #include -#include "gldraw/shader.hpp" +#include "scene/shader.hpp" namespace quickviz { diff --git a/src/gldraw/src/renderable/mesh.cpp b/src/scene/src/renderable/mesh.cpp similarity index 99% rename from src/gldraw/src/renderable/mesh.cpp rename to src/scene/src/renderable/mesh.cpp index db4e0da..373be03 100644 --- a/src/gldraw/src/renderable/mesh.cpp +++ b/src/scene/src/renderable/mesh.cpp @@ -7,9 +7,9 @@ * Copyright (c) 2025 Ruixiang Du (rdu) */ -#include "gldraw/renderable/mesh.hpp" +#include "scene/renderable/mesh.hpp" -#ifdef IMVIEW_WITH_GLAD +#ifdef VIEWER_WITH_GLAD #include #else #include @@ -20,7 +20,7 @@ #include #include -#include "gldraw/shader.hpp" +#include "scene/shader.hpp" namespace quickviz { diff --git a/src/scene/src/renderable/occupancy_grid.cpp b/src/scene/src/renderable/occupancy_grid.cpp new file mode 100644 index 0000000..128c49c --- /dev/null +++ b/src/scene/src/renderable/occupancy_grid.cpp @@ -0,0 +1,237 @@ +/** + * @file occupancy_grid.cpp + * + * Storage encoding (R8 single-channel texture): + * byte 0 → unknown sentinel + * byte 1..255 → occupancy 0..100% (linear; byte = round(1 + occ/100*254)) + * + * The shader checks for the `0` sentinel and otherwise lerps free→occupied. + * + * Copyright (c) 2026 Ruixiang Du (rdu) + */ + +#include "scene/renderable/occupancy_grid.hpp" + +#include +#include +#include + +#include "glad/glad.h" +#include + +#include "scene/shader.hpp" + +namespace quickviz { +namespace { + +constexpr uint8_t kUnknownByte = 0; + +// Two-triangle quad covering the unit square in XY (Z=0). Layout: +// x y u v +// Vertex order: top-left, bottom-left, bottom-right, top-left, bottom-right, top-right. +// Texture coords: +// u: 0..1 along X axis; v: 0..1 along Y axis. +const float kQuadVertices[] = { + 0.0f, 1.0f, 0.0f, 1.0f, + 0.0f, 0.0f, 0.0f, 0.0f, + 1.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 1.0f, + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 1.0f, 1.0f, 1.0f, +}; + +const std::string kVertexShader = R"( +#version 330 core +layout(location = 0) in vec2 aPos; +layout(location = 1) in vec2 aTex; + +uniform mat4 projection; +uniform mat4 view; +uniform mat4 model; +uniform mat4 coordSystemTransform; + +uniform vec3 uOrigin; +uniform vec3 uExtent; // xy = (width*resolution, height*resolution); z unused + +out vec2 vTex; + +void main() { + // Position the unit quad at uOrigin with extent uExtent.xy. + vec3 world = uOrigin + vec3(aPos * uExtent.xy, 0.0); + gl_Position = projection * view * coordSystemTransform * model * vec4(world, 1.0); + vTex = aTex; +} +)"; + +const std::string kFragmentShader = R"( +#version 330 core +in vec2 vTex; +out vec4 FragColor; + +uniform sampler2D uTex; +uniform vec4 uFree; +uniform vec4 uOccupied; +uniform vec4 uUnknown; + +void main() { + float r = texture(uTex, vTex).r; // 0..1 + // Sentinel: byte 0 == 0.0 means "unknown". + // Sample of byte 0 is exactly 0.0; bytes 1..255 are >= 1/255. + if (r < 0.5/255.0) { + FragColor = uUnknown; + } else { + // Reverse the encoding: occupancy = (byte - 1) / 254. + float occupancy = (r * 255.0 - 1.0) / 254.0; + FragColor = mix(uFree, uOccupied, clamp(occupancy, 0.0, 1.0)); + } +} +)"; + +uint8_t EncodeOccupancy(int8_t v) { + if (v < 0) return kUnknownByte; + // Clamp into [0, 100], then map linearly to [1, 255]. + const int clamped = std::clamp(static_cast(v), 0, 100); + // 1 + round(clamped * 254 / 100). + return static_cast(1 + (clamped * 254 + 50) / 100); +} + +} // namespace + +OccupancyGrid::OccupancyGrid() { AllocateGpuResources(); } + +OccupancyGrid::~OccupancyGrid() { ReleaseGpuResources(); } + +void OccupancyGrid::AllocateGpuResources() { + if (IsGpuResourcesAllocated()) return; + + Shader vs(kVertexShader.c_str(), Shader::Type::kVertex); + Shader fs(kFragmentShader.c_str(), Shader::Type::kFragment); + if (!vs.Compile()) { + throw std::runtime_error("OccupancyGrid: vertex shader compile failed"); + } + if (!fs.Compile()) { + throw std::runtime_error("OccupancyGrid: fragment shader compile failed"); + } + shader_.AttachShader(vs); + shader_.AttachShader(fs); + if (!shader_.LinkProgram()) { + throw std::runtime_error("OccupancyGrid: shader program link failed"); + } + + glGenVertexArrays(1, &vao_); + glGenBuffers(1, &vbo_); + glBindVertexArray(vao_); + glBindBuffer(GL_ARRAY_BUFFER, vbo_); + glBufferData(GL_ARRAY_BUFFER, sizeof(kQuadVertices), kQuadVertices, + GL_STATIC_DRAW); + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), + (void*)0); + glEnableVertexAttribArray(0); + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), + (void*)(2 * sizeof(float))); + glEnableVertexAttribArray(1); + glBindVertexArray(0); + + // Texture is created lazily on the first SetGrid; AllocateGpuResources + // only sets up shader + VAO/VBO so the renderable is safe to draw + // before the first SetGrid (it'll just render nothing). +} + +void OccupancyGrid::ReleaseGpuResources() noexcept { + if (texture_id_) { + glDeleteTextures(1, &texture_id_); + texture_id_ = 0; + } + if (vbo_) { + glDeleteBuffers(1, &vbo_); + vbo_ = 0; + } + if (vao_) { + glDeleteVertexArrays(1, &vao_); + vao_ = 0; + } +} + +void OccupancyGrid::SetGrid(uint32_t width, uint32_t height, float resolution, + const glm::vec3& origin, + const std::vector& values) { + if (width == 0 || height == 0) { + width_ = height_ = 0; + origin_ = origin; + resolution_ = resolution; + return; + } + if (resolution <= 0.0f) { + throw std::invalid_argument( + "OccupancyGrid::SetGrid: resolution must be positive"); + } + if (values.size() != static_cast(width) * height) { + throw std::invalid_argument( + "OccupancyGrid::SetGrid: values.size() must equal width * height"); + } + + EnsureTextureSize(width, height); + resolution_ = resolution; + origin_ = origin; + UploadTexel(values); +} + +void OccupancyGrid::EnsureTextureSize(uint32_t width, uint32_t height) { + if (texture_id_ == 0) { + glGenTextures(1, &texture_id_); + glBindTexture(GL_TEXTURE_2D, texture_id_); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + } + + if (width_ != width || height_ != height) { + glBindTexture(GL_TEXTURE_2D, texture_id_); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, width, height, 0, GL_RED, + GL_UNSIGNED_BYTE, nullptr); + width_ = width; + height_ = height; + } +} + +void OccupancyGrid::UploadTexel(const std::vector& values) { + std::vector packed; + packed.reserve(values.size()); + for (auto v : values) packed.push_back(EncodeOccupancy(v)); + + glBindTexture(GL_TEXTURE_2D, texture_id_); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width_, height_, GL_RED, + GL_UNSIGNED_BYTE, packed.data()); +} + +void OccupancyGrid::OnDraw(const glm::mat4& projection, const glm::mat4& view, + const glm::mat4& coord_transform) { + if (width_ == 0 || height_ == 0 || texture_id_ == 0) return; + + shader_.Use(); + shader_.SetUniform("projection", projection); + shader_.SetUniform("view", view); + shader_.SetUniform("model", GetTransform()); + shader_.SetUniform("coordSystemTransform", coord_transform); + shader_.SetUniform("uOrigin", origin_); + shader_.SetUniform( + "uExtent", + glm::vec3(static_cast(width_) * resolution_, + static_cast(height_) * resolution_, 0.0f)); + shader_.SetUniform("uFree", free_color_); + shader_.SetUniform("uOccupied", occupied_color_); + shader_.SetUniform("uUnknown", unknown_color_); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, texture_id_); + shader_.SetUniform("uTex", 0); + + glBindVertexArray(vao_); + glDrawArrays(GL_TRIANGLES, 0, 6); + glBindVertexArray(0); +} + +} // namespace quickviz diff --git a/src/gldraw/src/renderable/path.cpp b/src/scene/src/renderable/path.cpp similarity index 78% rename from src/gldraw/src/renderable/path.cpp rename to src/scene/src/renderable/path.cpp index 8578c85..9cedc6f 100644 --- a/src/gldraw/src/renderable/path.cpp +++ b/src/scene/src/renderable/path.cpp @@ -7,7 +7,7 @@ * Copyright (c) 2025 Ruixiang Du (rdu) */ -#include "gldraw/renderable/path.hpp" +#include "scene/renderable/path.hpp" #include #include @@ -17,7 +17,7 @@ #include #include -#include "gldraw/shader.hpp" +#include "scene/shader.hpp" namespace quickviz { @@ -140,6 +140,60 @@ void Path::AddPoint(const glm::vec3& point) { needs_arrow_update_ = true; } +void Path::AddPoint(const glm::vec3& point, float scalar) { + control_points_.push_back(point); + // Keep scalar_values_ aligned with control_points_. If scalar_values_ + // is shorter (e.g. user previously called AddPoint without scalar), + // pad with the new scalar so we don't introduce a tail of stale data. + if (scalar_values_.size() < control_points_.size() - 1) { + scalar_values_.resize(control_points_.size() - 1, scalar); + } + scalar_values_.push_back(scalar); + needs_geometry_update_ = true; + needs_color_update_ = true; + needs_arrow_update_ = true; +} + +void Path::AddPoint(const glm::vec3& point, const glm::quat& orientation) { + control_points_.push_back(point); + // Pad orientations_ similarly to AddPoint(point, scalar): if the user + // started with no-orientation AddPoints, back-fill with the new + // orientation so alignment is preserved. + if (orientations_.size() < control_points_.size() - 1) { + orientations_.resize(control_points_.size() - 1, orientation); + } + orientations_.push_back(orientation); + needs_geometry_update_ = true; + needs_color_update_ = true; + needs_arrow_update_ = true; +} + +void Path::AddPoint(const glm::vec3& point, const glm::quat& orientation, + float scalar) { + control_points_.push_back(point); + if (scalar_values_.size() < control_points_.size() - 1) { + scalar_values_.resize(control_points_.size() - 1, scalar); + } + scalar_values_.push_back(scalar); + if (orientations_.size() < control_points_.size() - 1) { + orientations_.resize(control_points_.size() - 1, orientation); + } + orientations_.push_back(orientation); + needs_geometry_update_ = true; + needs_color_update_ = true; + needs_arrow_update_ = true; +} + +void Path::SetOrientations(const std::vector& orientations) { + orientations_ = orientations; + needs_arrow_update_ = true; +} + +void Path::ClearOrientations() { + orientations_.clear(); + needs_arrow_update_ = true; +} + void Path::InsertPoint(size_t index, const glm::vec3& point) { if (index <= control_points_.size()) { control_points_.insert(control_points_.begin() + index, point); @@ -160,6 +214,8 @@ void Path::RemovePoint(size_t index) { void Path::ClearPath() { control_points_.clear(); + scalar_values_.clear(); + orientations_.clear(); path_vertices_.clear(); path_colors_.clear(); path_indices_.clear(); @@ -238,6 +294,17 @@ void Path::SetScalarValues(const std::vector& values) { } } +void Path::EnableAutoColorRange(bool enable) { + if (auto_color_range_ != enable) { + auto_color_range_ = enable; + if (color_mode_ == ColorMode::kVelocity || + color_mode_ == ColorMode::kTime || + color_mode_ == ColorMode::kCost) { + needs_color_update_ = true; + } + } +} + void Path::SetArrowMode(ArrowMode mode) { if (arrow_mode_ != mode) { arrow_mode_ = mode; @@ -398,6 +465,44 @@ void Path::GenerateSplineCurve() { } } +namespace { + +// Append a pyramid arrow at `position` oriented by the given basis +// vectors (forward, right, up — assumed orthonormal). `arrow_size` +// controls the overall scale. Pushes 5 vertices and 18 indices into +// the supplied buffers, plus 5 color entries. +void EmitPyramidArrow(std::vector& vertices, + std::vector& colors, + std::vector& indices, + const glm::vec3& position, const glm::vec3& forward, + const glm::vec3& right, const glm::vec3& up, + const glm::vec3& color, float arrow_size) { + const glm::vec3 fwd = forward * arrow_size; + const glm::vec3 r = right * (arrow_size * 0.4f); + const glm::vec3 u = up * (arrow_size * 0.4f); + + const uint32_t base_idx = static_cast(vertices.size()); + vertices.push_back(position + fwd); // 0: tip + vertices.push_back(position + r + u); // 1: top-right + vertices.push_back(position - r + u); // 2: top-left + vertices.push_back(position - r - u); // 3: bottom-left + vertices.push_back(position + r - u); // 4: bottom-right + for (int i = 0; i < 5; ++i) colors.push_back(color); + + const uint32_t tip = base_idx; + const uint32_t tr = base_idx + 1; + const uint32_t tl = base_idx + 2; + const uint32_t bl = base_idx + 3; + const uint32_t br = base_idx + 4; + // Side faces (tip → base edges). + indices.insert(indices.end(), + {tip, tr, br, tip, tl, tr, tip, bl, tl, tip, br, bl}); + // Base square (two triangles). + indices.insert(indices.end(), {tr, tl, bl, tr, bl, br}); +} + +} // namespace + void Path::GenerateArrows() { arrow_vertices_.clear(); arrow_colors_.clear(); @@ -407,6 +512,25 @@ void Path::GenerateArrows() { return; } + // Pose-oriented arrows iterate control_points_ (not path_vertices_) + // and use stored orientations rather than path tangents. Missing + // orientations fall back to identity, which renders as a +X-aligned + // arrow — a sensible default for ROS-style "X is forward". + if (arrow_mode_ == ArrowMode::kPoseArrows) { + for (size_t i = 0; i < control_points_.size(); ++i) { + const glm::quat q = (i < orientations_.size()) + ? orientations_[i] + : glm::quat(1.0f, 0.0f, 0.0f, 0.0f); + const glm::mat3 R = glm::mat3_cast(q); + // Columns of R are the rotated unit axes (X-forward, Y-right, + // Z-up convention). + EmitPyramidArrow(arrow_vertices_, arrow_colors_, arrow_indices_, + control_points_[i], R[0], R[1], R[2], arrow_color_, + arrow_size_); + } + return; + } + std::vector arrow_positions; switch (arrow_mode_) { @@ -545,13 +669,44 @@ void Path::ComputePathColors() { case ColorMode::kVelocity: case ColorMode::kTime: case ColorMode::kCost: { - for (size_t i = 0; i < path_vertices_.size(); ++i) { + // Auto-fit color range from current scalar_values_ if requested. + // Lets streaming trajectories adjust their color mapping as new + // samples arrive without the caller managing the range manually. + if (auto_color_range_ && !scalar_values_.empty()) { + float lo = scalar_values_.front(); + float hi = scalar_values_.front(); + for (float v : scalar_values_) { + if (v < lo) lo = v; + if (v > hi) hi = v; + } + // Avoid degenerate range when all samples are equal. + if (hi <= lo) hi = lo + 1.0f; + color_range_ = glm::vec2(lo, hi); + } + + // Map each path vertex to a fractional control-point index, then + // interpolate scalar_values_ at that fraction. This is correct + // for both line-segment paths (path_vertices_.size() == + // control_points_.size()) and subdivided smooth paths + // (path_vertices_.size() > control_points_.size()), where the + // previous "scalar_values_[i]" indexing produced misaligned + // colors. + const size_t v_count = path_vertices_.size(); + const size_t s_count = scalar_values_.size(); + for (size_t i = 0; i < v_count; ++i) { float value = 0.0f; - if (i < scalar_values_.size()) { - value = scalar_values_[i]; - } else if (!scalar_values_.empty()) { - // Use last available value - value = scalar_values_.back(); + if (s_count >= 2) { + const float t = + (v_count <= 1) ? 0.0f + : (static_cast(i) / + static_cast(v_count - 1)) * + static_cast(s_count - 1); + const size_t lo = static_cast(t); + const size_t hi = std::min(lo + 1, s_count - 1); + const float frac = t - static_cast(lo); + value = glm::mix(scalar_values_[lo], scalar_values_[hi], frac); + } else if (s_count == 1) { + value = scalar_values_[0]; } path_colors_.push_back(ColorFromScalar(value)); } diff --git a/src/gldraw/src/renderable/plane.cpp b/src/scene/src/renderable/plane.cpp similarity index 99% rename from src/gldraw/src/renderable/plane.cpp rename to src/scene/src/renderable/plane.cpp index b8c6d06..d6f514b 100644 --- a/src/gldraw/src/renderable/plane.cpp +++ b/src/scene/src/renderable/plane.cpp @@ -7,7 +7,7 @@ * Copyright (c) 2025 Ruixiang Du (rdu) */ -#include "gldraw/renderable/plane.hpp" +#include "scene/renderable/plane.hpp" #include #include @@ -16,7 +16,7 @@ #include #include -#include "gldraw/shader.hpp" +#include "scene/shader.hpp" namespace quickviz { diff --git a/src/gldraw/src/renderable/point_cloud.cpp b/src/scene/src/renderable/point_cloud.cpp similarity index 99% rename from src/gldraw/src/renderable/point_cloud.cpp rename to src/scene/src/renderable/point_cloud.cpp index da5709b..963ab20 100644 --- a/src/gldraw/src/renderable/point_cloud.cpp +++ b/src/scene/src/renderable/point_cloud.cpp @@ -7,7 +7,7 @@ * Copyright (c) 2025 Ruixiang Du (rdu) */ -#include "gldraw/renderable/point_cloud.hpp" +#include "scene/renderable/point_cloud.hpp" #include #include @@ -16,7 +16,7 @@ #include #include -#include "gldraw/shader.hpp" +#include "scene/shader.hpp" namespace quickviz { diff --git a/src/gldraw/src/renderable/pose.cpp b/src/scene/src/renderable/pose.cpp similarity index 99% rename from src/gldraw/src/renderable/pose.cpp rename to src/scene/src/renderable/pose.cpp index 7a55f2a..285449d 100644 --- a/src/gldraw/src/renderable/pose.cpp +++ b/src/scene/src/renderable/pose.cpp @@ -7,7 +7,7 @@ * Copyright (c) 2025 Ruixiang Du (rdu) */ -#include "gldraw/renderable/pose.hpp" +#include "scene/renderable/pose.hpp" #include #include @@ -17,7 +17,7 @@ #include #include -#include "gldraw/shader.hpp" +#include "scene/shader.hpp" namespace quickviz { diff --git a/src/gldraw/src/renderable/sphere.cpp b/src/scene/src/renderable/sphere.cpp similarity index 99% rename from src/gldraw/src/renderable/sphere.cpp rename to src/scene/src/renderable/sphere.cpp index 12a2962..2eb1260 100644 --- a/src/gldraw/src/renderable/sphere.cpp +++ b/src/scene/src/renderable/sphere.cpp @@ -7,7 +7,7 @@ * Copyright (c) 2025 Ruixiang Du (rdu) */ -#include "gldraw/renderable/sphere.hpp" +#include "scene/renderable/sphere.hpp" #include #include @@ -16,7 +16,7 @@ #include #include -#include "gldraw/shader.hpp" +#include "scene/shader.hpp" namespace quickviz { diff --git a/src/gldraw/src/renderable/texture.cpp b/src/scene/src/renderable/texture.cpp similarity index 99% rename from src/gldraw/src/renderable/texture.cpp rename to src/scene/src/renderable/texture.cpp index 2edfe88..17d7152 100644 --- a/src/gldraw/src/renderable/texture.cpp +++ b/src/scene/src/renderable/texture.cpp @@ -7,7 +7,7 @@ * Copyright (c) 2025 Ruixiang Du (rdu) */ -#include "gldraw/renderable/texture.hpp" +#include "scene/renderable/texture.hpp" #include #include diff --git a/src/scene/src/renderable/tf_frame_tree.cpp b/src/scene/src/renderable/tf_frame_tree.cpp new file mode 100644 index 0000000..374ea9c --- /dev/null +++ b/src/scene/src/renderable/tf_frame_tree.cpp @@ -0,0 +1,251 @@ +/** + * @file tf_frame_tree.cpp + * + * Copyright (c) 2026 Ruixiang Du (rdu) + */ + +#include "scene/renderable/tf_frame_tree.hpp" + +#include +#include + +#include "glad/glad.h" +#include + +#include "scene/shader.hpp" + +namespace quickviz { +namespace { + +const std::string kVertexShader = R"( +#version 330 core +layout(location = 0) in vec3 aPos; +layout(location = 1) in vec3 aColor; + +uniform mat4 projection; +uniform mat4 view; +uniform mat4 model; +uniform mat4 coordSystemTransform; + +out vec3 vColor; + +void main() { + gl_Position = projection * view * coordSystemTransform * model * vec4(aPos, 1.0); + vColor = aColor; +} +)"; + +const std::string kFragmentShader = R"( +#version 330 core +in vec3 vColor; +out vec4 FragColor; +void main() { FragColor = vec4(vColor, 1.0); } +)"; + +} // namespace + +TfFrameTree::TfFrameTree(float axis_length) : axis_length_(axis_length) { + AllocateGpuResources(); +} + +TfFrameTree::~TfFrameTree() { ReleaseGpuResources(); } + +void TfFrameTree::AllocateGpuResources() { + if (IsGpuResourcesAllocated()) return; + + Shader vs(kVertexShader.c_str(), Shader::Type::kVertex); + Shader fs(kFragmentShader.c_str(), Shader::Type::kFragment); + if (!vs.Compile()) { + throw std::runtime_error("TfFrameTree: vertex shader compile failed"); + } + if (!fs.Compile()) { + throw std::runtime_error("TfFrameTree: fragment shader compile failed"); + } + shader_.AttachShader(vs); + shader_.AttachShader(fs); + if (!shader_.LinkProgram()) { + throw std::runtime_error("TfFrameTree: shader program link failed"); + } + + glGenVertexArrays(1, &vao_); + glGenBuffers(1, &vbo_); + glBindVertexArray(vao_); + glBindBuffer(GL_ARRAY_BUFFER, vbo_); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), + (void*)offsetof(Vertex, position)); + glEnableVertexAttribArray(0); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), + (void*)offsetof(Vertex, color)); + glEnableVertexAttribArray(1); + glBindVertexArray(0); +} + +void TfFrameTree::ReleaseGpuResources() noexcept { + if (vbo_) { + glDeleteBuffers(1, &vbo_); + vbo_ = 0; + } + if (vao_) { + glDeleteVertexArrays(1, &vao_); + vao_ = 0; + } +} + +void TfFrameTree::SetFrame(const std::string& name, const std::string& parent, + const glm::mat4& transform_in_parent) { + if (name.empty()) { + throw std::invalid_argument("TfFrameTree::SetFrame: name cannot be empty"); + } + if (name == parent) { + throw std::invalid_argument( + "TfFrameTree::SetFrame: a frame cannot be its own parent"); + } + Frame& f = frames_[name]; + f.parent = parent; + f.local = transform_in_parent; + dirty_ = true; +} + +std::size_t TfFrameTree::RemoveFrame(const std::string& name) { + if (frames_.find(name) == frames_.end()) return 0; + + // Collect descendants by name (children-of relation). + std::unordered_set to_remove; + to_remove.insert(name); + + bool changed = true; + while (changed) { + changed = false; + for (const auto& [n, f] : frames_) { + if (to_remove.count(n)) continue; + if (to_remove.count(f.parent)) { + to_remove.insert(n); + changed = true; + } + } + } + + for (const auto& n : to_remove) frames_.erase(n); + dirty_ = true; + return to_remove.size(); +} + +void TfFrameTree::Clear() { + frames_.clear(); + dirty_ = true; +} + +bool TfFrameTree::HasFrame(const std::string& name) const { + return frames_.find(name) != frames_.end(); +} + +glm::mat4 TfFrameTree::GetWorldTransform(const std::string& name) const { + auto it = frames_.find(name); + if (it == frames_.end()) return glm::mat4(1.0f); + + // Walk parents, accumulating transforms. Detect cycles by visited set. + glm::mat4 accumulated = it->second.local; + std::string current = it->second.parent; + std::unordered_set visited{name}; + while (!current.empty()) { + if (visited.count(current)) { + // Cycle: bail out, return identity for safety. + return glm::mat4(1.0f); + } + visited.insert(current); + auto parent_it = frames_.find(current); + if (parent_it == frames_.end()) { + // Broken chain: parent referenced but not registered. Treat as + // root for visualization purposes (the missing parent is + // implicitly identity). + break; + } + accumulated = parent_it->second.local * accumulated; + current = parent_it->second.parent; + } + return accumulated; +} + +void TfFrameTree::SetAxisLength(float length) { + if (length <= 0.0f) { + throw std::invalid_argument( + "TfFrameTree::SetAxisLength: length must be positive"); + } + axis_length_ = length; + dirty_ = true; +} + +void TfFrameTree::RebuildVertices() { + vertices_.clear(); + if (frames_.empty()) { + dirty_ = false; + return; + } + + // Pre-compute world transforms once. + std::unordered_map world_xforms; + world_xforms.reserve(frames_.size()); + for (const auto& [name, _] : frames_) { + world_xforms.emplace(name, GetWorldTransform(name)); + } + + vertices_.reserve(frames_.size() * 6 + + (show_connections_ ? frames_.size() * 2 : 0)); + + const glm::vec3 red(1.0f, 0.0f, 0.0f); + const glm::vec3 green(0.0f, 1.0f, 0.0f); + const glm::vec3 blue(0.0f, 0.0f, 1.0f); + + for (const auto& [name, frame] : frames_) { + const glm::mat4& W = world_xforms.at(name); + const glm::vec3 origin(W[3]); + const glm::vec3 ex = glm::vec3(W * glm::vec4(axis_length_, 0, 0, 1)); + const glm::vec3 ey = glm::vec3(W * glm::vec4(0, axis_length_, 0, 1)); + const glm::vec3 ez = glm::vec3(W * glm::vec4(0, 0, axis_length_, 1)); + + vertices_.push_back({origin, red}); + vertices_.push_back({ex, red}); + vertices_.push_back({origin, green}); + vertices_.push_back({ey, green}); + vertices_.push_back({origin, blue}); + vertices_.push_back({ez, blue}); + + if (show_connections_ && !frame.parent.empty()) { + auto parent_it = world_xforms.find(frame.parent); + if (parent_it != world_xforms.end()) { + const glm::vec3 parent_origin(parent_it->second[3]); + vertices_.push_back({parent_origin, connection_color_}); + vertices_.push_back({origin, connection_color_}); + } + } + } + + glBindBuffer(GL_ARRAY_BUFFER, vbo_); + const std::size_t bytes = vertices_.size() * sizeof(Vertex); + if (vertices_.size() > buffer_capacity_) { + glBufferData(GL_ARRAY_BUFFER, bytes, vertices_.data(), GL_DYNAMIC_DRAW); + buffer_capacity_ = vertices_.size(); + } else { + glBufferSubData(GL_ARRAY_BUFFER, 0, bytes, vertices_.data()); + } + + dirty_ = false; +} + +void TfFrameTree::OnDraw(const glm::mat4& projection, const glm::mat4& view, + const glm::mat4& coord_transform) { + if (dirty_) RebuildVertices(); + if (vertices_.empty()) return; + + shader_.Use(); + shader_.SetUniform("projection", projection); + shader_.SetUniform("view", view); + shader_.SetUniform("model", GetTransform()); + shader_.SetUniform("coordSystemTransform", coord_transform); + + glBindVertexArray(vao_); + glDrawArrays(GL_LINES, 0, static_cast(vertices_.size())); + glBindVertexArray(0); +} + +} // namespace quickviz diff --git a/src/gldraw/src/gl_viewer.cpp b/src/scene/src/scene_app.cpp similarity index 85% rename from src/gldraw/src/gl_viewer.cpp rename to src/scene/src/scene_app.cpp index 6d05639..a4da022 100644 --- a/src/gldraw/src/gl_viewer.cpp +++ b/src/scene/src/scene_app.cpp @@ -8,18 +8,18 @@ * Copyright (c) 2025 Ruixiang Du (rdu) */ -#include "gldraw/gl_viewer.hpp" +#include "scene/scene_app.hpp" #include #include -#include "imview/styling.hpp" +#include "viewer/styling.hpp" namespace quickviz { -GlViewer::GlViewer(const Config& config) : config_(config) { SetupViewer(); } +SceneApp::SceneApp(const Config& config) : config_(config) { SetupViewer(); } -void GlViewer::SetupViewer() { +void SceneApp::SetupViewer() { // Create box container for layout auto box = std::make_shared("main_box"); box->SetFlexDirection(Styling::FlexDirection::kRow); @@ -37,7 +37,7 @@ void GlViewer::SetupViewer() { viewer_.AddSceneObject(box); } -void GlViewer::SetupBasicScene() { +void SceneApp::SetupBasicScene() { // Add grid if requested if (config_.show_grid) { auto grid = std::make_unique(config_.grid_size, config_.grid_step, @@ -54,22 +54,22 @@ void GlViewer::SetupBasicScene() { } } -void GlViewer::SetSceneSetup(SceneSetupCallback callback) { +void SceneApp::SetSceneSetup(SceneSetupCallback callback) { scene_setup_callback_ = std::move(callback); } -void GlViewer::AddHelpSection(const std::string& section_title, +void SceneApp::AddHelpSection(const std::string& section_title, const std::vector& help_lines) { help_sections_.emplace_back(section_title, help_lines); } -void GlViewer::SetDescription(const std::string& description) { +void SceneApp::SetDescription(const std::string& description) { description_ = description; } -SceneManager* GlViewer::GetSceneManager() const { return scene_panel_->GetSceneManager(); } +SceneManager* SceneApp::GetSceneManager() const { return scene_panel_->GetSceneManager(); } -void GlViewer::DisplayHelp() const { +void SceneApp::DisplayHelp() const { std::cout << "\n=== " << config_.window_title << " ===" << std::endl; if (!description_.empty()) { @@ -94,7 +94,7 @@ void GlViewer::DisplayHelp() const { std::cout << std::endl; } -void GlViewer::Run() { +void SceneApp::Run() { try { // Set up basic scene elements SetupBasicScene(); diff --git a/src/gldraw/src/scene_input_handler.cpp b/src/scene/src/scene_input_handler.cpp similarity index 97% rename from src/gldraw/src/scene_input_handler.cpp rename to src/scene/src/scene_input_handler.cpp index 74a8d26..967be8f 100644 --- a/src/gldraw/src/scene_input_handler.cpp +++ b/src/scene/src/scene_input_handler.cpp @@ -6,11 +6,11 @@ * @copyright Copyright (c) 2025 Ruixiang Du (rdu) */ -#include "gldraw/scene_input_handler.hpp" -#include "gldraw/scene_manager.hpp" -#include "gldraw/camera_control_config.hpp" -#include "gldraw/tools/interaction_tool.hpp" -#include "imview/input/input_types.hpp" +#include "scene/scene_input_handler.hpp" +#include "scene/scene_manager.hpp" +#include "scene/camera_control_config.hpp" +#include "scene/tools/interaction_tool.hpp" +#include "viewer/input/input_types.hpp" #include "core/event/input_mapping.hpp" namespace quickviz { diff --git a/src/gldraw/src/scene_manager.cpp b/src/scene/src/scene_manager.cpp similarity index 95% rename from src/gldraw/src/scene_manager.cpp rename to src/scene/src/scene_manager.cpp index 92b2bc8..5e6dd13 100644 --- a/src/gldraw/src/scene_manager.cpp +++ b/src/scene/src/scene_manager.cpp @@ -7,7 +7,7 @@ * Copyright (c) 2025 Ruixiang Du (rdu) */ -#include "gldraw/scene_manager.hpp" +#include "scene/scene_manager.hpp" #include #include @@ -18,11 +18,11 @@ #include -#include "gldraw/coordinate_transformer.hpp" -#include "gldraw/selection_manager.hpp" -#include "gldraw/tools/interaction_tool.hpp" -#include "gldraw/renderable/point_cloud.hpp" -#include "gldraw/renderable/geometric_primitive.hpp" +#include "scene/coordinate_transformer.hpp" +#include "scene/selection_manager.hpp" +#include "scene/tools/interaction_tool.hpp" +#include "scene/renderable/point_cloud.hpp" +#include "scene/renderable/geometric_primitive.hpp" namespace quickviz { SceneManager::SceneManager(const std::string& name, Mode mode) diff --git a/src/gldraw/src/selection_manager.cpp b/src/scene/src/selection_manager.cpp similarity index 99% rename from src/gldraw/src/selection_manager.cpp rename to src/scene/src/selection_manager.cpp index e4a6e4c..2eb335d 100644 --- a/src/gldraw/src/selection_manager.cpp +++ b/src/scene/src/selection_manager.cpp @@ -7,16 +7,16 @@ * Copyright (c) 2025 Ruixiang Du (rdu) */ -#include "gldraw/selection_manager.hpp" +#include "scene/selection_manager.hpp" #include #include #include #include -#include "gldraw/scene_manager.hpp" -#include "gldraw/renderable/point_cloud.hpp" -#include "gldraw/frame_buffer.hpp" +#include "scene/scene_manager.hpp" +#include "scene/renderable/point_cloud.hpp" +#include "scene/frame_buffer.hpp" namespace quickviz { diff --git a/src/gldraw/src/shader.cpp b/src/scene/src/shader.cpp similarity index 99% rename from src/gldraw/src/shader.cpp rename to src/scene/src/shader.cpp index 2a9aea4..c101270 100644 --- a/src/gldraw/src/shader.cpp +++ b/src/scene/src/shader.cpp @@ -6,7 +6,7 @@ * @copyright Copyright (c) 2024 Ruixiang Du (rdu) */ -#include "gldraw/shader.hpp" +#include "scene/shader.hpp" #include #include diff --git a/src/gldraw/src/shader_program.cpp b/src/scene/src/shader_program.cpp similarity index 99% rename from src/gldraw/src/shader_program.cpp rename to src/scene/src/shader_program.cpp index 82e17f5..ac2ad09 100644 --- a/src/gldraw/src/shader_program.cpp +++ b/src/scene/src/shader_program.cpp @@ -6,7 +6,7 @@ * @copyright Copyright (c) 2024 Ruixiang Du (rdu) */ -#include "gldraw/shader_program.hpp" +#include "scene/shader_program.hpp" #include diff --git a/src/gldraw/src/tools/interaction_tool.cpp b/src/scene/src/tools/interaction_tool.cpp similarity index 98% rename from src/gldraw/src/tools/interaction_tool.cpp rename to src/scene/src/tools/interaction_tool.cpp index 4179199..4edd9d7 100644 --- a/src/gldraw/src/tools/interaction_tool.cpp +++ b/src/scene/src/tools/interaction_tool.cpp @@ -7,8 +7,8 @@ * Copyright (c) 2025 Ruixiang Du (rdu) */ -#include "gldraw/tools/interaction_tool.hpp" -#include "gldraw/scene_manager.hpp" +#include "scene/tools/interaction_tool.hpp" +#include "scene/scene_manager.hpp" #include #include diff --git a/src/gldraw/src/tools/point_selection_tool.cpp b/src/scene/src/tools/point_selection_tool.cpp similarity index 99% rename from src/gldraw/src/tools/point_selection_tool.cpp rename to src/scene/src/tools/point_selection_tool.cpp index 46f56cf..8646a37 100644 --- a/src/gldraw/src/tools/point_selection_tool.cpp +++ b/src/scene/src/tools/point_selection_tool.cpp @@ -7,9 +7,9 @@ * Copyright (c) 2025 Ruixiang Du (rdu) */ -#include "gldraw/tools/point_selection_tool.hpp" -#include "gldraw/scene_manager.hpp" -#include "gldraw/renderable/point_cloud.hpp" +#include "scene/tools/point_selection_tool.hpp" +#include "scene/scene_manager.hpp" +#include "scene/renderable/point_cloud.hpp" #include #include diff --git a/src/gldraw/test/CMakeLists.txt b/src/scene/test/CMakeLists.txt similarity index 60% rename from src/gldraw/test/CMakeLists.txt rename to src/scene/test/CMakeLists.txt index 6b805c9..cfc7c0d 100644 --- a/src/gldraw/test/CMakeLists.txt +++ b/src/scene/test/CMakeLists.txt @@ -1,40 +1,41 @@ +add_subdirectory(test_utils) add_subdirectory(feature) add_subdirectory(renderable) add_subdirectory(selection) add_executable(test_framebuffer test_framebuffer.cpp) -target_link_libraries(test_framebuffer PRIVATE gldraw) +target_link_libraries(test_framebuffer PRIVATE scene) add_executable(test_shader test_shader.cpp) -target_link_libraries(test_shader PRIVATE gldraw) +target_link_libraries(test_shader PRIVATE scene) add_executable(test_camera_raw test_camera_raw.cpp) -target_link_libraries(test_camera_raw PRIVATE gldraw) +target_link_libraries(test_camera_raw PRIVATE scene) add_executable(test_point_cloud_realtime test_point_cloud_realtime.cpp) -target_link_libraries(test_point_cloud_realtime PRIVATE gldraw) +target_link_libraries(test_point_cloud_realtime PRIVATE scene) add_executable(test_point_cloud_buffer_strategies test_point_cloud_buffer_strategies.cpp) -target_link_libraries(test_point_cloud_buffer_strategies PRIVATE gldraw) +target_link_libraries(test_point_cloud_buffer_strategies PRIVATE scene) # Test external selection demo (replaces old selection integration) # test_pcd_with_selection.cpp now demonstrates external selection visualization add_executable(test_coordinate_system test_coordinate_system.cpp) -target_link_libraries(test_coordinate_system PRIVATE gldraw) +target_link_libraries(test_coordinate_system PRIVATE scene) add_executable(test_primitive_drawing test_primitive_drawing.cpp) -target_link_libraries(test_primitive_drawing PRIVATE gldraw) +target_link_libraries(test_primitive_drawing PRIVATE scene_test_utils) add_executable(test_canvas_st test_canvas_st.cpp) -target_link_libraries(test_canvas_st PRIVATE gldraw) +target_link_libraries(test_canvas_st PRIVATE scene_test_utils) add_executable(test_nav_map_rendering test_nav_map_rendering.cpp) -target_link_libraries(test_nav_map_rendering PRIVATE gldraw) +target_link_libraries(test_nav_map_rendering PRIVATE scene_test_utils) add_executable(test_layer_system_box test_layer_system_box.cpp) -target_link_libraries(test_layer_system_box PRIVATE gldraw) +target_link_libraries(test_layer_system_box PRIVATE scene) add_executable(test_font_renderer test_font_renderer.cpp) -target_link_libraries(test_font_renderer PRIVATE gldraw) +target_link_libraries(test_font_renderer PRIVATE scene) diff --git a/src/gldraw/test/feature/CMakeLists.txt b/src/scene/test/feature/CMakeLists.txt similarity index 51% rename from src/gldraw/test/feature/CMakeLists.txt rename to src/scene/test/feature/CMakeLists.txt index 25ce8d2..85da9be 100644 --- a/src/gldraw/test/feature/CMakeLists.txt +++ b/src/scene/test/feature/CMakeLists.txt @@ -1,20 +1,20 @@ add_executable(test_gl_scene_panel test_gl_scene_panel.cpp) -target_link_libraries(test_gl_scene_panel PRIVATE gldraw) +target_link_libraries(test_gl_scene_panel PRIVATE scene_test_utils) add_executable(test_robot_frames test_robot_frames.cpp) -target_link_libraries(test_robot_frames PRIVATE gldraw) +target_link_libraries(test_robot_frames PRIVATE scene) add_executable(test_camera test_camera.cpp) -target_link_libraries(test_camera PRIVATE gldraw) +target_link_libraries(test_camera PRIVATE scene) add_executable(test_layer_system test_layer_system.cpp) -target_link_libraries(test_layer_system PRIVATE gldraw) +target_link_libraries(test_layer_system PRIVATE scene) add_executable(test_camera_control_mappings test_camera_control_mappings.cpp) -target_link_libraries(test_camera_control_mappings PRIVATE gldraw) +target_link_libraries(test_camera_control_mappings PRIVATE scene) add_executable(test_camera_configuration test_camera_configuration.cpp) -target_link_libraries(test_camera_configuration PRIVATE gldraw) +target_link_libraries(test_camera_configuration PRIVATE scene) add_executable(test_visual_feedback_system test_visual_feedback_system.cpp) -target_link_libraries(test_visual_feedback_system PRIVATE gldraw) +target_link_libraries(test_visual_feedback_system PRIVATE scene_test_utils) diff --git a/src/gldraw/test/feature/test_camera.cpp b/src/scene/test/feature/test_camera.cpp similarity index 93% rename from src/gldraw/test/feature/test_camera.cpp rename to src/scene/test/feature/test_camera.cpp index 76f75a7..458aa9d 100644 --- a/src/gldraw/test/feature/test_camera.cpp +++ b/src/scene/test/feature/test_camera.cpp @@ -11,11 +11,11 @@ #include #include -#include "imview/viewer.hpp" -#include "imview/box.hpp" -#include "gldraw/gl_scene_panel.hpp" -#include "gldraw/renderable/grid.hpp" -#include "gldraw/renderable/point_cloud.hpp" +#include "viewer/viewer.hpp" +#include "viewer/box.hpp" +#include "scene/gl_scene_panel.hpp" +#include "scene/renderable/grid.hpp" +#include "scene/renderable/point_cloud.hpp" using namespace quickviz; diff --git a/src/gldraw/test/feature/test_camera_configuration.cpp b/src/scene/test/feature/test_camera_configuration.cpp similarity index 96% rename from src/gldraw/test/feature/test_camera_configuration.cpp rename to src/scene/test/feature/test_camera_configuration.cpp index 03f52d5..288e6fd 100644 --- a/src/gldraw/test/feature/test_camera_configuration.cpp +++ b/src/scene/test/feature/test_camera_configuration.cpp @@ -10,12 +10,12 @@ #include #include -#include "imview/viewer.hpp" -#include "imview/box.hpp" -#include "gldraw/gl_scene_panel.hpp" -#include "gldraw/renderable/grid.hpp" -#include "gldraw/renderable/point_cloud.hpp" -#include "gldraw/camera_controller.hpp" +#include "viewer/viewer.hpp" +#include "viewer/box.hpp" +#include "scene/gl_scene_panel.hpp" +#include "scene/renderable/grid.hpp" +#include "scene/renderable/point_cloud.hpp" +#include "scene/camera_controller.hpp" #include "imgui.h" using namespace quickviz; diff --git a/src/gldraw/test/feature/test_camera_control_mappings.cpp b/src/scene/test/feature/test_camera_control_mappings.cpp similarity index 96% rename from src/gldraw/test/feature/test_camera_control_mappings.cpp rename to src/scene/test/feature/test_camera_control_mappings.cpp index 1265030..d5d07fc 100644 --- a/src/gldraw/test/feature/test_camera_control_mappings.cpp +++ b/src/scene/test/feature/test_camera_control_mappings.cpp @@ -12,13 +12,13 @@ #include #include -#include "imview/viewer.hpp" -#include "imview/box.hpp" -#include "gldraw/gl_scene_panel.hpp" -#include "gldraw/renderable/grid.hpp" -#include "gldraw/renderable/point_cloud.hpp" -#include "gldraw/scene_input_handler.hpp" -#include "gldraw/camera_control_config.hpp" +#include "viewer/viewer.hpp" +#include "viewer/box.hpp" +#include "scene/gl_scene_panel.hpp" +#include "scene/renderable/grid.hpp" +#include "scene/renderable/point_cloud.hpp" +#include "scene/scene_input_handler.hpp" +#include "scene/camera_control_config.hpp" #include "imgui.h" using namespace quickviz; diff --git a/src/gldraw/test/feature/test_gl_scene_panel.cpp b/src/scene/test/feature/test_gl_scene_panel.cpp similarity index 88% rename from src/gldraw/test/feature/test_gl_scene_panel.cpp rename to src/scene/test/feature/test_gl_scene_panel.cpp index 8924e71..dddbda7 100644 --- a/src/gldraw/test/feature/test_gl_scene_panel.cpp +++ b/src/scene/test/feature/test_gl_scene_panel.cpp @@ -13,12 +13,12 @@ #include #include -#include "imview/box.hpp" -#include "imview/viewer.hpp" +#include "viewer/box.hpp" +#include "viewer/viewer.hpp" -#include "gldraw/gl_scene_panel.hpp" -#include "gldraw/renderable/grid.hpp" -#include "gldraw/renderable/triangle.hpp" +#include "scene/gl_scene_panel.hpp" +#include "scene/renderable/grid.hpp" +#include "test_utils/triangle.hpp" using namespace quickviz; diff --git a/src/gldraw/test/feature/test_layer_system.cpp b/src/scene/test/feature/test_layer_system.cpp similarity index 97% rename from src/gldraw/test/feature/test_layer_system.cpp rename to src/scene/test/feature/test_layer_system.cpp index b9b7bff..6bc8a39 100644 --- a/src/gldraw/test/feature/test_layer_system.cpp +++ b/src/scene/test/feature/test_layer_system.cpp @@ -12,12 +12,12 @@ #include #include -#include "imview/viewer.hpp" -#include "imview/box.hpp" -#include "gldraw/gl_scene_panel.hpp" -#include "gldraw/renderable/grid.hpp" -#include "gldraw/renderable/point_cloud.hpp" -#include "../../include/gldraw/renderable/details/point_layer_manager.hpp" +#include "viewer/viewer.hpp" +#include "viewer/box.hpp" +#include "scene/gl_scene_panel.hpp" +#include "scene/renderable/grid.hpp" +#include "scene/renderable/point_cloud.hpp" +#include "../../include/scene/renderable/details/point_layer_manager.hpp" using namespace quickviz; diff --git a/src/gldraw/test/feature/test_robot_frames.cpp b/src/scene/test/feature/test_robot_frames.cpp similarity index 95% rename from src/gldraw/test/feature/test_robot_frames.cpp rename to src/scene/test/feature/test_robot_frames.cpp index 46fbec6..118dcc5 100644 --- a/src/gldraw/test/feature/test_robot_frames.cpp +++ b/src/scene/test/feature/test_robot_frames.cpp @@ -16,12 +16,12 @@ #include #include -#include "imview/box.hpp" -#include "imview/viewer.hpp" +#include "viewer/box.hpp" +#include "viewer/viewer.hpp" -#include "gldraw/gl_scene_panel.hpp" -#include "gldraw/renderable/grid.hpp" -#include "gldraw/renderable/coordinate_frame.hpp" +#include "scene/gl_scene_panel.hpp" +#include "scene/renderable/grid.hpp" +#include "scene/renderable/coordinate_frame.hpp" using namespace quickviz; diff --git a/src/gldraw/test/feature/test_visual_feedback_system.cpp b/src/scene/test/feature/test_visual_feedback_system.cpp similarity index 96% rename from src/gldraw/test/feature/test_visual_feedback_system.cpp rename to src/scene/test/feature/test_visual_feedback_system.cpp index 92f1caa..f8cb42e 100644 --- a/src/gldraw/test/feature/test_visual_feedback_system.cpp +++ b/src/scene/test/feature/test_visual_feedback_system.cpp @@ -10,13 +10,13 @@ #include #include -#include "imview/viewer.hpp" -#include "imview/box.hpp" -#include "gldraw/gl_scene_panel.hpp" -#include "gldraw/renderable/grid.hpp" -#include "gldraw/renderable/point_cloud.hpp" -#include "gldraw/renderable/triangle.hpp" -#include "gldraw/feedback/visual_feedback_system.hpp" +#include "viewer/viewer.hpp" +#include "viewer/box.hpp" +#include "scene/gl_scene_panel.hpp" +#include "scene/renderable/grid.hpp" +#include "scene/renderable/point_cloud.hpp" +#include "test_utils/triangle.hpp" +#include "scene/feedback/visual_feedback_system.hpp" #include "imgui.h" using namespace quickviz; diff --git a/src/gldraw/test/input/test_gamepad_input.cpp b/src/scene/test/input/test_gamepad_input.cpp similarity index 98% rename from src/gldraw/test/input/test_gamepad_input.cpp rename to src/scene/test/input/test_gamepad_input.cpp index 786e595..5016204 100644 --- a/src/gldraw/test/input/test_gamepad_input.cpp +++ b/src/scene/test/input/test_gamepad_input.cpp @@ -12,9 +12,9 @@ #include "core/event/input_event.hpp" #include "core/event/input_mapping.hpp" -#include "imview/input/imgui_input_utils.hpp" -#include "gldraw/input/scene_input_handler.hpp" -#include "imview/input/input_dispatcher.hpp" +#include "viewer/input/imgui_input_utils.hpp" +#include "scene/input/scene_input_handler.hpp" +#include "viewer/input/input_dispatcher.hpp" using namespace quickviz; diff --git a/src/scene/test/renderable/CMakeLists.txt b/src/scene/test/renderable/CMakeLists.txt new file mode 100644 index 0000000..bd91d32 --- /dev/null +++ b/src/scene/test/renderable/CMakeLists.txt @@ -0,0 +1,58 @@ +add_executable(test_arrow test_arrow.cpp) +target_link_libraries(test_arrow PRIVATE scene) + +add_executable(test_billboard test_billboard.cpp) +target_link_libraries(test_billboard PRIVATE scene) + +add_executable(test_bounding_box test_bounding_box.cpp) +target_link_libraries(test_bounding_box PRIVATE scene) + +add_executable(test_canvas test_canvas.cpp) +target_link_libraries(test_canvas PRIVATE scene_test_utils) + +add_executable(test_coordinate_frame test_coordinate_frame.cpp) +target_link_libraries(test_coordinate_frame PRIVATE scene) + +add_executable(test_cylinder test_cylinder.cpp) +target_link_libraries(test_cylinder PRIVATE scene) + +add_executable(test_frustum test_frustum.cpp) +target_link_libraries(test_frustum PRIVATE scene) + +add_executable(test_grid test_grid.cpp) +target_link_libraries(test_grid PRIVATE scene) + +add_executable(test_occupancy_grid test_occupancy_grid.cpp) +target_link_libraries(test_occupancy_grid PRIVATE scene) + +add_executable(test_tf_frame_tree test_tf_frame_tree.cpp) +target_link_libraries(test_tf_frame_tree PRIVATE scene) + +add_executable(test_line_strip test_line_strip.cpp) +target_link_libraries(test_line_strip PRIVATE scene) + +add_executable(test_mesh test_mesh.cpp) +target_link_libraries(test_mesh PRIVATE scene) + +add_executable(test_point_cloud test_point_cloud.cpp) +target_link_libraries(test_point_cloud PRIVATE scene) + +add_executable(test_path test_path.cpp) +target_link_libraries(test_path PRIVATE scene) + +add_executable(test_plane test_plane.cpp) +target_link_libraries(test_plane PRIVATE scene) + +add_executable(test_pose test_pose.cpp) +target_link_libraries(test_pose PRIVATE scene) + +add_executable(test_sphere test_sphere.cpp) +target_link_libraries(test_sphere PRIVATE scene) + + +add_executable(test_texture test_texture.cpp) +target_link_libraries(test_texture PRIVATE scene) + +add_executable(test_triangle test_triangle.cpp) +target_link_libraries(test_triangle PRIVATE scene_test_utils) + diff --git a/src/gldraw/test/renderable/test_arrow.cpp b/src/scene/test/renderable/test_arrow.cpp similarity index 97% rename from src/gldraw/test/renderable/test_arrow.cpp rename to src/scene/test/renderable/test_arrow.cpp index 61c7fa6..1ef8c2d 100644 --- a/src/gldraw/test/renderable/test_arrow.cpp +++ b/src/scene/test/renderable/test_arrow.cpp @@ -15,8 +15,8 @@ #include #include -#include "gldraw/gl_viewer.hpp" -#include "gldraw/renderable/arrow.hpp" +#include "scene/scene_app.hpp" +#include "scene/renderable/arrow.hpp" using namespace quickviz; @@ -128,12 +128,12 @@ void SetupArrowScene(SceneManager* scene_manager) { int main(int argc, char* argv[]) { try { // Configure the view - GlViewer::Config config; + SceneApp::Config config; config.window_title = "Arrow Rendering Test"; config.coordinate_frame_size = 1.0f; // Create the view - GlViewer view(config); + SceneApp view(config); // Set up description and help sections view.SetDescription("Testing arrow rendering for vectors, directions, and forces"); diff --git a/src/gldraw/test/renderable/test_billboard.cpp b/src/scene/test/renderable/test_billboard.cpp similarity index 98% rename from src/gldraw/test/renderable/test_billboard.cpp rename to src/scene/test/renderable/test_billboard.cpp index c9b4988..41fe5c1 100644 --- a/src/gldraw/test/renderable/test_billboard.cpp +++ b/src/scene/test/renderable/test_billboard.cpp @@ -19,11 +19,11 @@ #include #include -#include "gldraw/gl_viewer.hpp" -#include "gldraw/renderable/billboard.hpp" -#include "gldraw/renderable/sphere.hpp" -#include "gldraw/renderable/arrow.hpp" -#include "gldraw/renderable/grid.hpp" +#include "scene/scene_app.hpp" +#include "scene/renderable/billboard.hpp" +#include "scene/renderable/sphere.hpp" +#include "scene/renderable/arrow.hpp" +#include "scene/renderable/grid.hpp" using namespace quickviz; @@ -249,12 +249,12 @@ int main(int argc, char* argv[]) { std::cout << std::endl; // Configure the viewer - GlViewer::Config config; + SceneApp::Config config; config.window_title = "Billboard Primitive Test"; config.coordinate_frame_size = 2.0f; // Create viewer - GlViewer viewer(config); + SceneApp viewer(config); // Set up description and help sections viewer.SetDescription("Testing Billboard primitive with ImGui font integration as Text3D replacement"); diff --git a/src/gldraw/test/renderable/test_bounding_box.cpp b/src/scene/test/renderable/test_bounding_box.cpp similarity index 98% rename from src/gldraw/test/renderable/test_bounding_box.cpp rename to src/scene/test/renderable/test_bounding_box.cpp index 51c8175..0035529 100644 --- a/src/gldraw/test/renderable/test_bounding_box.cpp +++ b/src/scene/test/renderable/test_bounding_box.cpp @@ -14,8 +14,8 @@ #include #include -#include "gldraw/gl_viewer.hpp" -#include "gldraw/renderable/bounding_box.hpp" +#include "scene/scene_app.hpp" +#include "scene/renderable/bounding_box.hpp" using namespace quickviz; @@ -96,12 +96,12 @@ void SetupBoundingBoxScene(SceneManager* scene_manager) { int main(int argc, char* argv[]) { try { // Configure the view for 3D mode - GlViewer::Config config; + SceneApp::Config config; config.window_title = "BoundingBox Rendering Test"; config.coordinate_frame_size = 2.0f; // Create the view - GlViewer view(config); + SceneApp view(config); // Set up description and help sections view.SetDescription("Testing bounding box rendering for object bounds and region visualization"); diff --git a/src/gldraw/test/renderable/test_canvas.cpp b/src/scene/test/renderable/test_canvas.cpp similarity index 98% rename from src/gldraw/test/renderable/test_canvas.cpp rename to src/scene/test/renderable/test_canvas.cpp index dd1ed9e..16249f9 100644 --- a/src/gldraw/test/renderable/test_canvas.cpp +++ b/src/scene/test/renderable/test_canvas.cpp @@ -16,9 +16,9 @@ #include #include -#include "gldraw/gl_viewer.hpp" -#include "gldraw/renderable/canvas.hpp" -#include "gldraw/renderable/triangle.hpp" +#include "scene/scene_app.hpp" +#include "scene/renderable/canvas.hpp" +#include "test_utils/triangle.hpp" using namespace quickviz; namespace fs = std::filesystem; @@ -113,13 +113,13 @@ int main(int argc, char* argv[]) { } // Configure the view for 2D mode (canvas works best in 2D) - GlViewer::Config config; + SceneApp::Config config; config.window_title = "Canvas Rendering Test - 2D Mode"; config.scene_mode = SceneManager::Mode::k2D; config.coordinate_frame_size = 0.5f; // Create the view - GlViewer view(config); + SceneApp view(config); // Set up description and help sections view.SetDescription("Testing canvas 2D drawing functionality with various shapes and styles"); diff --git a/src/gldraw/test/renderable/test_coordinate_frame.cpp b/src/scene/test/renderable/test_coordinate_frame.cpp similarity index 96% rename from src/gldraw/test/renderable/test_coordinate_frame.cpp rename to src/scene/test/renderable/test_coordinate_frame.cpp index 9d62d40..5d7c68a 100644 --- a/src/gldraw/test/renderable/test_coordinate_frame.cpp +++ b/src/scene/test/renderable/test_coordinate_frame.cpp @@ -13,9 +13,9 @@ #include #include -#include "gldraw/gl_viewer.hpp" -#include "gldraw/renderable/coordinate_frame.hpp" -#include "gldraw/renderable/grid.hpp" +#include "scene/scene_app.hpp" +#include "scene/renderable/coordinate_frame.hpp" +#include "scene/renderable/grid.hpp" using namespace quickviz; @@ -64,13 +64,13 @@ void SetupCoordinateFrameScene(SceneManager* scene_manager) { int main(int argc, char* argv[]) { try { // Configure the view for 3D mode - GlViewer::Config config; + SceneApp::Config config; config.window_title = "Coordinate Frame Rendering Test"; config.coordinate_frame_size = 2.0f; config.show_coordinate_frame = false; // We'll add our own coordinate frames // Create the view - GlViewer view(config); + SceneApp view(config); // Set up description and help sections view.SetDescription("Testing coordinate frame rendering with various orientations and scales"); diff --git a/src/gldraw/test/renderable/test_cylinder.cpp b/src/scene/test/renderable/test_cylinder.cpp similarity index 96% rename from src/gldraw/test/renderable/test_cylinder.cpp rename to src/scene/test/renderable/test_cylinder.cpp index fb38d19..4332a3b 100644 --- a/src/gldraw/test/renderable/test_cylinder.cpp +++ b/src/scene/test/renderable/test_cylinder.cpp @@ -11,8 +11,8 @@ #include #include -#include "gldraw/gl_viewer.hpp" -#include "gldraw/renderable/cylinder.hpp" +#include "scene/scene_app.hpp" +#include "scene/renderable/cylinder.hpp" using namespace quickviz; @@ -51,12 +51,12 @@ void SetupCylinderScene(SceneManager* scene_manager) { int main(int argc, char* argv[]) { try { // Configure the view for 3D mode - GlViewer::Config config; + SceneApp::Config config; config.window_title = "Cylinder Rendering Test"; config.coordinate_frame_size = 2.0f; // Create the view - GlViewer view(config); + SceneApp view(config); // Set up description and help sections view.SetDescription("Testing cylinder rendering with various dimensions and rendering modes"); diff --git a/src/gldraw/test/renderable/test_frustum.cpp b/src/scene/test/renderable/test_frustum.cpp similarity index 97% rename from src/gldraw/test/renderable/test_frustum.cpp rename to src/scene/test/renderable/test_frustum.cpp index 2677864..9fde161 100644 --- a/src/gldraw/test/renderable/test_frustum.cpp +++ b/src/scene/test/renderable/test_frustum.cpp @@ -11,9 +11,9 @@ #include #include -#include "gldraw/gl_viewer.hpp" -#include "gldraw/renderable/frustum.hpp" -#include "gldraw/renderable/grid.hpp" +#include "scene/scene_app.hpp" +#include "scene/renderable/frustum.hpp" +#include "scene/renderable/grid.hpp" using namespace quickviz; @@ -93,12 +93,12 @@ void SetupFrustumScene(SceneManager* scene_manager) { int main(int argc, char* argv[]) { try { // Configure the view for 3D mode - GlViewer::Config config; + SceneApp::Config config; config.window_title = "Frustum Rendering Test"; config.coordinate_frame_size = 2.0f; // Create the view - GlViewer view(config); + SceneApp view(config); // Set up description and help sections view.SetDescription("Testing frustum rendering for sensor field-of-view visualization"); diff --git a/src/gldraw/test/renderable/test_grid.cpp b/src/scene/test/renderable/test_grid.cpp similarity index 96% rename from src/gldraw/test/renderable/test_grid.cpp rename to src/scene/test/renderable/test_grid.cpp index fe8eb8d..a19739c 100644 --- a/src/gldraw/test/renderable/test_grid.cpp +++ b/src/scene/test/renderable/test_grid.cpp @@ -12,8 +12,8 @@ #include #include -#include "gldraw/gl_viewer.hpp" -#include "gldraw/renderable/grid.hpp" +#include "scene/scene_app.hpp" +#include "scene/renderable/grid.hpp" using namespace quickviz; @@ -46,13 +46,13 @@ void SetupGridScene(SceneManager* scene_manager) { int main(int argc, char* argv[]) { try { // Configure the view for 3D mode - GlViewer::Config config; + SceneApp::Config config; config.window_title = "Grid Rendering Test"; config.coordinate_frame_size = 2.0f; config.show_grid = false; // We'll add our own grids // Create the view - GlViewer view(config); + SceneApp view(config); // Set up description and help sections view.SetDescription("Testing grid rendering with various sizes, steps, and colors"); diff --git a/src/gldraw/test/renderable/test_line_strip.cpp b/src/scene/test/renderable/test_line_strip.cpp similarity index 97% rename from src/gldraw/test/renderable/test_line_strip.cpp rename to src/scene/test/renderable/test_line_strip.cpp index d4b8c20..4624081 100644 --- a/src/gldraw/test/renderable/test_line_strip.cpp +++ b/src/scene/test/renderable/test_line_strip.cpp @@ -12,8 +12,8 @@ #include #include -#include "gldraw/gl_viewer.hpp" -#include "gldraw/renderable/line_strip.hpp" +#include "scene/scene_app.hpp" +#include "scene/renderable/line_strip.hpp" using namespace quickviz; @@ -108,12 +108,12 @@ void SetupLineStripScene(SceneManager* scene_manager) { int main(int argc, char* argv[]) { try { // Configure the view for 3D mode - GlViewer::Config config; + SceneApp::Config config; config.window_title = "LineStrip Rendering Test"; config.coordinate_frame_size = 2.0f; // Create the view - GlViewer view(config); + SceneApp view(config); // Set up description and help sections view.SetDescription("Testing line strip rendering for paths, trajectories, and continuous curves"); diff --git a/src/gldraw/test/renderable/test_mesh.cpp b/src/scene/test/renderable/test_mesh.cpp similarity index 98% rename from src/gldraw/test/renderable/test_mesh.cpp rename to src/scene/test/renderable/test_mesh.cpp index d361274..31e5471 100644 --- a/src/gldraw/test/renderable/test_mesh.cpp +++ b/src/scene/test/renderable/test_mesh.cpp @@ -12,8 +12,8 @@ #include #include -#include "gldraw/gl_viewer.hpp" -#include "gldraw/renderable/mesh.hpp" +#include "scene/scene_app.hpp" +#include "scene/renderable/mesh.hpp" using namespace quickviz; @@ -179,12 +179,12 @@ void SetupMeshScene(SceneManager* scene_manager) { int main(int argc, char* argv[]) { try { // Configure the view for 3D mode - GlViewer::Config config; + SceneApp::Config config; config.window_title = "Mesh Rendering Test"; config.coordinate_frame_size = 2.0f; // Create the view - GlViewer view(config); + SceneApp view(config); // Set up description and help sections view.SetDescription("Testing mesh rendering with various shapes, materials, and rendering modes"); diff --git a/src/scene/test/renderable/test_occupancy_grid.cpp b/src/scene/test/renderable/test_occupancy_grid.cpp new file mode 100644 index 0000000..49de779 --- /dev/null +++ b/src/scene/test/renderable/test_occupancy_grid.cpp @@ -0,0 +1,98 @@ +/** + * @file test_occupancy_grid.cpp + * @brief Visual test for the OccupancyGrid renderable + * + * Renders a 50x50 occupancy grid with a hand-crafted pattern that + * exercises all three cell states (free, occupied, unknown). Run and + * inspect: + * + * - Outer frame of black (occupied) cells. + * - Inner light-gray (free) field with a diagonal corridor of + * intermediate occupancy values. + * - A square patch of unknown (medium gray) cells in the lower-left. + * + * Copyright (c) 2026 Ruixiang Du (rdu) + */ + +#include +#include +#include + +#include + +#include "scene/renderable/grid.hpp" +#include "scene/renderable/occupancy_grid.hpp" +#include "scene/scene_app.hpp" + +using namespace quickviz; + +namespace { + +constexpr uint32_t kWidth = 50; +constexpr uint32_t kHeight = 50; +constexpr float kResolution = 0.2f; // 0.2m per cell → 10m × 10m grid + +std::vector BuildPattern() { + std::vector data(kWidth * kHeight, 0); // free everywhere + + for (uint32_t y = 0; y < kHeight; ++y) { + for (uint32_t x = 0; x < kWidth; ++x) { + const std::size_t idx = y * kWidth + x; + + // Outer one-cell border: occupied. + if (x == 0 || y == 0 || x == kWidth - 1 || y == kHeight - 1) { + data[idx] = 100; + } + + // Diagonal corridor with intermediate occupancy values. + if (x == y) { + data[idx] = 50; + } + + // Lower-left square of unknown cells. + if (x < 12 && y < 12 && (x > 0 && y > 0)) { + data[idx] = -1; + } + } + } + return data; +} + +} // namespace + +void Setup(SceneManager* scene) { + // Reference grid at the same resolution / extent so the cells line up + // with the world axes for easy visual verification. + auto reference = std::make_unique( + static_cast(kWidth) * kResolution, kResolution, + glm::vec3(0.6f, 0.6f, 0.6f)); + scene->AddOpenGLObject("grid", std::move(reference)); + + auto og = std::make_unique(); + // Origin chosen so the centre of the grid sits at world origin. + const float half_w = 0.5f * static_cast(kWidth) * kResolution; + const float half_h = 0.5f * static_cast(kHeight) * kResolution; + og->SetGrid(kWidth, kHeight, kResolution, + glm::vec3(-half_w, -half_h, 0.0f), BuildPattern()); + scene->AddOpenGLObject("occupancy_grid", std::move(og)); +} + +int main() { + try { + SceneApp::Config config; + config.window_title = "OccupancyGrid Rendering Test"; + config.show_grid = false; // we add our own at the matching resolution + + SceneApp view(config); + view.SetDescription( + "OccupancyGrid: 50x50 cells at 0.2m resolution. Outer frame " + "occupied (black), interior free (light gray), diagonal " + "intermediate, lower-left corner unknown (medium gray)."); + view.SetSceneSetup(Setup); + view.Run(); + } catch (const std::exception& e) { + std::cerr << "Error: " << e.what() << std::endl; + return 1; + } + return 0; +} diff --git a/src/gldraw/test/renderable/test_path.cpp b/src/scene/test/renderable/test_path.cpp similarity index 88% rename from src/gldraw/test/renderable/test_path.cpp rename to src/scene/test/renderable/test_path.cpp index ffa7915..ee29a0b 100644 --- a/src/gldraw/test/renderable/test_path.cpp +++ b/src/scene/test/renderable/test_path.cpp @@ -14,10 +14,11 @@ #include #include +#include -#include "gldraw/gl_viewer.hpp" -#include "gldraw/renderable/path.hpp" -#include "gldraw/renderable/grid.hpp" +#include "scene/scene_app.hpp" +#include "scene/renderable/path.hpp" +#include "scene/renderable/grid.hpp" using namespace quickviz; @@ -183,17 +184,42 @@ void SetupPathScene(SceneManager* scene_manager) { path8->SetTransparency(0.4f); // Semi-transparent path8->SetGlowEffect(true, 0.8f); scene_manager->AddOpenGLObject("path_transparent", std::move(path8)); + + // 9. Oriented trajectory (pose-aware): same shape as a path but + // each waypoint carries a full quaternion. Arrows are oriented + // by the per-point pose, not the path tangent — useful when the + // object's heading differs from its travel direction (parallel + // parking, drone yaw, manipulator end-effector). + auto path9 = std::make_unique(); + path9->SetPathType(Path::PathType::kLineSegments); + path9->SetLineWidth(2.0f); + path9->SetColor(glm::vec3(0.7f, 0.85f, 1.0f)); + path9->SetArrowMode(Path::ArrowMode::kPoseArrows); + path9->SetArrowSize(0.3f); + path9->SetArrowColor(glm::vec3(0.9f, 0.5f, 0.1f)); + + // 6 poses along an arc; orientations sweep the heading from +X + // (yaw=0) to roughly +Y (yaw=90°) so the arrows fan out. + const int n = 6; + for (int i = 0; i < n; ++i) { + const float t = static_cast(i) / static_cast(n - 1); + const glm::vec3 pos(-3.0f + 6.0f * t, -4.0f, 2.0f); + const float yaw = glm::radians(t * 90.0f); + const glm::quat q = glm::angleAxis(yaw, glm::vec3(0, 0, 1)); + path9->AddPoint(pos, q); + } + scene_manager->AddOpenGLObject("path_oriented_trajectory", std::move(path9)); } int main(int argc, char* argv[]) { try { // Configure the view for 3D mode - GlViewer::Config config; + SceneApp::Config config; config.window_title = "Path Rendering Test"; config.coordinate_frame_size = 2.0f; // Create the view - GlViewer view(config); + SceneApp view(config); // Set up description and help sections view.SetDescription("Testing path rendering for trajectory and motion planning visualization"); diff --git a/src/gldraw/test/renderable/test_plane.cpp b/src/scene/test/renderable/test_plane.cpp similarity index 97% rename from src/gldraw/test/renderable/test_plane.cpp rename to src/scene/test/renderable/test_plane.cpp index 57786cb..a7a1098 100644 --- a/src/gldraw/test/renderable/test_plane.cpp +++ b/src/scene/test/renderable/test_plane.cpp @@ -15,10 +15,10 @@ #include #include -#include "gldraw/gl_viewer.hpp" -#include "gldraw/renderable/plane.hpp" -#include "gldraw/renderable/grid.hpp" -#include "gldraw/renderable/coordinate_frame.hpp" +#include "scene/scene_app.hpp" +#include "scene/renderable/plane.hpp" +#include "scene/renderable/grid.hpp" +#include "scene/renderable/coordinate_frame.hpp" using namespace quickviz; @@ -142,12 +142,12 @@ void SetupPlaneScene(SceneManager* scene_manager) { int main(int argc, char* argv[]) { try { // Configure the view for 3D mode - GlViewer::Config config; + SceneApp::Config config; config.window_title = "Plane Rendering Test"; config.coordinate_frame_size = 2.0f; // Create the view - GlViewer view(config); + SceneApp view(config); // Set up description and help sections view.SetDescription("Testing plane rendering with various orientations and visualization modes"); diff --git a/src/gldraw/test/renderable/test_point_cloud.cpp b/src/scene/test/renderable/test_point_cloud.cpp similarity index 97% rename from src/gldraw/test/renderable/test_point_cloud.cpp rename to src/scene/test/renderable/test_point_cloud.cpp index 20e9cd4..22cb81e 100644 --- a/src/gldraw/test/renderable/test_point_cloud.cpp +++ b/src/scene/test/renderable/test_point_cloud.cpp @@ -14,8 +14,8 @@ #include #include -#include "gldraw/gl_viewer.hpp" -#include "gldraw/renderable/point_cloud.hpp" +#include "scene/scene_app.hpp" +#include "scene/renderable/point_cloud.hpp" using namespace quickviz; @@ -86,12 +86,12 @@ void SetupPointCloudScene(SceneManager* scene_manager) { int main(int argc, char* argv[]) { try { // Configure the view for 3D mode - GlViewer::Config config; + SceneApp::Config config; config.window_title = "PointCloud Rendering Test"; config.coordinate_frame_size = 2.0f; // Create the view - GlViewer view(config); + SceneApp view(config); // Set up description and help sections view.SetDescription("Testing point cloud rendering with various patterns and coloring schemes"); diff --git a/src/gldraw/test/renderable/test_pose.cpp b/src/scene/test/renderable/test_pose.cpp similarity index 98% rename from src/gldraw/test/renderable/test_pose.cpp rename to src/scene/test/renderable/test_pose.cpp index a36d6af..040c76a 100644 --- a/src/gldraw/test/renderable/test_pose.cpp +++ b/src/scene/test/renderable/test_pose.cpp @@ -16,9 +16,9 @@ #include #include -#include "gldraw/gl_viewer.hpp" -#include "gldraw/renderable/pose.hpp" -#include "gldraw/renderable/grid.hpp" +#include "scene/scene_app.hpp" +#include "scene/renderable/pose.hpp" +#include "scene/renderable/grid.hpp" using namespace quickviz; @@ -136,12 +136,12 @@ void SetupPoseScene(SceneManager* scene_manager) { int main(int argc, char* argv[]) { try { // Configure the view for 3D mode - GlViewer::Config config; + SceneApp::Config config; config.window_title = "Pose Rendering Test"; config.coordinate_frame_size = 2.0f; // Create the view - GlViewer view(config); + SceneApp view(config); // Set up description and help sections view.SetDescription("Testing 6-DOF pose visualization with coordinate frames and history trails"); diff --git a/src/gldraw/test/renderable/test_sphere.cpp b/src/scene/test/renderable/test_sphere.cpp similarity index 96% rename from src/gldraw/test/renderable/test_sphere.cpp rename to src/scene/test/renderable/test_sphere.cpp index 7bf3fc2..242f6c1 100644 --- a/src/gldraw/test/renderable/test_sphere.cpp +++ b/src/scene/test/renderable/test_sphere.cpp @@ -11,8 +11,8 @@ #include #include -#include "gldraw/gl_viewer.hpp" -#include "gldraw/renderable/sphere.hpp" +#include "scene/scene_app.hpp" +#include "scene/renderable/sphere.hpp" using namespace quickviz; @@ -52,12 +52,12 @@ void SetupSphereScene(SceneManager* scene_manager) { int main(int argc, char* argv[]) { try { // Configure the view for 3D mode - GlViewer::Config config; + SceneApp::Config config; config.window_title = "Sphere Rendering Test"; config.coordinate_frame_size = 2.0f; // Create the view - GlViewer view(config); + SceneApp view(config); // Set up description and help sections view.SetDescription("Testing sphere rendering with various sizes, colors, and rendering modes"); diff --git a/src/gldraw/test/renderable/test_texture.cpp b/src/scene/test/renderable/test_texture.cpp similarity index 98% rename from src/gldraw/test/renderable/test_texture.cpp rename to src/scene/test/renderable/test_texture.cpp index 5d7bfc3..1f61506 100644 --- a/src/gldraw/test/renderable/test_texture.cpp +++ b/src/scene/test/renderable/test_texture.cpp @@ -19,8 +19,8 @@ #include #include -#include "gldraw/gl_viewer.hpp" -#include "gldraw/renderable/texture.hpp" +#include "scene/scene_app.hpp" +#include "scene/renderable/texture.hpp" #include "core/buffer/buffer_registry.hpp" #include "core/buffer/ring_buffer.hpp" @@ -145,13 +145,13 @@ void SetupTextureScene(SceneManager* scene_manager) { int main(int argc, char* argv[]) { try { // Configure the view for 2D mode - GlViewer::Config config; + SceneApp::Config config; config.window_title = "Texture Rendering Test - 2D Mode"; config.scene_mode = SceneManager::Mode::k2D; config.coordinate_frame_size = 2.0f; // Create the view - GlViewer view(config); + SceneApp view(config); // Set up description and help sections view.SetDescription("Testing dynamic texture rendering with animated patterns"); diff --git a/src/scene/test/renderable/test_tf_frame_tree.cpp b/src/scene/test/renderable/test_tf_frame_tree.cpp new file mode 100644 index 0000000..4c89d68 --- /dev/null +++ b/src/scene/test/renderable/test_tf_frame_tree.cpp @@ -0,0 +1,112 @@ +/** + * @file test_tf_frame_tree.cpp + * @brief Visual test for TfFrameTree + * + * Builds a small robot-like kinematics tree and animates the joints + * over time so the parent-child relationships are visible. Run and + * inspect: + * + * - Six axis triplets (RGB) at: + * world (origin), base, lidar, arm_base, arm_link_1, arm_tip + * - Gray lines connecting parents to children, showing tree topology + * - Smooth animation of the arm and base over time + * + * Copyright (c) 2026 Ruixiang Du (rdu) + */ + +#include +#include +#include +#include + +#include +#include + +#include "scene/renderable/grid.hpp" +#include "scene/renderable/tf_frame_tree.hpp" +#include "scene/scene_app.hpp" + +using namespace quickviz; + +namespace { + +glm::mat4 Translation(const glm::vec3& t) { + return glm::translate(glm::mat4(1.0f), t); +} + +glm::mat4 RotZ(float angle) { + return glm::rotate(glm::mat4(1.0f), angle, glm::vec3(0.0f, 0.0f, 1.0f)); +} + +} // namespace + +int main() { + try { + SceneApp::Config config; + config.window_title = "TfFrameTree Rendering Test"; + SceneApp view(config); + + view.SetDescription( + "Six-frame robot kinematics tree with animated joints. Each " + "frame draws as RGB axes; gray lines connect parents to children."); + + // Capture by reference into the lambda; SceneApp keeps it alive. + TfFrameTree* tree_ptr = nullptr; + + view.SetSceneSetup([&tree_ptr](SceneManager* scene) { + auto reference = std::make_unique(8.0f, 0.5f, + glm::vec3(0.6f, 0.6f, 0.6f)); + scene->AddOpenGLObject("grid", std::move(reference)); + + auto tree = std::make_unique(/*axis_length=*/0.4f); + + // Static parts of the tree. + tree->SetFrame("world", "", glm::mat4(1.0f)); + tree->SetFrame("base", "world", + Translation(glm::vec3(1.0f, 1.0f, 0.0f)) * RotZ(0.0f)); + tree->SetFrame("lidar", "base", + Translation(glm::vec3(0.3f, 0.0f, 0.4f))); + tree->SetFrame("arm_base", "base", + Translation(glm::vec3(0.0f, 0.0f, 0.5f))); + tree->SetFrame("arm_link_1", "arm_base", + Translation(glm::vec3(0.5f, 0.0f, 0.0f))); + tree->SetFrame("arm_tip", "arm_link_1", + Translation(glm::vec3(0.5f, 0.0f, 0.0f))); + + tree_ptr = tree.get(); + scene->AddOpenGLObject("tf_tree", std::move(tree)); + + // Animate base yaw + arm joint angles each frame. + const auto t0 = std::chrono::steady_clock::now(); + scene->SetPreDrawCallback([&tree_ptr, t0]() { + if (!tree_ptr) return; + const float t = std::chrono::duration( + std::chrono::steady_clock::now() - t0).count(); + + // Base spins slowly. + tree_ptr->SetFrame( + "base", "world", + Translation(glm::vec3(1.0f, 1.0f, 0.0f)) * RotZ(0.3f * t)); + + // Arm shoulder oscillates. + tree_ptr->SetFrame( + "arm_link_1", "arm_base", + RotZ(0.6f * std::sin(1.2f * t)) * + Translation(glm::vec3(0.5f, 0.0f, 0.0f))); + + // Arm tip rotates a bit too — grandchildren update without + // restating the chain because GetWorldTransform walks parents. + tree_ptr->SetFrame( + "arm_tip", "arm_link_1", + RotZ(0.8f * std::cos(1.5f * t)) * + Translation(glm::vec3(0.5f, 0.0f, 0.0f))); + }); + }); + + view.Run(); + } catch (const std::exception& e) { + std::cerr << "Error: " << e.what() << std::endl; + return 1; + } + return 0; +} diff --git a/src/gldraw/test/renderable/test_triangle.cpp b/src/scene/test/renderable/test_triangle.cpp similarity index 97% rename from src/gldraw/test/renderable/test_triangle.cpp rename to src/scene/test/renderable/test_triangle.cpp index 546f9f3..06732b7 100644 --- a/src/gldraw/test/renderable/test_triangle.cpp +++ b/src/scene/test/renderable/test_triangle.cpp @@ -15,8 +15,8 @@ #include #include -#include "gldraw/gl_viewer.hpp" -#include "gldraw/renderable/triangle.hpp" +#include "scene/scene_app.hpp" +#include "test_utils/triangle.hpp" using namespace quickviz; @@ -85,14 +85,14 @@ void SetupTriangleScene(SceneManager* scene_manager) { int main(int argc, char* argv[]) { try { // Configure the view for 2D mode - GlViewer::Config config; + SceneApp::Config config; config.window_title = "Triangle Rendering Test - 2D Mode"; config.scene_mode = SceneManager::Mode::k2D; // Set 2D mode config.show_grid = true; // Disable grid for cleaner 2D view config.show_coordinate_frame = true; // Disable 3D coordinate frame // Create the view - GlViewer view(config); + SceneApp view(config); // Set up description and help sections view.SetDescription("Testing triangle rendering in 2D mode for shapes and UI elements"); diff --git a/src/gldraw/test/selection/CMakeLists.txt b/src/scene/test/selection/CMakeLists.txt similarity index 93% rename from src/gldraw/test/selection/CMakeLists.txt rename to src/scene/test/selection/CMakeLists.txt index 3335e29..af3180b 100644 --- a/src/gldraw/test/selection/CMakeLists.txt +++ b/src/scene/test/selection/CMakeLists.txt @@ -5,11 +5,11 @@ # Shared utilities for all selection tests add_library(selection_test_utils selection_test_utils.cpp selection_test_utils.hpp) -target_link_libraries(selection_test_utils PUBLIC gldraw) +target_link_libraries(selection_test_utils PUBLIC scene) # Original comprehensive test (kept for backward compatibility) #add_executable(test_object_selection test_object_selection.cpp) -#target_link_libraries(test_object_selection PRIVATE gldraw) +#target_link_libraries(test_object_selection PRIVATE scene) # Individual object type selection tests add_executable(test_sphere_selection test_sphere_selection.cpp) diff --git a/src/gldraw/test/selection/README.md b/src/scene/test/selection/README.md similarity index 100% rename from src/gldraw/test/selection/README.md rename to src/scene/test/selection/README.md diff --git a/src/gldraw/test/selection/selection_test_utils.cpp b/src/scene/test/selection/selection_test_utils.cpp similarity index 98% rename from src/gldraw/test/selection/selection_test_utils.cpp rename to src/scene/test/selection/selection_test_utils.cpp index e0b319a..3a68764 100644 --- a/src/gldraw/test/selection/selection_test_utils.cpp +++ b/src/scene/test/selection/selection_test_utils.cpp @@ -13,13 +13,13 @@ #include #include -#include "gldraw/feedback/visual_feedback_system.hpp" +#include "scene/feedback/visual_feedback_system.hpp" -#include "gldraw/renderable/sphere.hpp" -#include "gldraw/renderable/point_cloud.hpp" -#include "gldraw/renderable/line_strip.hpp" -#include "gldraw/renderable/cylinder.hpp" -#include "gldraw/renderable/mesh.hpp" +#include "scene/renderable/sphere.hpp" +#include "scene/renderable/point_cloud.hpp" +#include "scene/renderable/line_strip.hpp" +#include "scene/renderable/cylinder.hpp" +#include "scene/renderable/mesh.hpp" namespace quickviz { namespace selection_test_utils { diff --git a/src/gldraw/test/selection/selection_test_utils.hpp b/src/scene/test/selection/selection_test_utils.hpp similarity index 96% rename from src/gldraw/test/selection/selection_test_utils.hpp rename to src/scene/test/selection/selection_test_utils.hpp index 288701d..5a2c605 100644 --- a/src/gldraw/test/selection/selection_test_utils.hpp +++ b/src/scene/test/selection/selection_test_utils.hpp @@ -21,14 +21,14 @@ #include #include -#include "imview/viewer.hpp" -#include "imview/box.hpp" -#include "imview/panel.hpp" -#include "imview/styling.hpp" - -#include "gldraw/gl_scene_panel.hpp" -#include "gldraw/selection_manager.hpp" -#include "gldraw/renderable/grid.hpp" +#include "viewer/viewer.hpp" +#include "viewer/box.hpp" +#include "viewer/panel.hpp" +#include "viewer/styling.hpp" + +#include "scene/gl_scene_panel.hpp" +#include "scene/selection_manager.hpp" +#include "scene/renderable/grid.hpp" namespace quickviz { namespace selection_test_utils { diff --git a/src/gldraw/test/selection/test_bounding_box_selection.cpp b/src/scene/test/selection/test_bounding_box_selection.cpp similarity index 99% rename from src/gldraw/test/selection/test_bounding_box_selection.cpp rename to src/scene/test/selection/test_bounding_box_selection.cpp index 23f077b..0d1c1b8 100644 --- a/src/gldraw/test/selection/test_bounding_box_selection.cpp +++ b/src/scene/test/selection/test_bounding_box_selection.cpp @@ -15,7 +15,7 @@ */ #include "selection_test_utils.hpp" -#include "gldraw/renderable/bounding_box.hpp" +#include "scene/renderable/bounding_box.hpp" #include #include diff --git a/src/gldraw/test/selection/test_comprehensive_selection.cpp b/src/scene/test/selection/test_comprehensive_selection.cpp similarity index 98% rename from src/gldraw/test/selection/test_comprehensive_selection.cpp rename to src/scene/test/selection/test_comprehensive_selection.cpp index 0fa2e91..121298c 100644 --- a/src/gldraw/test/selection/test_comprehensive_selection.cpp +++ b/src/scene/test/selection/test_comprehensive_selection.cpp @@ -16,10 +16,10 @@ */ #include "selection_test_utils.hpp" -#include "gldraw/renderable/sphere.hpp" -#include "gldraw/renderable/point_cloud.hpp" -#include "gldraw/renderable/line_strip.hpp" -#include "gldraw/feedback/visual_feedback_system.hpp" +#include "scene/renderable/sphere.hpp" +#include "scene/renderable/point_cloud.hpp" +#include "scene/renderable/line_strip.hpp" +#include "scene/feedback/visual_feedback_system.hpp" #include "core/event/input_event.hpp" #include #include diff --git a/src/gldraw/test/selection/test_cylinder_selection.cpp b/src/scene/test/selection/test_cylinder_selection.cpp similarity index 99% rename from src/gldraw/test/selection/test_cylinder_selection.cpp rename to src/scene/test/selection/test_cylinder_selection.cpp index 6aa7245..4ee790c 100644 --- a/src/gldraw/test/selection/test_cylinder_selection.cpp +++ b/src/scene/test/selection/test_cylinder_selection.cpp @@ -15,7 +15,7 @@ */ #include "selection_test_utils.hpp" -#include "gldraw/renderable/cylinder.hpp" +#include "scene/renderable/cylinder.hpp" #include #include diff --git a/src/gldraw/test/selection/test_id_buffer_debug.cpp b/src/scene/test/selection/test_id_buffer_debug.cpp similarity index 98% rename from src/gldraw/test/selection/test_id_buffer_debug.cpp rename to src/scene/test/selection/test_id_buffer_debug.cpp index 8bd9848..a883cd2 100644 --- a/src/gldraw/test/selection/test_id_buffer_debug.cpp +++ b/src/scene/test/selection/test_id_buffer_debug.cpp @@ -11,7 +11,7 @@ */ #include "selection_test_utils.hpp" -#include "gldraw/renderable/point_cloud.hpp" +#include "scene/renderable/point_cloud.hpp" #include #include diff --git a/src/gldraw/test/selection/test_line_strip_selection.cpp b/src/scene/test/selection/test_line_strip_selection.cpp similarity index 99% rename from src/gldraw/test/selection/test_line_strip_selection.cpp rename to src/scene/test/selection/test_line_strip_selection.cpp index 6475a93..0ced693 100644 --- a/src/gldraw/test/selection/test_line_strip_selection.cpp +++ b/src/scene/test/selection/test_line_strip_selection.cpp @@ -14,7 +14,7 @@ */ #include "selection_test_utils.hpp" -#include "gldraw/renderable/line_strip.hpp" +#include "scene/renderable/line_strip.hpp" #include #include diff --git a/src/gldraw/test/selection/test_mesh_selection.cpp b/src/scene/test/selection/test_mesh_selection.cpp similarity index 99% rename from src/gldraw/test/selection/test_mesh_selection.cpp rename to src/scene/test/selection/test_mesh_selection.cpp index 3bd7878..254679f 100644 --- a/src/gldraw/test/selection/test_mesh_selection.cpp +++ b/src/scene/test/selection/test_mesh_selection.cpp @@ -14,7 +14,7 @@ */ #include "selection_test_utils.hpp" -#include "gldraw/renderable/mesh.hpp" +#include "scene/renderable/mesh.hpp" #include #include diff --git a/src/gldraw/test/selection/test_object_selection.cpp b/src/scene/test/selection/test_object_selection.cpp similarity index 98% rename from src/gldraw/test/selection/test_object_selection.cpp rename to src/scene/test/selection/test_object_selection.cpp index 786ba7b..de67b58 100644 --- a/src/gldraw/test/selection/test_object_selection.cpp +++ b/src/scene/test/selection/test_object_selection.cpp @@ -14,16 +14,16 @@ #include #include -#include "imview/viewer.hpp" -#include "imview/box.hpp" -#include "imview/panel.hpp" -#include "imview/styling.hpp" - -#include "gldraw/gl_scene_panel.hpp" -#include "gldraw/renderable/point_cloud.hpp" -#include "gldraw/renderable/sphere.hpp" -#include "gldraw/renderable/grid.hpp" -#include "gldraw/selection_manager.hpp" +#include "viewer/viewer.hpp" +#include "viewer/box.hpp" +#include "viewer/panel.hpp" +#include "viewer/styling.hpp" + +#include "scene/gl_scene_panel.hpp" +#include "scene/renderable/point_cloud.hpp" +#include "scene/renderable/sphere.hpp" +#include "scene/renderable/grid.hpp" +#include "scene/selection_manager.hpp" using namespace quickviz; diff --git a/src/gldraw/test/selection/test_point_cloud_selection.cpp b/src/scene/test/selection/test_point_cloud_selection.cpp similarity index 99% rename from src/gldraw/test/selection/test_point_cloud_selection.cpp rename to src/scene/test/selection/test_point_cloud_selection.cpp index b69d0cc..6d7b2a3 100644 --- a/src/gldraw/test/selection/test_point_cloud_selection.cpp +++ b/src/scene/test/selection/test_point_cloud_selection.cpp @@ -14,7 +14,7 @@ */ #include "selection_test_utils.hpp" -#include "gldraw/renderable/point_cloud.hpp" +#include "scene/renderable/point_cloud.hpp" #include #include diff --git a/src/gldraw/test/selection/test_sphere_selection.cpp b/src/scene/test/selection/test_sphere_selection.cpp similarity index 99% rename from src/gldraw/test/selection/test_sphere_selection.cpp rename to src/scene/test/selection/test_sphere_selection.cpp index b5ce29b..d6add69 100644 --- a/src/gldraw/test/selection/test_sphere_selection.cpp +++ b/src/scene/test/selection/test_sphere_selection.cpp @@ -14,7 +14,7 @@ */ #include "selection_test_utils.hpp" -#include "gldraw/renderable/sphere.hpp" +#include "scene/renderable/sphere.hpp" #include using namespace quickviz; diff --git a/src/gldraw/test/test_camera_raw.cpp b/src/scene/test/test_camera_raw.cpp similarity index 96% rename from src/gldraw/test/test_camera_raw.cpp rename to src/scene/test/test_camera_raw.cpp index baf24af..d33b4e7 100644 --- a/src/gldraw/test/test_camera_raw.cpp +++ b/src/scene/test/test_camera_raw.cpp @@ -13,11 +13,11 @@ #include #include "glad/glad.h" -#include "imview/window.hpp" +#include "viewer/window.hpp" -#include "gldraw/renderable/grid.hpp" -#include "gldraw/camera.hpp" -#include "gldraw/camera_controller.hpp" +#include "scene/renderable/grid.hpp" +#include "scene/camera.hpp" +#include "scene/camera_controller.hpp" using namespace quickviz; diff --git a/src/gldraw/test/test_canvas_st.cpp b/src/scene/test/test_canvas_st.cpp similarity index 95% rename from src/gldraw/test/test_canvas_st.cpp rename to src/scene/test/test_canvas_st.cpp index cef3101..e5adc85 100644 --- a/src/gldraw/test/test_canvas_st.cpp +++ b/src/scene/test/test_canvas_st.cpp @@ -14,14 +14,14 @@ #include #include -#include "imview/box.hpp" -#include "imview/viewer.hpp" - -#include "gldraw/gl_scene_panel.hpp" -#include "gldraw/renderable/grid.hpp" -#include "gldraw/renderable/triangle.hpp" -#include "gldraw/renderable/coordinate_frame.hpp" -#include "gldraw/renderable/canvas.hpp" +#include "viewer/box.hpp" +#include "viewer/viewer.hpp" + +#include "scene/gl_scene_panel.hpp" +#include "scene/renderable/grid.hpp" +#include "test_utils/triangle.hpp" +#include "scene/renderable/coordinate_frame.hpp" +#include "scene/renderable/canvas.hpp" using namespace quickviz; namespace fs = std::filesystem; diff --git a/src/gldraw/test/test_coordinate_system.cpp b/src/scene/test/test_coordinate_system.cpp similarity index 94% rename from src/gldraw/test/test_coordinate_system.cpp rename to src/scene/test/test_coordinate_system.cpp index a6fa318..efa21f3 100644 --- a/src/gldraw/test/test_coordinate_system.cpp +++ b/src/scene/test/test_coordinate_system.cpp @@ -14,13 +14,13 @@ #include #include -#include "imview/box.hpp" -#include "imview/viewer.hpp" +#include "viewer/box.hpp" +#include "viewer/viewer.hpp" -#include "gldraw/gl_scene_panel.hpp" -#include "gldraw/coordinate_transformer.hpp" -#include "gldraw/renderable/grid.hpp" -#include "gldraw/renderable/coordinate_frame.hpp" +#include "scene/gl_scene_panel.hpp" +#include "scene/coordinate_transformer.hpp" +#include "scene/renderable/grid.hpp" +#include "scene/renderable/coordinate_frame.hpp" using namespace quickviz; diff --git a/src/gldraw/test/test_font_renderer.cpp b/src/scene/test/test_font_renderer.cpp similarity index 99% rename from src/gldraw/test/test_font_renderer.cpp rename to src/scene/test/test_font_renderer.cpp index b8e6438..ca58cc7 100644 --- a/src/gldraw/test/test_font_renderer.cpp +++ b/src/scene/test/test_font_renderer.cpp @@ -17,7 +17,7 @@ #include #include -#include "gldraw/font_renderer.hpp" +#include "scene/font_renderer.hpp" using namespace quickviz; diff --git a/src/gldraw/test/test_framebuffer.cpp b/src/scene/test/test_framebuffer.cpp similarity index 98% rename from src/gldraw/test/test_framebuffer.cpp rename to src/scene/test/test_framebuffer.cpp index 8f49d97..0ec81a2 100644 --- a/src/gldraw/test/test_framebuffer.cpp +++ b/src/scene/test/test_framebuffer.cpp @@ -10,8 +10,8 @@ #include #include "glad/glad.h" -#include "imview/window.hpp" -#include "gldraw/frame_buffer.hpp" +#include "viewer/window.hpp" +#include "scene/frame_buffer.hpp" using namespace quickviz; diff --git a/src/gldraw/test/test_layer_system_box.cpp b/src/scene/test/test_layer_system_box.cpp similarity index 96% rename from src/gldraw/test/test_layer_system_box.cpp rename to src/scene/test/test_layer_system_box.cpp index 6a82f98..1d72f08 100644 --- a/src/gldraw/test/test_layer_system_box.cpp +++ b/src/scene/test/test_layer_system_box.cpp @@ -12,12 +12,12 @@ #include #include -#include "imview/viewer.hpp" -#include "imview/box.hpp" -#include "gldraw/gl_scene_panel.hpp" -#include "gldraw/renderable/grid.hpp" -#include "gldraw/renderable/point_cloud.hpp" -#include "../include/gldraw/renderable/details/point_layer_manager.hpp" +#include "viewer/viewer.hpp" +#include "viewer/box.hpp" +#include "scene/gl_scene_panel.hpp" +#include "scene/renderable/grid.hpp" +#include "scene/renderable/point_cloud.hpp" +#include "../include/scene/renderable/details/point_layer_manager.hpp" using namespace quickviz; diff --git a/src/gldraw/test/test_nav_map_rendering.cpp b/src/scene/test/test_nav_map_rendering.cpp similarity index 96% rename from src/gldraw/test/test_nav_map_rendering.cpp rename to src/scene/test/test_nav_map_rendering.cpp index 4065a9a..e2dfd45 100644 --- a/src/gldraw/test/test_nav_map_rendering.cpp +++ b/src/scene/test/test_nav_map_rendering.cpp @@ -14,14 +14,14 @@ #include #include -#include "imview/box.hpp" -#include "imview/viewer.hpp" - -#include "gldraw/gl_scene_panel.hpp" -#include "gldraw/renderable/grid.hpp" -#include "gldraw/renderable/triangle.hpp" -#include "gldraw/renderable/coordinate_frame.hpp" -#include "gldraw/renderable/canvas.hpp" +#include "viewer/box.hpp" +#include "viewer/viewer.hpp" + +#include "scene/gl_scene_panel.hpp" +#include "scene/renderable/grid.hpp" +#include "test_utils/triangle.hpp" +#include "scene/renderable/coordinate_frame.hpp" +#include "scene/renderable/canvas.hpp" using namespace quickviz; namespace fs = std::filesystem; diff --git a/src/gldraw/test/test_point_cloud_buffer_strategies.cpp b/src/scene/test/test_point_cloud_buffer_strategies.cpp similarity index 98% rename from src/gldraw/test/test_point_cloud_buffer_strategies.cpp rename to src/scene/test/test_point_cloud_buffer_strategies.cpp index 24bef10..9a7a808 100644 --- a/src/gldraw/test/test_point_cloud_buffer_strategies.cpp +++ b/src/scene/test/test_point_cloud_buffer_strategies.cpp @@ -22,12 +22,12 @@ #include #include -#include "imview/box.hpp" -#include "imview/viewer.hpp" +#include "viewer/box.hpp" +#include "viewer/viewer.hpp" -#include "gldraw/gl_scene_panel.hpp" -#include "gldraw/renderable/grid.hpp" -#include "gldraw/renderable/point_cloud.hpp" +#include "scene/gl_scene_panel.hpp" +#include "scene/renderable/grid.hpp" +#include "scene/renderable/point_cloud.hpp" using namespace quickviz; diff --git a/src/gldraw/test/test_point_cloud_realtime.cpp b/src/scene/test/test_point_cloud_realtime.cpp similarity index 96% rename from src/gldraw/test/test_point_cloud_realtime.cpp rename to src/scene/test/test_point_cloud_realtime.cpp index 0633983..70fb654 100644 --- a/src/gldraw/test/test_point_cloud_realtime.cpp +++ b/src/scene/test/test_point_cloud_realtime.cpp @@ -17,12 +17,12 @@ #include #include -#include "imview/box.hpp" -#include "imview/viewer.hpp" +#include "viewer/box.hpp" +#include "viewer/viewer.hpp" -#include "gldraw/gl_scene_panel.hpp" -#include "gldraw/renderable/grid.hpp" -#include "gldraw/renderable/point_cloud.hpp" +#include "scene/gl_scene_panel.hpp" +#include "scene/renderable/grid.hpp" +#include "scene/renderable/point_cloud.hpp" #include "core/buffer/buffer_registry.hpp" #include "core/buffer/ring_buffer.hpp" diff --git a/src/gldraw/test/test_primitive_drawing.cpp b/src/scene/test/test_primitive_drawing.cpp similarity index 96% rename from src/gldraw/test/test_primitive_drawing.cpp rename to src/scene/test/test_primitive_drawing.cpp index 66d11a2..7457ef6 100644 --- a/src/gldraw/test/test_primitive_drawing.cpp +++ b/src/scene/test/test_primitive_drawing.cpp @@ -14,14 +14,14 @@ #include #include -#include "imview/box.hpp" -#include "imview/viewer.hpp" - -#include "gldraw/gl_scene_panel.hpp" -#include "gldraw/renderable/grid.hpp" -#include "gldraw/renderable/triangle.hpp" -#include "gldraw/renderable/coordinate_frame.hpp" -#include "gldraw/renderable/canvas.hpp" +#include "viewer/box.hpp" +#include "viewer/viewer.hpp" + +#include "scene/gl_scene_panel.hpp" +#include "scene/renderable/grid.hpp" +#include "test_utils/triangle.hpp" +#include "scene/renderable/coordinate_frame.hpp" +#include "scene/renderable/canvas.hpp" using namespace quickviz; namespace fs = std::filesystem; diff --git a/src/gldraw/test/test_shader.cpp b/src/scene/test/test_shader.cpp similarity index 96% rename from src/gldraw/test/test_shader.cpp rename to src/scene/test/test_shader.cpp index 6dea5ee..4702a07 100644 --- a/src/gldraw/test/test_shader.cpp +++ b/src/scene/test/test_shader.cpp @@ -8,9 +8,9 @@ #include -#include "imview/window.hpp" -#include "gldraw/shader.hpp" -#include "gldraw/shader_program.hpp" +#include "viewer/window.hpp" +#include "scene/shader.hpp" +#include "scene/shader_program.hpp" using namespace quickviz; diff --git a/src/scene/test/test_utils/CMakeLists.txt b/src/scene/test/test_utils/CMakeLists.txt new file mode 100644 index 0000000..0f5db50 --- /dev/null +++ b/src/scene/test/test_utils/CMakeLists.txt @@ -0,0 +1,15 @@ +# Test-only utilities for scene tests. Not part of the public library; +# never link these from non-test code. +# +# Provides simple renderables and helpers used across the renderable + +# selection + integration tests. Triangle lives here (rather than in the +# public scene library) because every real use is a test fixture or +# tutorial example — not application code. + +add_library(scene_test_utils STATIC + triangle.cpp) + +target_link_libraries(scene_test_utils PUBLIC scene) + +target_include_directories(scene_test_utils PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/src/gldraw/include/gldraw/renderable/triangle.hpp b/src/scene/test/test_utils/test_utils/triangle.hpp similarity index 81% rename from src/gldraw/include/gldraw/renderable/triangle.hpp rename to src/scene/test/test_utils/test_utils/triangle.hpp index 5784d9e..9789c33 100644 --- a/src/gldraw/include/gldraw/renderable/triangle.hpp +++ b/src/scene/test/test_utils/test_utils/triangle.hpp @@ -7,13 +7,13 @@ * Copyright (c) 2025 Ruixiang Du (rdu) */ -#ifndef COMPONENT_OPENGL_TRIANGLE_HPP -#define COMPONENT_OPENGL_TRIANGLE_HPP +#ifndef QUICKVIZ_TEST_UTILS_TRIANGLE_HPP +#define QUICKVIZ_TEST_UTILS_TRIANGLE_HPP #include -#include "gldraw/interface/opengl_object.hpp" -#include "../shader_program.hpp" +#include "scene/interface/opengl_object.hpp" +#include "scene/shader_program.hpp" namespace quickviz { class Triangle : public OpenGlObject { @@ -42,4 +42,4 @@ class Triangle : public OpenGlObject { }; } // namespace quickviz -#endif /* COMPONENT_OPENGL_TRIANGLE_HPP */ \ No newline at end of file +#endif /* QUICKVIZ_TEST_UTILS_TRIANGLE_HPP */ \ No newline at end of file diff --git a/src/gldraw/src/renderable/triangle.cpp b/src/scene/test/test_utils/triangle.cpp similarity index 99% rename from src/gldraw/src/renderable/triangle.cpp rename to src/scene/test/test_utils/triangle.cpp index 0e6cafd..ef55973 100644 --- a/src/gldraw/src/renderable/triangle.cpp +++ b/src/scene/test/test_utils/triangle.cpp @@ -7,7 +7,7 @@ * Copyright (c) 2025 Ruixiang Du (rdu) */ -#include "gldraw/renderable/triangle.hpp" +#include "test_utils/triangle.hpp" #include diff --git a/src/gldraw/test/tools/test_point_selection_tool.cpp b/src/scene/test/tools/test_point_selection_tool.cpp similarity index 98% rename from src/gldraw/test/tools/test_point_selection_tool.cpp rename to src/scene/test/tools/test_point_selection_tool.cpp index 7c9d658..0dc9e9f 100644 --- a/src/gldraw/test/tools/test_point_selection_tool.cpp +++ b/src/scene/test/tools/test_point_selection_tool.cpp @@ -10,10 +10,10 @@ #include #include -#include "gldraw/tools/point_selection_tool.hpp" -#include "gldraw/tools/interaction_tool.hpp" -#include "gldraw/scene_manager.hpp" -#include "gldraw/renderable/point_cloud.hpp" +#include "scene/tools/point_selection_tool.hpp" +#include "scene/tools/interaction_tool.hpp" +#include "scene/scene_manager.hpp" +#include "scene/renderable/point_cloud.hpp" #include "core/event/input_event.hpp" namespace quickviz { diff --git a/src/imview/CMakeLists.txt b/src/viewer/CMakeLists.txt similarity index 84% rename from src/imview/CMakeLists.txt rename to src/viewer/CMakeLists.txt index 56317a3..88c0b20 100644 --- a/src/imview/CMakeLists.txt +++ b/src/viewer/CMakeLists.txt @@ -29,7 +29,7 @@ if (ENABLE_AUTO_LAYOUT) endif () # add library -add_library(imview +add_library(viewer # ui components src/window.cpp src/viewer.cpp @@ -49,7 +49,7 @@ add_library(imview ${AUTO_LAYOUT_SRC} # terminal ${TUI_COMP_SRC}) -target_link_libraries(imview PUBLIC core imcore stb +target_link_libraries(viewer PUBLIC core imcore stb PkgConfig::Cairo PkgConfig::Fontconfig Threads::Threads OpenGL::GL @@ -57,13 +57,13 @@ target_link_libraries(imview PUBLIC core imcore stb ${OPENCV_COMP_LIBS} ${TUI_COMP_LIBS}) if (ENABLE_AUTO_LAYOUT) - target_compile_definitions(imview PUBLIC ENABLE_AUTO_LAYOUT) + target_compile_definitions(viewer PUBLIC ENABLE_AUTO_LAYOUT) endif () -if (IMVIEW_WITH_GLAD) - target_link_libraries(imview PUBLIC glad) - target_compile_definitions(imview PUBLIC IMVIEW_WITH_GLAD) +if (VIEWER_WITH_GLAD) + target_link_libraries(viewer PUBLIC glad) + target_compile_definitions(viewer PUBLIC VIEWER_WITH_GLAD) endif () -target_include_directories(imview PUBLIC +target_include_directories(viewer PUBLIC $ $ PRIVATE src) @@ -72,7 +72,7 @@ if (BUILD_TESTING) add_subdirectory(test) endif () -install(TARGETS imview +install(TARGETS viewer EXPORT quickvizTargets LIBRARY DESTINATION lib ARCHIVE DESTINATION lib diff --git a/src/imview/include/imview/box.hpp b/src/viewer/include/viewer/box.hpp similarity index 91% rename from src/imview/include/imview/box.hpp rename to src/viewer/include/viewer/box.hpp index fc410ab..9e79dea 100644 --- a/src/imview/include/imview/box.hpp +++ b/src/viewer/include/viewer/box.hpp @@ -14,9 +14,9 @@ #include #include -#include "imview/interface/container.hpp" -#include "imview/scene_object.hpp" -#include "imview/input/input_dispatcher.hpp" +#include "viewer/interface/container.hpp" +#include "viewer/scene_object.hpp" +#include "viewer/input/input_dispatcher.hpp" namespace quickviz { class Box : public SceneObject, public Container, public InputEventHandler { diff --git a/src/imview/include/imview/fonts.hpp b/src/viewer/include/viewer/fonts.hpp similarity index 100% rename from src/imview/include/imview/fonts.hpp rename to src/viewer/include/viewer/fonts.hpp diff --git a/src/imview/include/imview/input/gamepad_manager.hpp b/src/viewer/include/viewer/input/gamepad_manager.hpp similarity index 97% rename from src/imview/include/imview/input/gamepad_manager.hpp rename to src/viewer/include/viewer/input/gamepad_manager.hpp index ce14a4b..551b607 100644 --- a/src/imview/include/imview/input/gamepad_manager.hpp +++ b/src/viewer/include/viewer/input/gamepad_manager.hpp @@ -6,8 +6,8 @@ * @copyright Copyright (c) 2025 Ruixiang Du (rdu) */ -#ifndef IMVIEW_GAMEPAD_MANAGER_HPP -#define IMVIEW_GAMEPAD_MANAGER_HPP +#ifndef VIEWER_GAMEPAD_MANAGER_HPP +#define VIEWER_GAMEPAD_MANAGER_HPP #include #include @@ -171,4 +171,4 @@ class GamepadManager { } // namespace quickviz -#endif // IMVIEW_GAMEPAD_MANAGER_HPP \ No newline at end of file +#endif // VIEWER_GAMEPAD_MANAGER_HPP \ No newline at end of file diff --git a/src/imview/include/imview/input/imgui_input_utils.hpp b/src/viewer/include/viewer/input/imgui_input_utils.hpp similarity index 96% rename from src/imview/include/imview/input/imgui_input_utils.hpp rename to src/viewer/include/viewer/input/imgui_input_utils.hpp index ceb266f..60aed16 100644 --- a/src/imview/include/imview/input/imgui_input_utils.hpp +++ b/src/viewer/include/viewer/input/imgui_input_utils.hpp @@ -6,15 +6,15 @@ * @copyright Copyright (c) 2025 Ruixiang Du (rdu) */ -#ifndef IMVIEW_IMGUI_INPUT_UTILS_HPP -#define IMVIEW_IMGUI_INPUT_UTILS_HPP +#ifndef VIEWER_IMGUI_INPUT_UTILS_HPP +#define VIEWER_IMGUI_INPUT_UTILS_HPP #include "imgui.h" #include "core/event/input_event.hpp" #include "core/event/input_mapping.hpp" -#include "imview/input/input_types.hpp" +#include "viewer/input/input_types.hpp" namespace quickviz { /** @@ -140,4 +140,4 @@ class ScopedInputPoller { } // namespace quickviz -#endif // IMVIEW_IMGUI_INPUT_UTILS_HPP \ No newline at end of file +#endif // VIEWER_IMGUI_INPUT_UTILS_HPP \ No newline at end of file diff --git a/src/imview/include/imview/input/input_dispatcher.hpp b/src/viewer/include/viewer/input/input_dispatcher.hpp similarity index 89% rename from src/imview/include/imview/input/input_dispatcher.hpp rename to src/viewer/include/viewer/input/input_dispatcher.hpp index 5ca2150..5332588 100644 --- a/src/imview/include/imview/input/input_dispatcher.hpp +++ b/src/viewer/include/viewer/input/input_dispatcher.hpp @@ -1,13 +1,13 @@ /* * @file input_dispatcher.hpp * @date 9/1/25 - * @brief Central input event dispatcher for imview module + * @brief Central input event dispatcher for viewer module * * @copyright Copyright (c) 2025 Ruixiang Du (rdu) */ -#ifndef IMVIEW_INPUT_DISPATCHER_HPP -#define IMVIEW_INPUT_DISPATCHER_HPP +#ifndef VIEWER_INPUT_DISPATCHER_HPP +#define VIEWER_INPUT_DISPATCHER_HPP #include #include @@ -20,7 +20,7 @@ namespace quickviz { /** - * @brief Priority-based input event handler interface for imview + * @brief Priority-based input event handler interface for viewer * * Extends the basic InputHandler interface with priority support * for proper event ordering and consumption. @@ -53,7 +53,7 @@ class InputEventHandler { }; /** - * @brief Central input event dispatcher for the imview module + * @brief Central input event dispatcher for the viewer module * * Manages priority-based event handling with proper consumption semantics. * Handlers are processed in priority order (highest first) until one @@ -119,4 +119,4 @@ class InputDispatcher { } // namespace quickviz -#endif // IMVIEW_INPUT_DISPATCHER_HPP \ No newline at end of file +#endif // VIEWER_INPUT_DISPATCHER_HPP \ No newline at end of file diff --git a/src/imview/include/imview/input/input_manager.hpp b/src/viewer/include/viewer/input/input_manager.hpp similarity index 91% rename from src/imview/include/imview/input/input_manager.hpp rename to src/viewer/include/viewer/input/input_manager.hpp index e6d9ce4..58a528b 100644 --- a/src/imview/include/imview/input/input_manager.hpp +++ b/src/viewer/include/viewer/input/input_manager.hpp @@ -1,20 +1,20 @@ /* * @file input_manager.hpp * @date 9/1/25 - * @brief ImGui-centric input management for imview windows + * @brief ImGui-centric input management for viewer windows * * @copyright Copyright (c) 2025 Ruixiang Du (rdu) */ -#ifndef IMVIEW_INPUT_MANAGER_HPP -#define IMVIEW_INPUT_MANAGER_HPP +#ifndef VIEWER_INPUT_MANAGER_HPP +#define VIEWER_INPUT_MANAGER_HPP #include #include #include "core/event/input_event.hpp" #include "core/event/input_mapping.hpp" -#include "imview/input/input_dispatcher.hpp" +#include "viewer/input/input_dispatcher.hpp" namespace quickviz { @@ -99,4 +99,4 @@ class InputManager { } // namespace quickviz -#endif // IMVIEW_INPUT_MANAGER_HPP \ No newline at end of file +#endif // VIEWER_INPUT_MANAGER_HPP \ No newline at end of file diff --git a/src/imview/include/imview/input/input_policy.hpp b/src/viewer/include/viewer/input/input_policy.hpp similarity index 98% rename from src/imview/include/imview/input/input_policy.hpp rename to src/viewer/include/viewer/input/input_policy.hpp index bac4e6a..023f1ed 100644 --- a/src/imview/include/imview/input/input_policy.hpp +++ b/src/viewer/include/viewer/input/input_policy.hpp @@ -6,8 +6,8 @@ * @copyright Copyright (c) 2025 Ruixiang Du (rdu) */ -#ifndef IMVIEW_INPUT_POLICY_HPP -#define IMVIEW_INPUT_POLICY_HPP +#ifndef VIEWER_INPUT_POLICY_HPP +#define VIEWER_INPUT_POLICY_HPP #include "core/event/input_event.hpp" @@ -246,4 +246,4 @@ class InputControlled { } // namespace quickviz -#endif // IMVIEW_INPUT_POLICY_HPP \ No newline at end of file +#endif // VIEWER_INPUT_POLICY_HPP \ No newline at end of file diff --git a/src/imview/include/imview/input/input_types.hpp b/src/viewer/include/viewer/input/input_types.hpp similarity index 100% rename from src/imview/include/imview/input/input_types.hpp rename to src/viewer/include/viewer/input/input_types.hpp diff --git a/src/imview/include/imview/interface/container.hpp b/src/viewer/include/viewer/interface/container.hpp similarity index 93% rename from src/imview/include/imview/interface/container.hpp rename to src/viewer/include/viewer/interface/container.hpp index c98eba0..89a1cb4 100644 --- a/src/imview/include/imview/interface/container.hpp +++ b/src/viewer/include/viewer/interface/container.hpp @@ -11,7 +11,7 @@ #include -#include "imview/scene_object.hpp" +#include "viewer/scene_object.hpp" namespace quickviz { class Container { diff --git a/src/imview/include/imview/interface/renderable.hpp b/src/viewer/include/viewer/interface/renderable.hpp similarity index 100% rename from src/imview/include/imview/interface/renderable.hpp rename to src/viewer/include/viewer/interface/renderable.hpp diff --git a/src/imview/include/imview/interface/resizable.hpp b/src/viewer/include/viewer/interface/resizable.hpp similarity index 98% rename from src/imview/include/imview/interface/resizable.hpp rename to src/viewer/include/viewer/interface/resizable.hpp index 554b0b6..c0bbefb 100644 --- a/src/imview/include/imview/interface/resizable.hpp +++ b/src/viewer/include/viewer/interface/resizable.hpp @@ -9,7 +9,7 @@ #ifndef QUICKVIZ_RESIZABLE_HPP #define QUICKVIZ_RESIZABLE_HPP -#include "imview/styling.hpp" +#include "viewer/styling.hpp" namespace quickviz { class Resizable { diff --git a/src/imview/include/imview/logging/app_log_handler.hpp b/src/viewer/include/viewer/logging/app_log_handler.hpp similarity index 97% rename from src/imview/include/imview/logging/app_log_handler.hpp rename to src/viewer/include/viewer/logging/app_log_handler.hpp index d93a2a6..d39d06b 100644 --- a/src/imview/include/imview/logging/app_log_handler.hpp +++ b/src/viewer/include/viewer/logging/app_log_handler.hpp @@ -9,7 +9,7 @@ #ifndef APP_LOG_HANDLER_HPP #define APP_LOG_HANDLER_HPP -#include "imview/logging/log_processor.hpp" +#include "viewer/logging/log_processor.hpp" #include #include diff --git a/src/imview/include/imview/logging/log_processor.hpp b/src/viewer/include/viewer/logging/log_processor.hpp similarity index 100% rename from src/imview/include/imview/logging/log_processor.hpp rename to src/viewer/include/viewer/logging/log_processor.hpp diff --git a/src/imview/include/imview/panel.hpp b/src/viewer/include/viewer/panel.hpp similarity index 88% rename from src/imview/include/imview/panel.hpp rename to src/viewer/include/viewer/panel.hpp index 54ab4ed..5c856cc 100644 --- a/src/imview/include/imview/panel.hpp +++ b/src/viewer/include/viewer/panel.hpp @@ -7,18 +7,18 @@ * Copyright (c) 2022 Ruixiang Du (rdu) */ -#ifndef ROBOSW_SRC_VISUALIZATION_IMVIEW_INCLUDE_IMVIEW_PANEL_HPP -#define ROBOSW_SRC_VISUALIZATION_IMVIEW_INCLUDE_IMVIEW_PANEL_HPP +#ifndef ROBOSW_SRC_VISUALIZATION_VIEWER_INCLUDE_VIEWER_PANEL_HPP +#define ROBOSW_SRC_VISUALIZATION_VIEWER_INCLUDE_VIEWER_PANEL_HPP #include #include #include #include "imgui.h" -#include "imview/scene_object.hpp" -#include "imview/input/imgui_input_utils.hpp" -#include "imview/input/input_policy.hpp" -#include "imview/input/input_dispatcher.hpp" +#include "viewer/scene_object.hpp" +#include "viewer/input/imgui_input_utils.hpp" +#include "viewer/input/input_policy.hpp" +#include "viewer/input/input_dispatcher.hpp" namespace quickviz { class Window; // Forward declaration @@ -103,4 +103,4 @@ class Panel : public SceneObject, public InputControlled, public InputEventHandl }; } // namespace quickviz -#endif // ROBOSW_SRC_VISUALIZATION_IMVIEW_INCLUDE_IMVIEW_PANEL_HPP +#endif // ROBOSW_SRC_VISUALIZATION_VIEWER_INCLUDE_VIEWER_PANEL_HPP diff --git a/src/imview/include/imview/popup.hpp b/src/viewer/include/viewer/popup.hpp similarity index 77% rename from src/imview/include/imview/popup.hpp rename to src/viewer/include/viewer/popup.hpp index d8163d7..5deb967 100644 --- a/src/imview/include/imview/popup.hpp +++ b/src/viewer/include/viewer/popup.hpp @@ -7,8 +7,8 @@ * Copyright (c) 2022 Ruixiang Du (rdu) */ -#ifndef ROBOSW_SRC_VISUALIZATION_IMVIEW_INCLUDE_IMVIEW_POPUP_HPP -#define ROBOSW_SRC_VISUALIZATION_IMVIEW_INCLUDE_IMVIEW_POPUP_HPP +#ifndef ROBOSW_SRC_VISUALIZATION_VIEWER_INCLUDE_VIEWER_POPUP_HPP +#define ROBOSW_SRC_VISUALIZATION_VIEWER_INCLUDE_VIEWER_POPUP_HPP #include #include @@ -26,4 +26,4 @@ void ShowConfirmationPopup(std::string title, std::string msg, float width = 300, float height = 150); } // namespace quickviz -#endif // ROBOSW_SRC_VISUALIZATION_IMVIEW_INCLUDE_IMVIEW_POPUP_HPP +#endif // ROBOSW_SRC_VISUALIZATION_VIEWER_INCLUDE_VIEWER_POPUP_HPP diff --git a/src/imview/include/imview/popup_manager.hpp b/src/viewer/include/viewer/popup_manager.hpp similarity index 97% rename from src/imview/include/imview/popup_manager.hpp rename to src/viewer/include/viewer/popup_manager.hpp index 1e32de9..5b40181 100644 --- a/src/imview/include/imview/popup_manager.hpp +++ b/src/viewer/include/viewer/popup_manager.hpp @@ -11,7 +11,7 @@ #include -#include "imview/popup.hpp" +#include "viewer/popup.hpp" namespace quickviz { class PopupManager { diff --git a/src/imview/include/imview/scene_object.hpp b/src/viewer/include/viewer/scene_object.hpp similarity index 97% rename from src/imview/include/imview/scene_object.hpp rename to src/viewer/include/viewer/scene_object.hpp index 98e76bf..e108984 100644 --- a/src/imview/include/imview/scene_object.hpp +++ b/src/viewer/include/viewer/scene_object.hpp @@ -13,8 +13,8 @@ #include #include -#include "imview/interface/resizable.hpp" -#include "imview/interface/renderable.hpp" +#include "viewer/interface/resizable.hpp" +#include "viewer/interface/renderable.hpp" #ifdef ENABLE_AUTO_LAYOUT struct YGNode; diff --git a/src/imview/include/imview/styling.hpp b/src/viewer/include/viewer/styling.hpp similarity index 100% rename from src/imview/include/imview/styling.hpp rename to src/viewer/include/viewer/styling.hpp diff --git a/src/imview/include/imview/terminal/tui_panel.hpp b/src/viewer/include/viewer/terminal/tui_panel.hpp similarity index 82% rename from src/imview/include/imview/terminal/tui_panel.hpp rename to src/viewer/include/viewer/terminal/tui_panel.hpp index 118dc52..28f4655 100644 --- a/src/imview/include/imview/terminal/tui_panel.hpp +++ b/src/viewer/include/viewer/terminal/tui_panel.hpp @@ -7,15 +7,15 @@ * Copyright (c) 2025 Ruixiang Du (rdu) */ -#ifndef IMVIEW_TERMINAL_TUI_PANEL_HPP -#define IMVIEW_TERMINAL_TUI_PANEL_HPP +#ifndef VIEWER_TERMINAL_TUI_PANEL_HPP +#define VIEWER_TERMINAL_TUI_PANEL_HPP #include #include #include -#include "imview/scene_object.hpp" +#include "viewer/scene_object.hpp" namespace quickviz { class TuiPanel : public SceneObject { @@ -40,4 +40,4 @@ class TuiPanel : public SceneObject { }; } // namespace quickviz -#endif /* IMVIEW_TERMINAL_TUI_PANEL_HPP */ +#endif /* VIEWER_TERMINAL_TUI_PANEL_HPP */ diff --git a/src/imview/include/imview/terminal/tui_text.hpp b/src/viewer/include/viewer/terminal/tui_text.hpp similarity index 93% rename from src/imview/include/imview/terminal/tui_text.hpp rename to src/viewer/include/viewer/terminal/tui_text.hpp index edf29f1..22085af 100644 --- a/src/imview/include/imview/terminal/tui_text.hpp +++ b/src/viewer/include/viewer/terminal/tui_text.hpp @@ -7,8 +7,8 @@ * @copyright Copyright (c) 2023 Ruixiang Du (rdu) */ -#ifndef IMVIEW_TERMINAL_NC_TEXT_HPP -#define IMVIEW_TERMINAL_NC_TEXT_HPP +#ifndef VIEWER_TERMINAL_NC_TEXT_HPP +#define VIEWER_TERMINAL_NC_TEXT_HPP #include @@ -64,4 +64,4 @@ class TuiText { }; } // namespace quickviz -#endif /* IMVIEW_TERMINAL_NC_TEXT_HPP */ +#endif /* VIEWER_TERMINAL_NC_TEXT_HPP */ diff --git a/src/imview/include/imview/terminal/tui_viewer.hpp b/src/viewer/include/viewer/terminal/tui_viewer.hpp similarity index 80% rename from src/imview/include/imview/terminal/tui_viewer.hpp rename to src/viewer/include/viewer/terminal/tui_viewer.hpp index a9f8138..0a9c93c 100644 --- a/src/imview/include/imview/terminal/tui_viewer.hpp +++ b/src/viewer/include/viewer/terminal/tui_viewer.hpp @@ -7,8 +7,8 @@ * Copyright (c) 2025 Ruixiang Du (rdu) */ -#ifndef IMVIEW_TERMINAL_TUI_VIEWER_HPP -#define IMVIEW_TERMINAL_TUI_VIEWER_HPP +#ifndef VIEWER_TERMINAL_TUI_VIEWER_HPP +#define VIEWER_TERMINAL_TUI_VIEWER_HPP #include @@ -17,8 +17,8 @@ #include #include -#include "imview/terminal/tui_text.hpp" -#include "imview/terminal/tui_panel.hpp" +#include "viewer/terminal/tui_text.hpp" +#include "viewer/terminal/tui_panel.hpp" namespace quickviz { class TuiViewer { @@ -49,4 +49,4 @@ class TuiViewer { }; } // namespace quickviz -#endif /* IMVIEW_TERMINAL_TUI_VIEWER_HPP */ +#endif /* VIEWER_TERMINAL_TUI_VIEWER_HPP */ diff --git a/src/imview/include/imview/viewer.hpp b/src/viewer/include/viewer/viewer.hpp similarity index 90% rename from src/imview/include/imview/viewer.hpp rename to src/viewer/include/viewer/viewer.hpp index 3dc4a50..03ff210 100644 --- a/src/imview/include/imview/viewer.hpp +++ b/src/viewer/include/viewer/viewer.hpp @@ -9,8 +9,8 @@ * Copyright (c) 2021 Ruixiang Du (rdu) */ -#ifndef IMVIEW_VIEWER_HPP -#define IMVIEW_VIEWER_HPP +#ifndef VIEWER_VIEWER_HPP +#define VIEWER_VIEWER_HPP #include #include @@ -18,9 +18,9 @@ #include "imgui.h" -#include "imview/fonts.hpp" -#include "imview/window.hpp" -#include "imview/scene_object.hpp" +#include "viewer/fonts.hpp" +#include "viewer/window.hpp" +#include "viewer/scene_object.hpp" namespace quickviz { class Viewer : public Window { @@ -70,4 +70,4 @@ class Viewer : public Window { }; } // namespace quickviz -#endif /* IMVIEW_VIEWER_HPP */ +#endif /* VIEWER_VIEWER_HPP */ diff --git a/src/imview/include/imview/window.hpp b/src/viewer/include/viewer/window.hpp similarity index 92% rename from src/imview/include/imview/window.hpp rename to src/viewer/include/viewer/window.hpp index d9d7054..324cb52 100644 --- a/src/imview/include/imview/window.hpp +++ b/src/viewer/include/viewer/window.hpp @@ -8,10 +8,10 @@ * Copyright (c) 2021 Ruixiang Du (rdu) */ -#ifndef IMVIEW_WINDOW_HPP -#define IMVIEW_WINDOW_HPP +#ifndef VIEWER_WINDOW_HPP +#define VIEWER_WINDOW_HPP -#ifdef IMVIEW_WITH_GLAD +#ifdef VIEWER_WITH_GLAD #include #endif #include @@ -20,7 +20,7 @@ #include #include -#include "imview/input/input_manager.hpp" +#include "viewer/input/input_manager.hpp" namespace quickviz { class Panel; // Forward declaration @@ -80,4 +80,4 @@ class Window { }; } // namespace quickviz -#endif /* IMVIEW_WINDOW_HPP */ +#endif /* VIEWER_WINDOW_HPP */ diff --git a/src/imview/src/box.cpp b/src/viewer/src/box.cpp similarity index 97% rename from src/imview/src/box.cpp rename to src/viewer/src/box.cpp index f3d4126..8c903a3 100644 --- a/src/imview/src/box.cpp +++ b/src/viewer/src/box.cpp @@ -6,12 +6,12 @@ * @copyright Copyright (c) 2024 Ruixiang Du (rdu) */ -#include "imview/box.hpp" +#include "viewer/box.hpp" #include #include -#include "imview/input/input_dispatcher.hpp" +#include "viewer/input/input_dispatcher.hpp" namespace quickviz { namespace { diff --git a/src/imview/src/fonts.cpp b/src/viewer/src/fonts.cpp similarity index 98% rename from src/imview/src/fonts.cpp rename to src/viewer/src/fonts.cpp index c8b6d46..2499e04 100644 --- a/src/imview/src/fonts.cpp +++ b/src/viewer/src/fonts.cpp @@ -6,7 +6,7 @@ * @copyright Copyright (c) 2024 Ruixiang Du (rdu) */ -#include "imview/fonts.hpp" +#include "viewer/fonts.hpp" #include diff --git a/src/imview/src/input/gamepad_manager.cpp b/src/viewer/src/input/gamepad_manager.cpp similarity index 99% rename from src/imview/src/input/gamepad_manager.cpp rename to src/viewer/src/input/gamepad_manager.cpp index 652ea71..97dd10b 100644 --- a/src/imview/src/input/gamepad_manager.cpp +++ b/src/viewer/src/input/gamepad_manager.cpp @@ -6,7 +6,7 @@ * @copyright Copyright (c) 2025 Ruixiang Du (rdu) */ -#include "imview/input/gamepad_manager.hpp" +#include "viewer/input/gamepad_manager.hpp" #include #include #include diff --git a/src/imview/src/input/imgui_input_utils.cpp b/src/viewer/src/input/imgui_input_utils.cpp similarity index 99% rename from src/imview/src/input/imgui_input_utils.cpp rename to src/viewer/src/input/imgui_input_utils.cpp index e1b476f..24dcf7c 100644 --- a/src/imview/src/input/imgui_input_utils.cpp +++ b/src/viewer/src/input/imgui_input_utils.cpp @@ -6,8 +6,8 @@ * @copyright Copyright (c) 2025 Ruixiang Du (rdu) */ -#include "imview/input/imgui_input_utils.hpp" -#include "imview/input/gamepad_manager.hpp" +#include "viewer/input/imgui_input_utils.hpp" +#include "viewer/input/gamepad_manager.hpp" #include #include #include diff --git a/src/imview/src/input/input_dispatcher.cpp b/src/viewer/src/input/input_dispatcher.cpp similarity index 98% rename from src/imview/src/input/input_dispatcher.cpp rename to src/viewer/src/input/input_dispatcher.cpp index f94a09b..35225e9 100644 --- a/src/imview/src/input/input_dispatcher.cpp +++ b/src/viewer/src/input/input_dispatcher.cpp @@ -6,7 +6,7 @@ * @copyright Copyright (c) 2025 Ruixiang Du (rdu) */ -#include "imview/input/input_dispatcher.hpp" +#include "viewer/input/input_dispatcher.hpp" #include diff --git a/src/imview/src/input/input_manager.cpp b/src/viewer/src/input/input_manager.cpp similarity index 96% rename from src/imview/src/input/input_manager.cpp rename to src/viewer/src/input/input_manager.cpp index c55a495..e4df3be 100644 --- a/src/imview/src/input/input_manager.cpp +++ b/src/viewer/src/input/input_manager.cpp @@ -6,7 +6,7 @@ * @copyright Copyright (c) 2025 Ruixiang Du (rdu) */ -#include "imview/input/input_manager.hpp" +#include "viewer/input/input_manager.hpp" namespace quickviz { diff --git a/src/imview/src/logging/app_log_handler.cpp b/src/viewer/src/logging/app_log_handler.cpp similarity index 82% rename from src/imview/src/logging/app_log_handler.cpp rename to src/viewer/src/logging/app_log_handler.cpp index 930564e..3265750 100644 --- a/src/imview/src/logging/app_log_handler.cpp +++ b/src/viewer/src/logging/app_log_handler.cpp @@ -6,7 +6,7 @@ * @copyright Copyright (c) 2024 Ruixiang Du (rdu) */ -#include "imview/logging/app_log_handler.hpp" +#include "viewer/logging/app_log_handler.hpp" namespace quickviz { void AppLogHandler::Draw() { processor_.Draw("AppLog"); } diff --git a/src/imview/src/logging/log_processor.cpp b/src/viewer/src/logging/log_processor.cpp similarity index 98% rename from src/imview/src/logging/log_processor.cpp rename to src/viewer/src/logging/log_processor.cpp index 05aa555..d30c388 100644 --- a/src/imview/src/logging/log_processor.cpp +++ b/src/viewer/src/logging/log_processor.cpp @@ -6,7 +6,7 @@ * @copyright Copyright (c) 2024 Ruixiang Du (rdu) */ -#include "imview/logging/log_processor.hpp" +#include "viewer/logging/log_processor.hpp" namespace quickviz { LogProcessor::LogProcessor() { diff --git a/src/imview/src/opengl_capability_checker.cpp b/src/viewer/src/opengl_capability_checker.cpp similarity index 99% rename from src/imview/src/opengl_capability_checker.cpp rename to src/viewer/src/opengl_capability_checker.cpp index 30c480d..736e298 100644 --- a/src/imview/src/opengl_capability_checker.cpp +++ b/src/viewer/src/opengl_capability_checker.cpp @@ -14,7 +14,7 @@ #include #include -#ifdef IMVIEW_WITH_GLAD +#ifdef VIEWER_WITH_GLAD #include "glad/glad.h" #else #include diff --git a/src/imview/src/opengl_capability_checker.hpp b/src/viewer/src/opengl_capability_checker.hpp similarity index 100% rename from src/imview/src/opengl_capability_checker.hpp rename to src/viewer/src/opengl_capability_checker.hpp diff --git a/src/imview/src/panel.cpp b/src/viewer/src/panel.cpp similarity index 99% rename from src/imview/src/panel.cpp rename to src/viewer/src/panel.cpp index 262c57a..8fad949 100644 --- a/src/imview/src/panel.cpp +++ b/src/viewer/src/panel.cpp @@ -7,10 +7,10 @@ * Copyright (c) 2022 Ruixiang Du (rdu) */ -#include "imview/panel.hpp" +#include "viewer/panel.hpp" #include "imgui_internal.h" -#include "imview/window.hpp" +#include "viewer/window.hpp" namespace quickviz { Panel::Panel(std::string name) : SceneObject(name) { diff --git a/src/imview/src/popup.cpp b/src/viewer/src/popup.cpp similarity index 98% rename from src/imview/src/popup.cpp rename to src/viewer/src/popup.cpp index bc86c8e..a549c59 100644 --- a/src/imview/src/popup.cpp +++ b/src/viewer/src/popup.cpp @@ -7,7 +7,7 @@ * Copyright (c) 2022 Ruixiang Du (rdu) */ -#include "imview/popup.hpp" +#include "viewer/popup.hpp" #include "imgui.h" diff --git a/src/imview/src/popup_manager.cpp b/src/viewer/src/popup_manager.cpp similarity index 98% rename from src/imview/src/popup_manager.cpp rename to src/viewer/src/popup_manager.cpp index a4fb40a..ebc7cc7 100644 --- a/src/imview/src/popup_manager.cpp +++ b/src/viewer/src/popup_manager.cpp @@ -6,7 +6,7 @@ * @copyright Copyright (c) 2024 Ruixiang Du (rdu) */ -#include "imview/popup_manager.hpp" +#include "viewer/popup_manager.hpp" #include "imgui/imgui.h" diff --git a/src/imview/src/scene_object.cpp b/src/viewer/src/scene_object.cpp similarity index 99% rename from src/imview/src/scene_object.cpp rename to src/viewer/src/scene_object.cpp index e995ae9..20cc2fe 100644 --- a/src/imview/src/scene_object.cpp +++ b/src/viewer/src/scene_object.cpp @@ -6,7 +6,7 @@ * @copyright Copyright (c) 2024 Ruixiang Du (rdu) */ -#include "imview/scene_object.hpp" +#include "viewer/scene_object.hpp" #include diff --git a/src/imview/src/terminal/tui_panel.cpp b/src/viewer/src/terminal/tui_panel.cpp similarity index 97% rename from src/imview/src/terminal/tui_panel.cpp rename to src/viewer/src/terminal/tui_panel.cpp index c5219e0..0e3166b 100644 --- a/src/imview/src/terminal/tui_panel.cpp +++ b/src/viewer/src/terminal/tui_panel.cpp @@ -7,7 +7,7 @@ * Copyright (c) 2025 Ruixiang Du (rdu) */ -#include "imview/terminal/tui_panel.hpp" +#include "viewer/terminal/tui_panel.hpp" #include diff --git a/src/imview/src/terminal/tui_text.cpp b/src/viewer/src/terminal/tui_text.cpp similarity index 95% rename from src/imview/src/terminal/tui_text.cpp rename to src/viewer/src/terminal/tui_text.cpp index 0c72a4c..1a2f328 100644 --- a/src/imview/src/terminal/tui_text.cpp +++ b/src/viewer/src/terminal/tui_text.cpp @@ -6,7 +6,7 @@ * @copyright Copyright (c) 2023 Ruixiang Du (rdu) */ -#include "imview/terminal/tui_text.hpp" +#include "viewer/terminal/tui_text.hpp" #include diff --git a/src/imview/src/terminal/tui_viewer.cpp b/src/viewer/src/terminal/tui_viewer.cpp similarity index 97% rename from src/imview/src/terminal/tui_viewer.cpp rename to src/viewer/src/terminal/tui_viewer.cpp index 420a2d8..bdc0c26 100644 --- a/src/imview/src/terminal/tui_viewer.cpp +++ b/src/viewer/src/terminal/tui_viewer.cpp @@ -12,7 +12,7 @@ #include #include -#include "imview/terminal/tui_viewer.hpp" +#include "viewer/terminal/tui_viewer.hpp" namespace quickviz { TuiViewer::TuiViewer(const std::string &title, bool has_border) diff --git a/src/imview/src/viewer.cpp b/src/viewer/src/viewer.cpp similarity index 99% rename from src/imview/src/viewer.cpp rename to src/viewer/src/viewer.cpp index 72f33f4..525985f 100644 --- a/src/imview/src/viewer.cpp +++ b/src/viewer/src/viewer.cpp @@ -15,7 +15,7 @@ * Copyright (c) 2021 Ruixiang Du (rdu) */ -#include "imview/viewer.hpp" +#include "viewer/viewer.hpp" #include #include @@ -25,8 +25,8 @@ #include "imgui_impl_glfw.h" #include "imgui_impl_opengl3.h" #include "opengl_capability_checker.hpp" -#include "imview/panel.hpp" -#include "imview/input/imgui_input_utils.hpp" +#include "viewer/panel.hpp" +#include "viewer/input/imgui_input_utils.hpp" namespace quickviz { namespace { diff --git a/src/imview/src/window.cpp b/src/viewer/src/window.cpp similarity index 98% rename from src/imview/src/window.cpp rename to src/viewer/src/window.cpp index b35e2f3..b3ff903 100644 --- a/src/imview/src/window.cpp +++ b/src/viewer/src/window.cpp @@ -7,14 +7,14 @@ * Copyright (c) 2021 Ruixiang Du (rdu) */ -#include "imview/window.hpp" +#include "viewer/window.hpp" #include #include #include -#include "imview/panel.hpp" -#include "imview/input/gamepad_manager.hpp" +#include "viewer/panel.hpp" +#include "viewer/input/gamepad_manager.hpp" namespace quickviz { namespace { @@ -71,7 +71,7 @@ Window::Window(std::string title, uint32_t width, uint32_t height, glfwMakeContextCurrent(win_); glfwSwapInterval(1); -#ifdef IMVIEW_WITH_GLAD +#ifdef VIEWER_WITH_GLAD // initialize GLAD if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { throw std::runtime_error("Failed to initialize GLAD"); diff --git a/src/imview/src/yoga_utils.cpp b/src/viewer/src/yoga_utils.cpp similarity index 100% rename from src/imview/src/yoga_utils.cpp rename to src/viewer/src/yoga_utils.cpp diff --git a/src/imview/src/yoga_utils.hpp b/src/viewer/src/yoga_utils.hpp similarity index 96% rename from src/imview/src/yoga_utils.hpp rename to src/viewer/src/yoga_utils.hpp index 605fd0b..db0e590 100644 --- a/src/imview/src/yoga_utils.hpp +++ b/src/viewer/src/yoga_utils.hpp @@ -10,7 +10,7 @@ #define QUICKVIZ_YOGA_UTILS_HPP #include "yoga/Yoga.h" -#include "imview/styling.hpp" +#include "viewer/styling.hpp" namespace quickviz { namespace YogaUtils { diff --git a/src/imview/test/CMakeLists.txt b/src/viewer/test/CMakeLists.txt similarity index 59% rename from src/imview/test/CMakeLists.txt rename to src/viewer/test/CMakeLists.txt index b1521de..374a516 100644 --- a/src/imview/test/CMakeLists.txt +++ b/src/viewer/test/CMakeLists.txt @@ -3,15 +3,15 @@ add_subdirectory(feature) ## additional tests/sample add_executable(test_window_gl_triangle test_window_gl_triangle.cpp) -target_link_libraries(test_window_gl_triangle PRIVATE imview) +target_link_libraries(test_window_gl_triangle PRIVATE viewer) if (ENABLE_AUTO_LAYOUT) add_executable(test_box test_box.cpp) - target_link_libraries(test_box PRIVATE imview) + target_link_libraries(test_box PRIVATE viewer) add_executable(test_box_inside_box test_box_inside_box.cpp) - target_link_libraries(test_box_inside_box PRIVATE imview) + target_link_libraries(test_box_inside_box PRIVATE viewer) endif () #add_executable(test_panel test_panel.cpp) -#target_link_libraries(test_panel imview) +#target_link_libraries(test_panel viewer) diff --git a/src/imview/test/feature/CMakeLists.txt b/src/viewer/test/feature/CMakeLists.txt similarity index 54% rename from src/imview/test/feature/CMakeLists.txt rename to src/viewer/test/feature/CMakeLists.txt index 2a50f15..c9de8d9 100644 --- a/src/imview/test/feature/CMakeLists.txt +++ b/src/viewer/test/feature/CMakeLists.txt @@ -1,27 +1,27 @@ add_executable(test_window test_window.cpp) -target_link_libraries(test_window PRIVATE imview) +target_link_libraries(test_window PRIVATE viewer) if(ENABLE_AUTO_LAYOUT) add_executable(test_viewer test_viewer.cpp) - target_link_libraries(test_viewer PRIVATE imview) + target_link_libraries(test_viewer PRIVATE viewer) add_executable(test_auto_layout test_auto_layout.cpp) - target_link_libraries(test_auto_layout PRIVATE imview) + target_link_libraries(test_auto_layout PRIVATE viewer) if(ENABLE_TUI_SUPPORT) add_executable(test_tui_composer test_tui_composer.cpp) - target_link_libraries(test_tui_composer PRIVATE imview) + target_link_libraries(test_tui_composer PRIVATE viewer) endif() endif() add_executable(test_popup test_popup.cpp) -target_link_libraries(test_popup PRIVATE imview) +target_link_libraries(test_popup PRIVATE viewer) add_executable(test_joystick_input test_joystick_input.cpp) -target_link_libraries(test_joystick_input PRIVATE imview) +target_link_libraries(test_joystick_input PRIVATE viewer) add_executable(test_keyboard_mouse_input test_keyboard_mouse_input.cpp) -target_link_libraries(test_keyboard_mouse_input PRIVATE imview) +target_link_libraries(test_keyboard_mouse_input PRIVATE viewer) add_executable(test_centralized_input test_centralized_input.cpp) -target_link_libraries(test_centralized_input PRIVATE imview gtest gtest_main) +target_link_libraries(test_centralized_input PRIVATE viewer gtest gtest_main) diff --git a/src/imview/test/feature/scene_objects/gl_triangle_scene_object.hpp b/src/viewer/test/feature/scene_objects/gl_triangle_scene_object.hpp similarity index 99% rename from src/imview/test/feature/scene_objects/gl_triangle_scene_object.hpp rename to src/viewer/test/feature/scene_objects/gl_triangle_scene_object.hpp index 935a4bf..03e8381 100644 --- a/src/imview/test/feature/scene_objects/gl_triangle_scene_object.hpp +++ b/src/viewer/test/feature/scene_objects/gl_triangle_scene_object.hpp @@ -11,7 +11,7 @@ #include #include "glad/glad.h" -#include "imview/panel.hpp" +#include "viewer/panel.hpp" namespace quickviz { class GLTriangleSceneObject : public Panel { diff --git a/src/imview/test/feature/scene_objects/imgui_fixed_panel.hpp b/src/viewer/test/feature/scene_objects/imgui_fixed_panel.hpp similarity index 95% rename from src/imview/test/feature/scene_objects/imgui_fixed_panel.hpp rename to src/viewer/test/feature/scene_objects/imgui_fixed_panel.hpp index 3a273bd..07bd7a0 100644 --- a/src/imview/test/feature/scene_objects/imgui_fixed_panel.hpp +++ b/src/viewer/test/feature/scene_objects/imgui_fixed_panel.hpp @@ -9,8 +9,8 @@ #ifndef QUICKVIZ_IMGUI_FIXED_PANEL_HPP #define QUICKVIZ_IMGUI_FIXED_PANEL_HPP -#include "imview/viewer.hpp" -#include "imview/panel.hpp" +#include "viewer/viewer.hpp" +#include "viewer/panel.hpp" namespace quickviz { class ImGuiFixedPanel : public Panel { diff --git a/src/imview/test/feature/scene_objects/imtext_panel.hpp b/src/viewer/test/feature/scene_objects/imtext_panel.hpp similarity index 96% rename from src/imview/test/feature/scene_objects/imtext_panel.hpp rename to src/viewer/test/feature/scene_objects/imtext_panel.hpp index 553d8d4..02296e0 100644 --- a/src/imview/test/feature/scene_objects/imtext_panel.hpp +++ b/src/viewer/test/feature/scene_objects/imtext_panel.hpp @@ -9,7 +9,7 @@ #ifndef QUICKVIZ_IMTEXT_PANEL_HPP #define QUICKVIZ_IMTEXT_PANEL_HPP -#include "imview/panel.hpp" +#include "viewer/panel.hpp" namespace quickviz { class ImTextPanel : public Panel { diff --git a/src/imview/test/feature/scene_objects/opengl_scene_object.hpp b/src/viewer/test/feature/scene_objects/opengl_scene_object.hpp similarity index 96% rename from src/imview/test/feature/scene_objects/opengl_scene_object.hpp rename to src/viewer/test/feature/scene_objects/opengl_scene_object.hpp index 3179536..e1ad012 100644 --- a/src/imview/test/feature/scene_objects/opengl_scene_object.hpp +++ b/src/viewer/test/feature/scene_objects/opengl_scene_object.hpp @@ -9,7 +9,7 @@ #define QUICKVIZ_OPENGL_SCENE_OBJECT_HPP #include "glad/glad.h" -#include "imview/panel.hpp" +#include "viewer/panel.hpp" namespace quickviz { class OpenGLSceneObject : public Panel { diff --git a/src/imview/test/feature/test_auto_layout.cpp b/src/viewer/test/feature/test_auto_layout.cpp similarity index 97% rename from src/imview/test/feature/test_auto_layout.cpp rename to src/viewer/test/feature/test_auto_layout.cpp index 2a05fc9..f2640d7 100644 --- a/src/imview/test/feature/test_auto_layout.cpp +++ b/src/viewer/test/feature/test_auto_layout.cpp @@ -9,8 +9,8 @@ #include -#include "imview/viewer.hpp" -#include "imview/box.hpp" +#include "viewer/viewer.hpp" +#include "viewer/box.hpp" #include "scene_objects/imtext_panel.hpp" #include "scene_objects/imgui_fixed_panel.hpp" diff --git a/src/imview/test/feature/test_centralized_input.cpp b/src/viewer/test/feature/test_centralized_input.cpp similarity index 97% rename from src/imview/test/feature/test_centralized_input.cpp rename to src/viewer/test/feature/test_centralized_input.cpp index d0acdad..73ec8cf 100644 --- a/src/imview/test/feature/test_centralized_input.cpp +++ b/src/viewer/test/feature/test_centralized_input.cpp @@ -10,9 +10,9 @@ #include #include -#include "imview/window.hpp" -#include "imview/panel.hpp" -#include "imview/input/gamepad_manager.hpp" +#include "viewer/window.hpp" +#include "viewer/panel.hpp" +#include "viewer/input/gamepad_manager.hpp" #include "core/event/input_event.hpp" using namespace quickviz; diff --git a/src/imview/test/feature/test_joystick_input.cpp b/src/viewer/test/feature/test_joystick_input.cpp similarity index 98% rename from src/imview/test/feature/test_joystick_input.cpp rename to src/viewer/test/feature/test_joystick_input.cpp index 073666d..08264db 100644 --- a/src/imview/test/feature/test_joystick_input.cpp +++ b/src/viewer/test/feature/test_joystick_input.cpp @@ -10,9 +10,9 @@ #include #include -#include "imview/panel.hpp" -#include "imview/viewer.hpp" -#include "imview/input/gamepad_manager.hpp" +#include "viewer/panel.hpp" +#include "viewer/viewer.hpp" +#include "viewer/input/gamepad_manager.hpp" using namespace quickviz; diff --git a/src/imview/test/feature/test_keyboard_mouse_input.cpp b/src/viewer/test/feature/test_keyboard_mouse_input.cpp similarity index 99% rename from src/imview/test/feature/test_keyboard_mouse_input.cpp rename to src/viewer/test/feature/test_keyboard_mouse_input.cpp index 97ad9f4..b43bc55 100644 --- a/src/imview/test/feature/test_keyboard_mouse_input.cpp +++ b/src/viewer/test/feature/test_keyboard_mouse_input.cpp @@ -13,8 +13,8 @@ #include #include -#include "imview/panel.hpp" -#include "imview/viewer.hpp" +#include "viewer/panel.hpp" +#include "viewer/viewer.hpp" using namespace quickviz; diff --git a/src/imview/test/feature/test_popup.cpp b/src/viewer/test/feature/test_popup.cpp similarity index 91% rename from src/imview/test/feature/test_popup.cpp rename to src/viewer/test/feature/test_popup.cpp index efde977..191779a 100644 --- a/src/imview/test/feature/test_popup.cpp +++ b/src/viewer/test/feature/test_popup.cpp @@ -9,13 +9,13 @@ #include -#include "imview/viewer.hpp" -#include "imview/box.hpp" +#include "viewer/viewer.hpp" +#include "viewer/box.hpp" -#include "imview/panel.hpp" -#include "imview/popup.hpp" +#include "viewer/panel.hpp" +#include "viewer/popup.hpp" -#include "imview/popup_manager.hpp" +#include "viewer/popup_manager.hpp" using namespace quickviz; diff --git a/src/imview/test/feature/test_tui_composer.cpp b/src/viewer/test/feature/test_tui_composer.cpp similarity index 96% rename from src/imview/test/feature/test_tui_composer.cpp rename to src/viewer/test/feature/test_tui_composer.cpp index 1192a26..0e7851d 100644 --- a/src/imview/test/feature/test_tui_composer.cpp +++ b/src/viewer/test/feature/test_tui_composer.cpp @@ -7,8 +7,8 @@ * Copyright (c) 2025 Ruixiang Du (rdu) */ -#include "imview/box.hpp" -#include "imview/terminal/tui_viewer.hpp" +#include "viewer/box.hpp" +#include "viewer/terminal/tui_viewer.hpp" using namespace quickviz; diff --git a/src/imview/test/feature/test_viewer.cpp b/src/viewer/test/feature/test_viewer.cpp similarity index 98% rename from src/imview/test/feature/test_viewer.cpp rename to src/viewer/test/feature/test_viewer.cpp index 66bda5e..5b0bd71 100644 --- a/src/imview/test/feature/test_viewer.cpp +++ b/src/viewer/test/feature/test_viewer.cpp @@ -9,8 +9,8 @@ #include -#include "imview/viewer.hpp" -#include "imview/box.hpp" +#include "viewer/viewer.hpp" +#include "viewer/box.hpp" #include "scene_objects/imtext_panel.hpp" #include "scene_objects/imgui_fixed_panel.hpp" diff --git a/src/imview/test/feature/test_window.cpp b/src/viewer/test/feature/test_window.cpp similarity index 97% rename from src/imview/test/feature/test_window.cpp rename to src/viewer/test/feature/test_window.cpp index 4225fbf..d2e893a 100644 --- a/src/imview/test/feature/test_window.cpp +++ b/src/viewer/test/feature/test_window.cpp @@ -10,7 +10,7 @@ #include #include "glad/glad.h" -#include "imview/window.hpp" +#include "viewer/window.hpp" using namespace quickviz; diff --git a/src/imview/test/test_box.cpp b/src/viewer/test/test_box.cpp similarity index 96% rename from src/imview/test/test_box.cpp rename to src/viewer/test/test_box.cpp index b2289b7..29c99c2 100644 --- a/src/imview/test/test_box.cpp +++ b/src/viewer/test/test_box.cpp @@ -8,8 +8,8 @@ #include -#include "imview/viewer.hpp" -#include "imview/box.hpp" +#include "viewer/viewer.hpp" +#include "viewer/box.hpp" #include "feature/scene_objects/imgui_fixed_panel.hpp" diff --git a/src/imview/test/test_box_inside_box.cpp b/src/viewer/test/test_box_inside_box.cpp similarity index 97% rename from src/imview/test/test_box_inside_box.cpp rename to src/viewer/test/test_box_inside_box.cpp index 0ffb7aa..1ec973c 100644 --- a/src/imview/test/test_box_inside_box.cpp +++ b/src/viewer/test/test_box_inside_box.cpp @@ -9,8 +9,8 @@ #include -#include "imview/viewer.hpp" -#include "imview/box.hpp" +#include "viewer/viewer.hpp" +#include "viewer/box.hpp" #include "feature/scene_objects/imtext_panel.hpp" #include "feature/scene_objects/imgui_fixed_panel.hpp" diff --git a/src/imview/test/test_panel.cpp b/src/viewer/test/test_panel.cpp similarity index 98% rename from src/imview/test/test_panel.cpp rename to src/viewer/test/test_panel.cpp index 7e5518b..ee809b0 100644 --- a/src/imview/test/test_panel.cpp +++ b/src/viewer/test/test_panel.cpp @@ -7,8 +7,8 @@ * Copyright (c) 2021 Weston Robot Pte. Ltd. */ -#include "imview/viewer.hpp" -#include "imview/panel.hpp" +#include "viewer/viewer.hpp" +#include "viewer/panel.hpp" using namespace quickviz::swviz; diff --git a/src/imview/test/test_viewer_fonts.cpp b/src/viewer/test/test_viewer_fonts.cpp similarity index 98% rename from src/imview/test/test_viewer_fonts.cpp rename to src/viewer/test/test_viewer_fonts.cpp index 9a16577..58c481e 100644 --- a/src/imview/test/test_viewer_fonts.cpp +++ b/src/viewer/test/test_viewer_fonts.cpp @@ -7,7 +7,7 @@ * Copyright (c) 2021 Ruixiang Du (rdu) */ -#include "imview/viewer.hpp" +#include "viewer/viewer.hpp" using namespace quickviz; diff --git a/src/imview/test/test_window_gl_triangle.cpp b/src/viewer/test/test_window_gl_triangle.cpp similarity index 99% rename from src/imview/test/test_window_gl_triangle.cpp rename to src/viewer/test/test_window_gl_triangle.cpp index 7dcffd5..8c622c8 100644 --- a/src/imview/test/test_window_gl_triangle.cpp +++ b/src/viewer/test/test_window_gl_triangle.cpp @@ -9,7 +9,7 @@ #include -#include "imview/window.hpp" +#include "viewer/window.hpp" using namespace quickviz; diff --git a/src/widget/CMakeLists.txt b/src/widget/CMakeLists.txt deleted file mode 100644 index a38db2c..0000000 --- a/src/widget/CMakeLists.txt +++ /dev/null @@ -1,57 +0,0 @@ -# find dependency -find_package(PkgConfig REQUIRED) -pkg_check_modules(Cairo REQUIRED IMPORTED_TARGET cairo) -pkg_check_modules(Fontconfig REQUIRED IMPORTED_TARGET fontconfig) - -find_package(Threads REQUIRED) -find_package(OpenGL REQUIRED) - -# (optional) OpenCV support -find_package(OpenCV QUIET) -if(OpenCV_FOUND) - message(STATUS "OpenCV found: ${OpenCV_VERSION}") - set(ENABLE_OPENCV_SUPPORT ON) - set(OPENCV_COMP_SRC - src/details/image_utils.cpp - src/cv_image_widget.cpp - src/buffered_cv_image_widget.cpp) - set(OPENCV_COMP_LIBS ${OpenCV_LIBS}) -else() - message(STATUS "OpenCV not found") -endif() - -# add library -add_library(widget - # widgets - src/details/cairo_context.cpp - src/details/cairo_draw.cpp - src/details/scrolling_plot_buffer.cpp - src/cairo_widget.cpp - src/rt_line_plot_widget.cpp - ${OPENCV_COMP_SRC}) -target_link_libraries(widget PUBLIC - core - imcore imview - stb - PkgConfig::Cairo PkgConfig::Fontconfig - Threads::Threads - OpenGL::GL - ${OPENCV_COMP_LIBS}) -target_include_directories(widget PUBLIC - $ - $ - PRIVATE src) - -if(BUILD_TESTING) - add_subdirectory(test) -endif() - -install(TARGETS widget - EXPORT quickvizTargets - LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib - RUNTIME DESTINATION bin - INCLUDES DESTINATION include) - -install(DIRECTORY include/ - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) diff --git a/src/widget/test/CMakeLists.txt b/src/widget/test/CMakeLists.txt deleted file mode 100644 index b20f894..0000000 --- a/src/widget/test/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -add_executable(test_implot_widget test_implot_widget.cpp) -target_link_libraries(test_implot_widget PRIVATE widget) - -add_executable(test_cairo_widget test_cairo_widget.cpp) -target_link_libraries(test_cairo_widget PRIVATE widget) - -if(ENABLE_OPENCV_SUPPORT) - add_executable(test_cv_image_widget test_cv_image_widget.cpp) - target_link_libraries(test_cv_image_widget PRIVATE widget) - - add_executable(test_buffered_cv_image_widget test_buffered_cv_image_widget.cpp) - target_link_libraries(test_buffered_cv_image_widget PRIVATE widget) -endif() diff --git a/src/widget/test/test_cairo_context.cpp b/src/widget/test/test_cairo_context.cpp deleted file mode 100644 index e7ecd0d..0000000 --- a/src/widget/test/test_cairo_context.cpp +++ /dev/null @@ -1,80 +0,0 @@ -/* - * test_cairo_canvas.cpp - * - * Created on: Dec 03, 2020 21:27 - * Description: - * - * Copyright (c) 2020 Ruixiang Du - */ - -#include - -#include "imview/viewer.hpp" -#include "imview/cairo_widget.hpp" - -using namespace quickviz::swviz; - -void Paint(cairo_t* cr); - -struct DrawArc : public Viewer { - DrawArc() { ctx1_ = std::make_shared(320, 240); } - - std::shared_ptr ctx1_; - - void Update() override { - ImVec2 panel_size = {ImGui::GetIO().DisplaySize.x / 2.0f, - ImGui::GetIO().DisplaySize.y / 2.0f}; - - // show on imgui - { - ImGui::SetNextWindowPos(ImVec2(0, 0)); - ImGui::SetNextWindowSize(panel_size); - - ImGui::Begin("Cairo Canvas 1", NULL, - ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoTitleBar | - ImGuiWindowFlags_NoBringToFrontOnFocus | - ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoCollapse | - ImGuiWindowFlags_NoResize | - ImGuiWindowFlags_NoScrollbar); - - // do paint with cairo - ctx1_->Draw(Paint); - - // GLuint image = ctx1_->RenderToGlTexture(); - // ImGui::Image((void*)(intptr_t)image, ImGui::GetContentRegionAvail()); - - ImGui::End(); - } - } -}; - -void Paint(cairo_t* cr) { - cairo_set_source_rgba(cr, 0.5, 0.5, 0.5, 0.6); - cairo_paint(cr); - - double x = 25.6, y = 128.0; - double x1 = 102.4, y1 = 230.4, x2 = 153.6, y2 = 25.6, x3 = 230.4, y3 = 128.0; - - cairo_set_source_rgba(cr, 0.2, 0.2, 0.2, 0.6); - - cairo_move_to(cr, x, y); - cairo_curve_to(cr, x1, y1, x2, y2, x3, y3); - - cairo_set_line_width(cr, 10.0); - cairo_stroke(cr); - - cairo_set_source_rgba(cr, 1, 0.2, 0.2, 0.6); - cairo_set_line_width(cr, 6.0); - cairo_move_to(cr, x, y); - cairo_line_to(cr, x1, y1); - cairo_move_to(cr, x2, y2); - cairo_line_to(cr, x3, y3); - cairo_stroke(cr); -} - -int main(int argc, const char* argv[]) { - DrawArc cc; - cc.Show(); - - return 0; -} \ No newline at end of file diff --git a/src/widget/test/test_cairo_draw.cpp b/src/widget/test/test_cairo_draw.cpp deleted file mode 100644 index fdc635a..0000000 --- a/src/widget/test/test_cairo_draw.cpp +++ /dev/null @@ -1,119 +0,0 @@ -/* - * test_imgui.cpp - * - * Created on: Mar 04, 2021 15:02 - * Description: - * - * Copyright (c) 2021 Ruixiang Du (rdu) - */ - -#include - -#include "imview/viewer.hpp" -#include "imview/cairo_widget.hpp" -#include "imview/cairo_draw.hpp" - -using namespace quickviz::swviz; - -const std::string img_file = "../data/screenshots/sampling/rrts.png"; - -class MyWin : public Viewer { - public: - MyWin(std::string title = "Canvas", uint32_t width = 1080, - uint32_t height = 720) - : Viewer(title, width, height), cairo_panel_{width, height} { - cairo_panel_.LoadImage(img_file); - } - - bool show_demo_window = true; - bool show_another_window = false; - ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); - double b = 0.0001; - - void Update() override { - ShowCairoPanel(); - ShowImPanel(); - } - - void Paint(cairo_t* cr) { - DrawPoint(cr, {860, 200}); - DrawPoint(cr, {1060, 200}, 10, {1, 0.2, 0.2, 0.6}); - - DrawLine(cr, {860, 150}, {1060, 150}); - DrawLine(cr, {860, 250}, {1060, 250}, 2, {1, 0.2, 0.2, 0.6}); - - DrawCircle(cr, {960, 540}, 30); - DrawCircle(cr, {960, 540}, 50, 5, {1, 0.2, 0.2, 0.6}); - - DrawRing(cr, {960, 540}, 100, 130, 0, M_PI / 4.0); - DrawRing(cr, {960, 540}, 140, 180, 0, M_PI / 4.0, 5, colors[GREEN]); - - DrawRing(cr, {960, 540}, 100, 200, M_PI, M_PI * 1.5f, 5, colors[YELLOW], - true); - DrawRing(cr, {960, 540}, 140, 220, M_PI / 2.0, 2 * M_PI / 3.0, 5, - colors[GREEN], true); - DrawRing(cr, {960, 540}, 140, 220, M_PI / 2.0, 5 * M_PI / 6.0, 5, - colors[PURPLE], false); - - DrawArc(cr, {600, 800}, 60, M_PI, 2 * M_PI / 4.0); - DrawArc(cr, {600, 800}, 70, M_PI / 4.0, M_PI, 5, {1, 0.2, 0.2, 0.6}); - - DrawArcSector(cr, {1060, 800}, 60, 0, -M_PI / 4.0); - DrawArcSector(cr, {1060, 800}, 80, M_PI / 4.0, M_PI, 5, {1, 0.2, 0.2, 0.6}); - DrawArcSector(cr, {1060, 800}, 85, 5.0 * M_PI / 4.0, 6.0 * M_PI / 4.0, 5, - {1, 0.2, 0.2, 0.3}, true); - - DrawRectangle(cr, {400, 400}, {500, 600}); - DrawRectangle(cr, {550, 400}, {600, 600}, 5, colors[MAGENTA]); - DrawRectangle(cr, {650, 400}, {700, 600}, 5, colors[CYAN], true); - - for (int i = 0; i < COLOR_LAST; ++i) { - DrawLine(cr, {200.0f, 300.0f + 20 * i}, {250.0f, 300.0f + 20 * i}, 10, - colors[i]); - } - } - - void ShowCairoPanel() { - ImGui::SetNextWindowPos(ImVec2(0, 0)); - ImGui::SetNextWindowSize(ImVec2(window_->GetWidth(), window_->GetHeight())); - - ImGui::Begin("Cairo Canvas", NULL, - ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoMove | - ImGuiWindowFlags_NoBringToFrontOnFocus | - ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoCollapse | - ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoScrollbar | - ImGuiWindowFlags_NoBackground); - - int width, height; - glfwGetWindowSize(window_->GetGlfwWindow(), &width, &height); - cairo_panel_.Resize(width, height); - - cairo_panel_.Fill(); - // cairo_panel_.Draw(img_file, 0, 0, M_PI / 4.0f); - cairo_panel_.Draw(std::bind(&MyWin::Paint, this, std::placeholders::_1)); - // cairo_panel_.DrawText("Hello World, Canvas", 100, 100); - - cairo_panel_.Render(); - - ImGui::End(); - } - - void ShowImPanel() { - ImGui::Begin("ImPanel"); - ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", - 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); - ImGui::End(); - } - - private: - CairoWidget cairo_panel_; -}; - -int main(int argc, char* argv[]) { - // MyWin win(1280, 720); - MyWin win("cairo_draw", 1920, 1080); - // MyWin win(1080, 720); - - win.Show(); - return 0; -} diff --git a/src/widget/test/test_cairo_normalize.cpp b/src/widget/test/test_cairo_normalize.cpp deleted file mode 100644 index b0f1884..0000000 --- a/src/widget/test/test_cairo_normalize.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/* - * test_imgui.cpp - * - * Created on: Mar 04, 2021 15:02 - * Description: - * - * Copyright (c) 2021 Ruixiang Du (rdu) - */ - -#include - -#include "imview/viewer.hpp" -#include "imview/cairo_widget.hpp" -#include "imview/cairo_draw.hpp" - -using namespace quickviz::swviz; - -const std::string img_file = "../image/fish.png"; - -class MyWin : public Viewer { - public: - MyWin(std::string title, uint32_t width, uint32_t height) - : Viewer(title, width, height), cairo_panel_{width, height, true} { - cairo_panel_.LoadImage(img_file); - } - - bool show_demo_window = true; - bool show_another_window = false; - ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); - double b = 0.0001; - - void Update() override { - ImGui::SetNextWindowPos(ImVec2(0, 0)); - ImGui::SetNextWindowSize(ImVec2(window_->GetWidth(), window_->GetHeight())); - - ImGui::Begin("Cairo Canvas", NULL, - ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoMove | - ImGuiWindowFlags_NoBringToFrontOnFocus | - ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoCollapse | - ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoScrollbar | - ImGuiWindowFlags_NoBackground); - - ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", - 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); - - int width, height; - glfwGetWindowSize(window_->GetGlfwWindow(), &width, &height); - cairo_panel_.Resize(window_->GetWidth(), window_->GetHeight()); - - cairo_panel_.Fill(); - cairo_panel_.Draw(std::bind(&MyWin::Paint, this, std::placeholders::_1)); - - cairo_panel_.DrawText("1.5 m/s", 0.5, 0.5, 0.0, {0.5, 0.5, 0.5, 1}, 0.0140, - 0.05); - - cairo_panel_.Render(); - - ImGui::End(); - } - - void Paint(cairo_t* cr) { - float ratio = - window_->GetWidth() / static_cast(window_->GetHeight()); - float pos_x = 0.5 * cairo_panel_.GetAspectRatio(); - float pos_y = 0.5; - - // std::cout << "first: " << ratio - // << " , second: " << cairo_panel_.GetAspectRatio() << std::endl; - - DrawPoint(cr, {pos_x, pos_y}, 0.01, {1, 0.2, 0.2, 0.6}); - DrawCircle(cr, {pos_x, pos_y}, 0.3, 0.002, {1, 0.2, 0.2, 0.6}); - DrawRectangle(cr, {pos_x - 0.2f, pos_y - 0.2f}, - {pos_x + 0.2f, pos_y + 0.2f}, 0.002); - } - - private: - CairoWidget cairo_panel_; -}; - -int main(int argc, char* argv[]) { - // MyWin win(1280, 720); - // MyWin win(1920, 1080); - MyWin win("cairo_normalize", 1080, 720); - - win.Show(); - return 0; -} diff --git a/src/widget/test/test_plot_buffer.cpp b/src/widget/test/test_plot_buffer.cpp deleted file mode 100644 index b3b09c4..0000000 --- a/src/widget/test/test_plot_buffer.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/* - * test_plot_buffer.cpp - * - * Created on: Mar 25, 2021 17:41 - * Description: - * - * Copyright (c) 2021 Ruixiang Du (rdu) - */ - -#include - -#include "imview/viewer.hpp" -#include "imview/data_buffer.hpp" - -using namespace quickviz::swviz; - -struct ImDraw : public Viewer { - void Update() override { - // do nothing - ImGui::BulletText("Move your mouse to change the data!"); - ImGui::BulletText( - "This example assumes 60 FPS. Higher FPS requires larger buffer " - "size."); - static DataBuffer sdata1; - static DataBuffer sdata2; - - ImVec2 mouse = ImGui::GetMousePos(); - static float t = 0; - t += ImGui::GetIO().DeltaTime; - sdata1.AddPoint(t, mouse.x * 0.0005f); - sdata2.AddPoint(t, mouse.y * 0.0005f); - - static float history = 10.0f; - ImGui::SliderFloat("History", &history, 1, 30, "%.1f s"); - - static ImPlotAxisFlags rt_axis = ImPlotAxisFlags_NoTickLabels; - // ImPlot::SetNextPlotLimitsX(t - history, t, ImGuiCond_Always); - - if (ImPlot::BeginPlot("##Scrolling")) { - ImPlot::PlotShaded("Data 1", &(sdata1[0].x), &(sdata1[0].y), - sdata1.GetSize(), 0, sdata1.GetOffset(), - 2 * sizeof(float)); - ImPlot::PlotLine("Data 2", &(sdata1[0].x), &(sdata1[0].y), - sdata2.GetSize(), sdata2.GetOffset(), 2 * sizeof(float)); - ImPlot::EndPlot(); - - // std::cout << "buffer size: " << sdata1.GetSize() << std::endl; - } - } -}; - -int main(int argc, char *argv[]) { - ImDraw canvas; - canvas.Show(); - return 0; -} \ No newline at end of file diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 18839ce..3e76051 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -60,7 +60,7 @@ add_executable(test_geometric_primitive_types target_link_libraries(test_geometric_primitive_types PRIVATE gtest_main - gldraw + scene test_utils ) gtest_discover_tests(test_geometric_primitive_types @@ -78,8 +78,8 @@ add_executable(test_renderer_pipeline target_link_libraries(test_renderer_pipeline PRIVATE gtest_main - imview - gldraw + viewer + scene_test_utils test_utils ) gtest_discover_tests(test_renderer_pipeline @@ -87,16 +87,16 @@ gtest_discover_tests(test_renderer_pipeline ) # ImView integration tests -add_executable(test_imview_integration - integration/test_imview_integration.cpp +add_executable(test_viewer_integration + integration/test_viewer_integration.cpp ) -target_link_libraries(test_imview_integration +target_link_libraries(test_viewer_integration PRIVATE gtest_main - imview + viewer test_utils ) -gtest_discover_tests(test_imview_integration +gtest_discover_tests(test_viewer_integration PROPERTIES LABELS "integration" ) @@ -111,8 +111,8 @@ add_executable(test_memory_leaks target_link_libraries(test_memory_leaks PRIVATE gtest_main - imview - gldraw + viewer + scene test_utils ) gtest_discover_tests(test_memory_leaks @@ -131,8 +131,8 @@ if(benchmark_FOUND) target_link_libraries(benchmark_rendering PRIVATE benchmark::benchmark - imview - gldraw + viewer + scene core ) @@ -214,8 +214,8 @@ if(ENABLE_COVERAGE AND CMAKE_BUILD_TYPE STREQUAL "Debug") target_compile_options(test_renderer_pipeline PRIVATE --coverage) target_link_options(test_renderer_pipeline PRIVATE --coverage) - target_compile_options(test_imview_integration PRIVATE --coverage) - target_link_options(test_imview_integration PRIVATE --coverage) + target_compile_options(test_viewer_integration PRIVATE --coverage) + target_link_options(test_viewer_integration PRIVATE --coverage) target_compile_options(test_memory_leaks PRIVATE --coverage) target_link_options(test_memory_leaks PRIVATE --coverage) diff --git a/tests/README.md b/tests/README.md index 5827cf9..7fa9cd1 100644 --- a/tests/README.md +++ b/tests/README.md @@ -26,7 +26,7 @@ tests/ ### 2. Integration Tests (`integration/`) - **Renderer Pipeline Tests** (`test_renderer_pipeline.cpp`): End-to-end rendering pipeline testing -- **ImView Integration Tests** (`test_imview_integration.cpp`): GUI component integration testing +- **ImView Integration Tests** (`test_viewer_integration.cpp`): GUI component integration testing ### 3. Performance Benchmarks (`benchmarks/`) diff --git a/tests/benchmarks/profile_canvas_performance.cpp b/tests/benchmarks/profile_canvas_performance.cpp index 37ae78f..86a2948 100644 --- a/tests/benchmarks/profile_canvas_performance.cpp +++ b/tests/benchmarks/profile_canvas_performance.cpp @@ -19,7 +19,7 @@ #include #include -#include "gldraw/renderable/canvas.hpp" +#include "scene/renderable/canvas.hpp" using namespace quickviz; using namespace std::chrono; diff --git a/tests/integration/test_renderer_pipeline.cpp b/tests/integration/test_renderer_pipeline.cpp index d259f4a..19ecc9f 100644 --- a/tests/integration/test_renderer_pipeline.cpp +++ b/tests/integration/test_renderer_pipeline.cpp @@ -13,13 +13,13 @@ #include #include -#include "imview/viewer.hpp" -#include "gldraw/gl_scene_panel.hpp" -#include "gldraw/renderable/triangle.hpp" -#include "gldraw/renderable/point_cloud.hpp" -#include "gldraw/renderable/grid.hpp" -#include "gldraw/camera.hpp" -#include "gldraw/camera_controller.hpp" +#include "viewer/viewer.hpp" +#include "scene/gl_scene_panel.hpp" +#include "test_utils/triangle.hpp" +#include "scene/renderable/point_cloud.hpp" +#include "scene/renderable/grid.hpp" +#include "scene/camera.hpp" +#include "scene/camera_controller.hpp" using namespace quickviz; diff --git a/tests/integration/test_imview_integration.cpp b/tests/integration/test_viewer_integration.cpp similarity index 95% rename from tests/integration/test_imview_integration.cpp rename to tests/integration/test_viewer_integration.cpp index fc5b1e5..19aa513 100644 --- a/tests/integration/test_imview_integration.cpp +++ b/tests/integration/test_viewer_integration.cpp @@ -1,5 +1,5 @@ /* - * @file test_imview_integration.cpp + * @file test_viewer_integration.cpp * @date 2024-06-25 * @brief Integration tests for ImView GUI components * @@ -11,11 +11,11 @@ #include #include -#include "imview/viewer.hpp" -#include "imview/panel.hpp" -#include "imview/box.hpp" -#include "imview/scene_object.hpp" -#include "imview/styling.hpp" +#include "viewer/viewer.hpp" +#include "viewer/panel.hpp" +#include "viewer/box.hpp" +#include "viewer/scene_object.hpp" +#include "viewer/styling.hpp" using namespace quickviz; diff --git a/tests/unit/test_geometric_primitive_types.cpp b/tests/unit/test_geometric_primitive_types.cpp index 9b130a8..819ff98 100644 --- a/tests/unit/test_geometric_primitive_types.cpp +++ b/tests/unit/test_geometric_primitive_types.cpp @@ -13,7 +13,7 @@ #include #include -#include "gldraw/renderable/geometric_primitive.hpp" +#include "scene/renderable/geometric_primitive.hpp" using namespace quickviz; diff --git a/third_party/imcore/CMakeLists.txt b/third_party/imcore/CMakeLists.txt index 434b862..499ae25 100644 --- a/third_party/imcore/CMakeLists.txt +++ b/third_party/imcore/CMakeLists.txt @@ -23,7 +23,13 @@ set(IMPLOT_SRC implot/implot_items.cpp implot/implot_demo.cpp ) -add_library(imcore ${IMGUI_CORE_SRC} ${IMGUI_BACKEND_SRC} ${IMPLOT_SRC}) +set(IMPLOT3D_SRC + implot3d/implot3d.cpp + implot3d/implot3d_items.cpp + implot3d/implot3d_meshes.cpp + implot3d/implot3d_demo.cpp +) +add_library(imcore ${IMGUI_CORE_SRC} ${IMGUI_BACKEND_SRC} ${IMPLOT_SRC} ${IMPLOT3D_SRC}) target_link_libraries(imcore PUBLIC glfw OpenGL::GL ${GLFW3_LIBRARY} ${CMAKE_DL_LIBS}) target_compile_definitions(imcore PUBLIC "-DIMGUI_IMPL_OPENGL_LOADER_GL3W") target_include_directories(imcore PUBLIC @@ -42,6 +48,6 @@ install(TARGETS imcore RUNTIME DESTINATION bin INCLUDES DESTINATION include) -install(DIRECTORY imgui implot +install(DIRECTORY imgui implot implot3d DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} PATTERN "*.h*") \ No newline at end of file diff --git a/third_party/imcore/implot3d b/third_party/imcore/implot3d new file mode 160000 index 0000000..41ae3e4 --- /dev/null +++ b/third_party/imcore/implot3d @@ -0,0 +1 @@ +Subproject commit 41ae3e447c0de20ecab95d38a4b4dc0835a3efc2