class_docstr: Multiscale convolution down (also supports single scale). Convolution kernel is shared accross the scales
  
  Arguments:
      sampler  -- Strategy for sampling the input clouds
      neighbour_finder -- Multiscale strategy for finding neighbours
docstr: Parameters
  ----------
  data: Data
      x -- Previous features [B, C, N]
      pos -- Previous positions [B, N, 3]
  sample_idx: Optional[torch.Tensor]
      can be used to shortcut the sampler [B,K]
docstr_tok: ["Parameters","--","--","--","--","--","data",":","Data","x","--","Previous","features","[","B",",","C",",","N","]","pos","--","Previous","positions","[","B",",","N",",","3","]","sample_idx",":","Optional","[","torch.Tensor","]","can","be","used","to","shortcut","the","sampler","[","B",",","K","]"]
code: def forward(self, data, sample_idx=None, **kwargs):
      """
      Parameters
      ----------
      data: Data
          x -- Previous features [B, C, N]
          pos -- Previous positions [B, N, 3]
      sample_idx: Optional[torch.Tensor]
          can be used to shortcut the sampler [B,K]
      """
      x, pos = data.x, data.pos
      if sample_idx:
          idx = sample_idx
      else:
          idx = self.sampler(pos)
      idx = idx.unsqueeze(-1).repeat(1, 1, pos.shape[-1]).long()
      new_pos = pos.gather(1, idx)
  
      ms_x = []
      for scale_idx in range(self.neighbour_finder.num_scales):
          radius_idx = self.neighbour_finder(
              pos, new_pos, scale_idx=scale_idx
          )
          ms_x.append(self.conv(x, pos, new_pos, radius_idx, scale_idx))
      new_x = torch.cat(ms_x, 1)
  
      new_data = Data(pos=new_pos, x=new_x)
      if self._save_sampling_id:
          setattr(
              new_data,
              "sampling_id_{}".format(self._index),
              idx[:, :, 0],
          )
      return new_data
  
imports: import numpy
  import torch
  from torch.nn import Linear, ReLU, LeakyReLU, BatchNorm1d, Dropout
  from torch_geometric.nn import knn_interpolate, fps, radius, global_max_pool, global_mean_pool, knn
  from torch_geometric.data import Data
  import torch_points_kernels
  from torch_points3d.core.spatial_ops import BaseMSNeighbourFinder
  from torch_points3d.core.base_conv import BaseConvolution
  from torch_points3d.core.common_modules.dense_modules import MLP2D
  from torch_points3d.utils.enums import ConvolutionFormat
  from torch_points3d.utils.model_building_utils.activation_resolver import get_activation
label_desc: Use image node_id 3 for calling the BaseDenseConvolutionDown obj's underlying member method code with example usage: obj.forward(data, sample_idx) and returns: new_data