class_docstr: This class provides functions for working with batches of volumetric grids
  of possibly varying spatial sizes.
  
  VOLUME DENSITIES
  
  The Volumes class can be either constructed from a 5D tensor of
  `densities` of size `batch x density_dim x depth x height x width` or
  from a list of differently-sized 4D tensors `[D_1, ..., D_batch]`,
  where each `D_i` is of size `[density_dim x depth_i x height_i x width_i]`.
  
  In case the `Volumes` object is initialized from the list of `densities`,
  the list of tensors is internally converted to a single 5D tensor by
  zero-padding the relevant dimensions. Both list and padded representations can be
  accessed with the `Volumes.densities()` or `Volumes.densities_list()` getters.
  The sizes of the individual volumes in the structure can be retrieved
  with the `Volumes.get_grid_sizes()` getter.
  
  The `Volumes` class is immutable. I.e. after generating a `Volumes` object,
  one cannot change its properties, such as `self._densities` or `self._features`
  anymore.
  
  
  VOLUME FEATURES
  
  While the `densities` field is intended to represent various measures of the
  "density" of the volume cells (opacity, signed/unsigned distances
  from the nearest surface, ...), one can additionally initialize the
  object with the `features` argument. `features` are either a 5D tensor
  of shape `batch x feature_dim x depth x height x width` or a list of
  of differently-sized 4D tensors `[F_1, ..., F_batch]`,
  where each `F_i` is of size `[feature_dim x depth_i x height_i x width_i]`.
  `features` are intended to describe other properties of volume cells,
  such as per-voxel 3D vectors of RGB colors that can be later used
  for rendering the volume.
  
  
  VOLUME COORDINATES
  
  Additionally, using the `VolumeLocator` class the `Volumes` class keeps track
  of the locations of the centers of the volume cells in the local volume
  coordinates as well as in the world coordinates.
  
      Local coordinates:
          - Represent the locations of the volume cells in the local coordinate
            frame of the volume.
          - The center of the voxel indexed with `[·, ·, 0, 0, 0]` in the volume
            has its 3D local coordinate set to `[-1, -1, -1]`, while the voxel
            at index `[·, ·, depth_i-1, height_i-1, width_i-1]` has its
            3D local coordinate set to `[1, 1, 1]`.
          - The first/second/third coordinate of each of the 3D per-voxel
            XYZ vector denotes the horizontal/vertical/depth-wise position
            respectively. I.e the order of the coordinate dimensions in the
            volume is reversed w.r.t. the order of the 3D coordinate vectors.
          - The intermediate coordinates between `[-1, -1, -1]` and `[1, 1, 1]`.
            are linearly interpolated over the spatial dimensions of the volume.
          - Note that the convention is the same as for the 5D version of the
            `torch.nn.functional.grid_sample` function called with
            the same value of `align_corners` argument.
          - Note that the local coordinate convention of `Volumes`
            (+X = left to right, +Y = top to bottom, +Z = away from the user)
            is *different* from the world coordinate convention of the
            renderer for `Meshes` or `Pointclouds`
            (+X = right to left, +Y = bottom to top, +Z = away from the user).
  
      World coordinates:
          - These define the locations of the centers of the volume cells
            in the world coordinates.
          - They are specified with the following mapping that converts
            points `x_local` in the local coordinates to points `x_world`
            in the world coordinates::
  
                  x_world = (
                      x_local * (volume_size - 1) * 0.5 * voxel_size
                  ) - volume_translation,
  
            here `voxel_size` specifies the size of each voxel of the volume,
            and `volume_translation` is the 3D offset of the central voxel of
            the volume w.r.t. the origin of the world coordinate frame.
            Both `voxel_size` and `volume_translation` are specified in
            the world coordinate units. `volume_size` is the spatial size of
            the volume in form of a 3D vector `[width, height, depth]`.
          - Given the above definition of `x_world`, one can derive the
            inverse mapping from `x_world` to `x_local` as follows::
  
                  x_local = (
                      (x_world + volume_translation) / (0.5 * voxel_size)
                  ) / (volume_size - 1)
  
          - For a trivial volume with `volume_translation==[0, 0, 0]`
            with `voxel_size=-1`, `x_world` would range
            from -(volume_size-1)/2` to `+(volume_size-1)/2`.
  
  Coordinate tensors that denote the locations of each of the volume cells in
  local / world coordinates (with shape `(depth x height x width x 3)`)
  can be retrieved by calling the `Volumes.get_coord_grid()` getter with the
  appropriate `world_coordinates` argument.
  
  Internally, the mapping between `x_local` and `x_world` is represented
  as a `Transform3d` object `Volumes.VolumeLocator._local_to_world_transform`.
  Users can access the relevant transformations with the
  `Volumes.get_world_to_local_coords_transform()` and
  `Volumes.get_local_to_world_coords_transform()`
  functions.
  
  Example coordinate conversion:
      - For a "trivial" volume with `voxel_size = 1.`,
        `volume_translation=[0., 0., 0.]`, and the spatial size of
        `DxHxW = 5x5x5`, the point `x_world = (-2, 0, 2)` gets mapped
        to `x_local=(-1, 0, 1)`.
      - For a "trivial" volume `v` with `voxel_size = 1.`,
        `volume_translation=[0., 0., 0.]`, the following holds:
  
              torch.nn.functional.grid_sample(
                  v.densities(),
                  v.get_coord_grid(world_coordinates=False),
                  align_corners=align_corners,
              ) == v.densities(),
  
          i.e. sampling the volume at trivial local coordinates
          (no scaling with `voxel_size`` or shift with `volume_translation`)
          results in the same volume.
docstr: Return a Transform3d object that converts points in the
  world coordinates to the local coordinate frame of the volume.
  Local volume coordinates are scaled s.t. the coordinates along one
  side of the volume are in range [-1, 1].
  
  Returns:
      **world_to_local_transform**: A Transform3d object converting
          points from world coordinates to local coordinates.
docstr_tok: ["Return","a","Transform3d","object","that","converts","points","in","the","world","coordinates","to","the","local","coordinate","frame","of","the","volume",".","Local","volume","coordinates","are","scaled","s.t",".","the","coordinates","along","one","side","of","the","volume","are","in","range","[","-1",",","1","]",".","Returns",":","*","*","world_to_local_transform","*","*",":","A","Transform3d","object","converting","points","from","world","coordinates","to","local","coordinates","."]
code: def get_world_to_local_coords_transform(self) -> Transform3d:
      """
      Return a Transform3d object that converts points in the
      world coordinates to the local coordinate frame of the volume.
      Local volume coordinates are scaled s.t. the coordinates along one
      side of the volume are in range [-1, 1].
  
      Returns:
          **world_to_local_transform**: A Transform3d object converting
              points from world coordinates to local coordinates.
      """
      return self.get_local_to_world_coords_transform().inverse()
  
imports: import copy
  from typing import List, Optional, Tuple, Union
  import torch
  from pytorch3d.common.compat import meshgrid_ij
  from pytorch3d.common.datatypes import Device, make_device
  from pytorch3d.transforms import Scale, Transform3d
  from .None import utils
label_desc: Use image node_id 21 for calling the Volumes obj's underlying member method code with example usage: obj.get_world_to_local_coords_transform() and returns: self