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. dim () = 2 : # feats is in packed format, transform it from packed to # padded, i.e. cat (, dim = 1 ) # (sum(V_n)+sum(E_n), 3) new_feats = None # Calculate features for new vertices. _N, - 1, - 1 ) # Add one new vertex at the midpoint of each edge by taking the average # of the vertices that form each edge.
edges_packed () # The set of faces is the same across the different meshes. verts_padded () # (N, V, D) edges = meshes. **new_feats**: (optional) Tensor of subdivided feats, parallel to the (packed) vertices of the subdivided meshes. Returns: 2-element tuple containing - **new_meshes**: Meshes object of a batch of subdivided meshes. feats: Per-vertex features to be subdivided along with the verts. Args: meshes: Meshes object representing a batch of meshes. The subdivided faces are precomputed in the initializer. 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. subdivide_heterogenerous ( meshes, feats ) subdivide_homogeneous ( meshes, feats ) else : return self. Should be parallel to the packed vert representation of the input meshes so it should have shape (V, D) where V is the total number of verts in the input meshes. Data for these vertices is the average of the data for the two vertices that make up the edge. 2) New vertices at the midpoint of each edge. Data for these vertices are copied from the input meshes. New meshes contains two types of vertices: 1) Vertices that appear in the input meshes. def forward ( self, meshes, feats = None ): """ Subdivide a batch of meshes by adding a new vertex on each edge, and dividing each face into four new faces. cat (, dim = 0 ) # (4*sum(F_n), 3) return subdivided_faces_packed stack (, faces_packed_to_edges_packed, faces_packed_to_edges_packed, ], dim = 1, ) f3 = faces_packed_to_edges_packed subdivided_faces_packed = torch. stack (, faces_packed_to_edges_packed, faces_packed_to_edges_packed, ], dim = 1, ) f2 = torch. stack (, faces_packed_to_edges_packed, faces_packed_to_edges_packed, ], dim = 1, ) f1 = torch. faces_packed_to_edges_packed () + verts_packed. faces_packed () faces_packed_to_edges_packed = ( meshes.
:: faces_packed_to_edges_packed = ] + 3 = ] e.g. To get the indices of the new vertices, offset `faces_packed_to_edges_packed` by the total number of vertices. The actual vertex coordinates will be computed in the forward function. Input face :: v0 /\ / \ / \ e1 / \ e0 / \ / \ / \ /_\ v2 e2 v1 faces_packed = ] faces_packed_to_edges_packed = ] `faces_packed_to_edges_packed` is used to represent all the new vertex indices corresponding to the mid-points of edges in the mesh. Refer to for more details on packed representations of faces. Returns: subdivided_faces_packed: (4*sum(F_n), 3) shape LongTensor of original and new faces. Def subdivide_faces ( self, meshes ): r """ Args: meshes: a Meshes object.