code: def test_estimate_normals(self):
      for with_normals in (True, False):
          for run_padded in (True, False):
              for run_packed in (True, False):
                  clouds = TestPointclouds.init_cloud(
                      3,
                      100,
                      with_normals=with_normals,
                      with_features=False,
                      min_points=60,
                  )
                  nums = clouds.num_points_per_cloud()
                  if run_padded:
                      clouds.points_padded()
                  if run_packed:
                      clouds.points_packed()
  
                  normals_est_padded = clouds.estimate_normals(
                      assign_to_self=True
                  )
                  normals_est_list = struct_utils.padded_to_list(
                      normals_est_padded, nums.tolist()
                  )
                  self.assertClose(
                      clouds.normals_padded(), normals_est_padded
                  )
                  for i in range(len(clouds)):
                      self.assertClose(
                          clouds.normals_list()[i], normals_est_list[i]
                      )
                  self.assertClose(
                      clouds.normals_packed(),
                      torch.cat(normals_est_list, dim=0),
                  )
  
imports: import itertools
  import random
  import unittest
  import numpy
  import torch
  from pytorch3d.structures import utils
  from pytorch3d.structures.pointclouds import join_pointclouds_as_batch, join_pointclouds_as_scene, Pointclouds
  from .common_testing import TestCaseMixin
label_desc: Use image node_id 27 for calling the TestPointclouds obj's underlying member method code with example usage: obj.test_estimate_normals() without return types