class_docstr: Subdivide a triangle mesh by adding a new vertex at the center of each edge
  and dividing each face into four new faces. Vectors of vertex
  attributes can also be subdivided by averaging the values of the attributes
  at the two vertices which form each edge. This implementation
  preserves face orientation - if the vertices of a face are all ordered
  counter-clockwise, then the faces in the subdivided meshes will also have
  their vertices ordered counter-clockwise.
  
  If meshes is provided as an input, the initializer performs the relatively
  expensive computation of determining the new face indices. This one-time
  computation can be reused for all meshes with the same face topology
  but different vertex positions.
class_docstr_tok: ["Subdivide","a","triangle","mesh","by","adding","a","new","vertex","at","the","center","of","each","edge","and","dividing","each","face","into","four","new","faces",".","Vectors","of","vertex","attributes","can","also","be","subdivided","by","averaging","the","values","of","the","attributes","at","the","two","vertices","which","form","each","edge",".","This","implementation","preserves","face","orientation","-","if","the","vertices","of","a","face","are","all","ordered","counter-clockwise",",","then","the","faces","in","the","subdivided","meshes","will","also","have","their","vertices","ordered","counter-clockwise",".","If","meshes","is","provided","as","an","input",",","the","initializer","performs","the","relatively","expensive","computation","of","determining","the","new","face","indices",".","This","one-time","computation","can","be","reused","for","all","meshes","with","the","same","face","topology","but","different","vertex","positions","."]
docstr: Subdivide verts (and optionally features) of a batch of meshes
  where each mesh has the same topology of faces. The subdivided faces
  are precomputed in the initializer.
  
  Args:
      meshes: Meshes object representing a batch of meshes.
      feats: Per-vertex features to be subdivided along with the verts.
  
  Returns:
      2-element tuple containing
  
      - **new_meshes**: Meshes object of a batch of subdivided meshes.
      - **new_feats**: (optional) Tensor of subdivided feats, parallel to the
        (packed) vertices of the subdivided meshes. Only returned
        if feats is not None.
docstr_tok: ["Subdivide","verts","(","and","optionally","features",")","of","a","batch","of","meshes","where","each","mesh","has","the","same","topology","of","faces",".","The","subdivided","faces","are","precomputed","in","the","initializer",".","Args",":","meshes",":","Meshes","object","representing","a","batch","of","meshes",".","feats",":","Per-vertex","features","to","be","subdivided","along","with","the","verts",".","Returns",":","2-element","tuple","containing","-","*","*","new_meshes","*","*",":","Meshes","object","of","a","batch","of","subdivided","meshes",".","-","*","*","new_feats","*","*",":","(","optional",")","Tensor","of","subdivided","feats",",","parallel","to","the","(","packed",")","vertices","of","the","subdivided","meshes",".","Only","returned","if","feats","is","not","None","."]
code: def subdivide_homogeneous(self, meshes, feats=None):
      """
      Subdivide verts (and optionally features) of a batch of meshes
      where each mesh has the same topology of faces. The subdivided faces
      are precomputed in the initializer.
  
      Args:
          meshes: Meshes object representing a batch of meshes.
          feats: Per-vertex features to be subdivided along with the verts.
  
      Returns:
          2-element tuple containing
  
          - **new_meshes**: Meshes object of a batch of subdivided meshes.
          - **new_feats**: (optional) Tensor of subdivided feats, parallel to the
            (packed) vertices of the subdivided meshes. Only returned
            if feats is not None.
      """
      verts = meshes.verts_padded()  # (N, V, D)
      edges = meshes[0].edges_packed()
  
      # The set of faces is the same across the different meshes.
      new_faces = self._subdivided_faces.view(1, -1, 3).expand(
          self._N, -1, -1
      )
  
      # Add one new vertex at the midpoint of each edge by taking the average
      # of the vertices that form each edge.
      new_verts = verts[:, edges].mean(dim=2)
      new_verts = torch.cat(
          [verts, new_verts], dim=1
      )  # (sum(V_n)+sum(E_n), 3)
      new_feats = None
  
      # Calculate features for new vertices.
      if feats is not None:
          if feats.dim() == 2:
              # feats is in packed format, transform it from packed to
              # padded, i.e. (N*V, D) to (N, V, D).
              feats = feats.view(
                  verts.size(0), verts.size(1), feats.size(1)
              )
          if feats.dim() != 3:
              raise ValueError(
                  "features need to be of shape (N, V, D) or (N*V, D)"
              )
  
          # Take average of the features at the vertices that form each edge.
          new_feats = feats[:, edges].mean(dim=2)
          new_feats = torch.cat(
              [feats, new_feats], dim=1
          )  # (sum(V_n)+sum(E_n), 3)
  
      new_meshes = Meshes(verts=new_verts, faces=new_faces)
  
      if feats is None:
          return new_meshes
      else:
          return new_meshes, new_feats
  
file_path: pytorch3d/pytorch3d/ops/subdivide_meshes.py
imports: import torch
  import torch.nn
  from pytorch3d.structures import Meshes
label_desc: Use image node_id 4 for calling the SubdivideMeshes obj's underlying member method code with example usage: obj.subdivide_homogeneous(meshes, feats) and returns: new_meshes, new_meshes,  new_feats