docstr: Use PyTorch3D point renderer to render a colored point cloud, then
  sample the image at the locations of the point projections with
  `ndc_grid_sample`. Finally, assert that the sampled colors are equal to the
  original point cloud colors.
  
  Note that, in order to ensure correctness, we use a nearest-neighbor
  assignment point renderer (i.e. no soft splatting).
docstr_tok: ["Use","PyTorch3D","point","renderer","to","render","a","colored","point","cloud",",","then","sample","the","image","at","the","locations","of","the","point","projections","with","`","ndc_grid_sample","`",".","Finally",",","assert","that","the","sampled","colors","are","equal","to","the","original","point","cloud","colors",".","Note","that",",","in","order","to","ensure","correctness",",","we","use","a","nearest-neighbor","assignment","point","renderer","(","i.e",".","no","soft","splatting",")","."]
code: def test_ndc_grid_sample_rendering(self):
      """
      Use PyTorch3D point renderer to render a colored point cloud, then
      sample the image at the locations of the point projections with
      `ndc_grid_sample`. Finally, assert that the sampled colors are equal to the
      original point cloud colors.
  
      Note that, in order to ensure correctness, we use a nearest-neighbor
      assignment point renderer (i.e. no soft splatting).
      """
  
      # generate a bunch of 3D points on a regular grid lying in the z-plane
      n_grid_pts = 10
      grid_scale = 0.9
      z_plane = 2.0
      image_size = [128, 128]
      point_radius = 0.015
      n_pts = n_grid_pts * n_grid_pts
      pts = torch.stack(
          meshgrid_ij(
              [torch.linspace(-grid_scale, grid_scale, n_grid_pts)] * 2,
          ),
          dim=-1,
      )
      pts = torch.cat(
          [pts, z_plane * torch.ones_like(pts[..., :1])], dim=-1
      )
      pts = pts.reshape(1, n_pts, 3)
  
      # color the points randomly
      pts_colors = torch.rand(1, n_pts, 3)
  
      # make trivial rendering cameras
      cameras = PerspectiveCameras(
          R=eyes(dim=3, N=1),
          device=pts.device,
          T=torch.zeros(1, 3, dtype=torch.float32, device=pts.device),
      )
  
      # render the point cloud
      pcl = Pointclouds(points=pts, features=pts_colors)
      renderer = NearestNeighborPointsRenderer(
          rasterizer=PointsRasterizer(
              cameras=cameras,
              raster_settings=PointsRasterizationSettings(
                  image_size=image_size,
                  radius=point_radius,
                  points_per_pixel=1,
              ),
          ),
          compositor=AlphaCompositor(),
      )
      im_render = renderer(pcl)
  
      # sample the render at projected pts
      pts_proj = cameras.transform_points(pcl.points_padded())[..., :2]
      pts_colors_sampled = ndc_grid_sample(
          im_render,
          pts_proj,
          mode="nearest",
          align_corners=False,
      ).permute(0, 2, 1)
  
      # assert that the samples are the same as original points
      self.assertClose(pts_colors, pts_colors_sampled, atol=1e-4)
  
imports: import unittest
  import numpy
  import torch
  from pytorch3d.common.compat import meshgrid_ij
  from pytorch3d.ops import eyes
  from pytorch3d.renderer import AlphaCompositor, PerspectiveCameras, PointsRasterizationSettings, PointsRasterizer, PointsRenderer
  from pytorch3d.renderer.utils import ndc_grid_sample, ndc_to_grid_sample_coords, TensorProperties
  from pytorch3d.structures import Pointclouds
  from .common_testing import TestCaseMixin
label_desc: Use image node_id 7 for calling the TestTensorProperties obj's underlying member method code with example usage: obj.test_ndc_grid_sample_rendering() without return types