Source code for fvdb.viz._image_view

# Copyright Contributors to the OpenVDB Project
# SPDX-License-Identifier: Apache-2.0
#

from typing import Any

import torch

from ..types import NumericMaxRank1
from ._viewer_server import _get_viewer_server_cpp


[docs] class ImageView: """ A view for an RGBA8 image in a :class:`fvdb.viz.Scene`. .. note:: Images are stored as NanoVDB grids on the C++ side. The ImageView provides a Python interface for managing the image and updating its contents. """ __PRIVATE__ = object() def __init__( self, scene_name: str, name: str, width: int, height: int, _private: Any = None, ): """ Create a new :class:`ImageView` within a scene with the given name. .. warning:: This constructor is private and should never be called directly. Use :meth:`fvdb.viz.Scene.add_image()` instead. Args: scene_name (str): The name of the scene the view belongs to. name (str): The name of the :class:`ImageView`. width (int): The width of the image in pixels. height (int): The height of the image in pixels. _private (Any): A private object to prevent direct construction. Must be :attr:`ImageView.__PRIVATE__`. """ if _private is not self.__PRIVATE__: raise ValueError("ImageView constructor is private. Use Scene.add_image() instead.") self._scene_name = scene_name self._name = name self._width = width self._height = height @property def name(self) -> str: """ Get the name of the image view. Returns: name (str): The name of this image view. """ return self._name @property def scene_name(self) -> str: """ Get the name of the scene this image view belongs to. Returns: scene_name (str): The name of the scene. """ return self._scene_name @property def width(self) -> int: """ Get the width of the image in pixels. Returns: width (int): The image width. """ return self._width @property def height(self) -> int: """ Get the height of the image in pixels. Returns: height (int): The image height. """ return self._height
[docs] def update(self, rgba_image: NumericMaxRank1): """ Update the image data displayed in the viewer. Args: rgba_image (NumericMaxRank1): A 1D uint8 tensor-like object of size ``width * height * 4`` containing packed RGBA values. Each pixel is represented by 4 consecutive bytes (R, G, B, A) with values in [0, 255]. """ # Convert to torch tensor rgba_tensor = torch.as_tensor(rgba_image) if rgba_tensor.dtype != torch.uint8: raise TypeError(f"rgba_image must have dtype torch.uint8, got {rgba_tensor.dtype}") if rgba_tensor.dim() != 1: raise ValueError(f"rgba_image must be a 1D tensor, got {rgba_tensor.dim()}D") if rgba_tensor.numel() != self._width * self._height * 4: raise ValueError( f"rgba_image must have size width * height * 4 = {self._width * self._height * 4}, " f"got {rgba_tensor.numel()}" ) server = _get_viewer_server_cpp() server.add_image(self._scene_name, self._name, rgba_tensor, self._width, self._height)