-
Notifications
You must be signed in to change notification settings - Fork 19
Expose Viewport Dimensions Through fvdb.viz API #550
Description
Expose Viewport Dimensions Through fvdb.viz API
Problem
The image2d.slang overlay shader in nanovdb-editor uses 1:1 pixel mapping, so any overlay image must match the viewport's exact resolution for correct alignment. Currently the viewport dimensions (updated if window resizes) are only available as stack-local variables inside the render loop. They need to be exposed through the Python API so consumers can render overlays at the correct resolution.
Architecture
flowchart LR
subgraph NanovdbEditor ["nanovdb-editor"]
RenderLoop["show() render loop"] -->|"atomic store"| ImplAtomics["EditorImpl atomics"]
ImplAtomics -->|"read"| EditorAPI["pnanovdb_editor_t API"]
end
subgraph FvdbCore ["fvdb-core"]
EditorAPI --> Viewer["Viewer.cpp getters"]
Viewer --> Pybind["ViewerBinding.cpp"]
Pybind --> ScenePy["_scene.py properties"]
end
Changes: nanovdb-editor
1. Add atomic viewport dimension members to EditorImpl
In editor/Editor.h, add two atomic members to pnanovdb_editor_impl_t (alongside the existing show_active atomic, around line 82):
std::atomic<pnanovdb_int32_t> viewport_width{0};
std::atomic<pnanovdb_int32_t> viewport_height{0};2. Store dimensions in the render loop
In editor/Editor.cpp, store the viewport dimensions at two points:
a) After the initial resolution is determined from INI/defaults (around line 452), so values are available before the first render frame:
editor->impl->viewport_width.store(image_width, std::memory_order_relaxed);
editor->impl->viewport_height.store(image_height, std::memory_order_relaxed);b) After get_camera_view_proj updates image_width/image_height each frame (line 642):
imgui_window_iface->get_camera_view_proj(imgui_window, &image_width, &image_height, &view, &projection);
editor->impl->viewport_width.store(image_width, std::memory_order_relaxed);
editor->impl->viewport_height.store(image_height, std::memory_order_relaxed);3. Expose through the pnanovdb_editor_t interface
In nanovdb_editor/putil/Editor.h, add function pointers to the pnanovdb_editor_t interface for reading the viewport dimensions, following the pattern of existing getters like get_resolved_port. The implementations read from the atomics added in step 1.
Changes: fvdb-core
4. Add C++ getters to the Viewer class
In src/fvdb/detail/viewer/Viewer.h, declare read-only getters:
int viewportWidth(const std::string &scene_name);
int viewportHeight(const std::string &scene_name);In src/fvdb/detail/viewer/Viewer.cpp, implement by calling the new nanovdb-editor API from step 3. These do NOT need getCamera() since viewport dimensions are not part of the camera struct. No setters -- viewport size is controlled by the browser window. scene_name is kept for API consistency even though the viewport is scene-independent.
5. Add pybind11 bindings
In src/python/ViewerBinding.cpp, add bindings following the camera_fov pattern:
.def("viewport_width",
&fvdb::detail::viewer::Viewer::viewportWidth,
py::arg("scene_name"),
"Get the viewport render width in pixels")
.def("viewport_height",
&fvdb::detail::viewer::Viewer::viewportHeight,
py::arg("scene_name"),
"Get the viewport render height in pixels")6. Add Python properties to _scene.py
In fvdb/viz/_scene.py, add read-only properties (after camera_fov):
@property
def viewport_width(self) -> int:
"""Return the viewport render width in pixels."""
server = _get_viewer_server_cpp()
return server.viewport_width(self._name)
@property
def viewport_height(self) -> int:
"""Return the viewport render height in pixels."""
server = _get_viewer_server_cpp()
return server.viewport_height(self._name)Thread safety
memory_order_relaxed is sufficient -- we only need eventual visibility, not ordering guarantees. The Python API reading a slightly stale value for one frame is acceptable. This matches the existing pattern used by resolved_port and show_active in pnanovdb_editor_impl_t.