pytorch3d.io

pytorch3d.io.load_obj(f_obj, load_textures=True, create_texture_atlas: bool = False, texture_atlas_size: int = 4, texture_wrap: Optional[str] = 'repeat', device='cpu')[source]

Load a mesh from a .obj file and optionally textures from a .mtl file. Currently this handles verts, faces, vertex texture uv coordinates, normals, texture images and material reflectivity values.

Note .obj files are 1-indexed. The tensors returned from this function are 0-indexed. OBJ spec reference: http://www.martinreddy.net/gfx/3d/OBJ.spec

Example .obj file format:

# this is a comment
v 1.000000 -1.000000 -1.000000
v 1.000000 -1.000000 1.000000
v -1.000000 -1.000000 1.000000
v -1.000000 -1.000000 -1.000000
v 1.000000 1.000000 -1.000000
vt 0.748573 0.750412
vt 0.749279 0.501284
vt 0.999110 0.501077
vt 0.999455 0.750380
vn 0.000000 0.000000 -1.000000
vn -1.000000 -0.000000 -0.000000
vn -0.000000 -0.000000 1.000000
f 5/2/1 1/2/1 4/3/1
f 5/1/1 4/3/1 2/4/1

The first character of the line denotes the type of input:

- v is a vertex
- vt is the texture coordinate of one vertex
- vn is the normal of one vertex
- f is a face

Faces are interpreted as follows:

5/2/1 describes the first vertex of the first triange
- 5: index of vertex [1.000000 1.000000 -1.000000]
- 2: index of texture coordinate [0.749279 0.501284]
- 1: index of normal [0.000000 0.000000 -1.000000]

If there are faces with more than 3 vertices they are subdivided into triangles. Polygonal faces are assummed to have vertices ordered counter-clockwise so the (right-handed) normal points out of the screen e.g. a proper rectangular face would be specified like this:

0_________1
|         |
|         |
3 ________2

The face would be split into two triangles: (0, 2, 1) and (0, 3, 2), both of which are also oriented counter-clockwise and have normals pointing out of the screen.

Parameters:
  • f – A file-like object (with methods read, readline, tell, and seek), a pathlib path or a string containing a file name.
  • load_textures – Boolean indicating whether material files are loaded
  • create_texture_atlas – Bool, If True a per face texture map is created and a tensor texture_atlas is also returned in aux.
  • texture_atlas_size – Int specifying the resolution of the texture map per face when create_texture_atlas=True. A (texture_size, texture_size, 3) map is created per face.
  • texture_wrap – string, one of [“repeat”, “clamp”]. This applies when computing the texture atlas. If texture_mode=”repeat”, for uv values outside the range [0, 1] the integer part is ignored and a repeating pattern is formed. If texture_mode=”clamp” the values are clamped to the range [0, 1]. If None, then there is no transformation of the texture values.
  • device – string or torch.device on which to return the new tensors.
Returns:

6-element tuple containing

  • verts: FloatTensor of shape (V, 3).

  • faces: NamedTuple with fields:
    • verts_idx: LongTensor of vertex indices, shape (F, 3).
    • normals_idx: (optional) LongTensor of normal indices, shape (F, 3).
    • textures_idx: (optional) LongTensor of texture indices, shape (F, 3). This can be used to index into verts_uvs.
    • materials_idx: (optional) List of indices indicating which material the texture is derived from for each face. If there is no material for a face, the index is -1. This can be used to retrieve the corresponding values in material_colors/texture_images after they have been converted to tensors or Materials/Textures data structures - see textures.py and materials.py for more info.
  • aux: NamedTuple with fields:
    • normals: FloatTensor of shape (N, 3)

    • verts_uvs: FloatTensor of shape (T, 2), giving the uv coordinate per vertex. If a vertex is shared between two faces, it can have a different uv value for each instance. Therefore it is possible that the number of verts_uvs is greater than num verts i.e. T > V. vertex.

    • material_colors: if load_textures=True and the material has associated properties this will be a dict of material names and properties of the form:

      {
          material_name_1:  {
              "ambient_color": tensor of shape (1, 3),
              "diffuse_color": tensor of shape (1, 3),
              "specular_color": tensor of shape (1, 3),
              "shininess": tensor of shape (1)
          },
          material_name_2: {},
          ...
      }
      

      If a material does not have any properties it will have an empty dict. If load_textures=False, material_colors will None.

    • texture_images: if load_textures=True and the material has a texture map, this will be a dict of the form:

      {
          material_name_1: (H, W, 3) image,
          ...
      }
      

      If load_textures=False, texture_images will None.

    • texture_atlas: if load_textures=True and create_texture_atlas=True, this will be a FloatTensor of the form: (F, texture_size, textures_size, 3) If the material does not have a texture map, then all faces will have a uniform white texture. Otherwise texture_atlas will be None.

pytorch3d.io.load_objs_as_meshes(files: list, device=None, load_textures: bool = True)[source]

Load meshes from a list of .obj files using the load_obj function, and return them as a Meshes object. This only works for meshes which have a single texture image for the whole mesh. See the load_obj function for more details. material_colors and normals are not stored.

Parameters:
  • f – A list of file-like objects (with methods read, readline, tell,
  • seek), pathlib paths or strings containing file names. (and) –
  • device – Desired device of returned Meshes. Default: uses the current device for the default tensor type.
  • load_textures – Boolean indicating whether material files are loaded
Returns:

New Meshes object.

pytorch3d.io.save_obj(f, verts, faces, decimal_places: Optional[int] = None)[source]

Save a mesh to an .obj file.

Parameters:
  • f – File (or path) to which the mesh should be written.
  • verts – FloatTensor of shape (V, 3) giving vertex coordinates.
  • faces – LongTensor of shape (F, 3) giving faces.
  • decimal_places – Number of decimal places for saving.
pytorch3d.io.load_ply(f)[source]

Load the data from a .ply file.

Example .ply file format:

ply format ascii 1.0 { ascii/binary, format version number } comment made by Greg Turk { comments keyword specified, like all lines } comment this file is a cube element vertex 8 { define “vertex” element, 8 of them in file } property float x { vertex contains float “x” coordinate } property float y { y coordinate is also a vertex property } property float z { z coordinate, too } element face 6 { there are 6 “face” elements in the file } property list uchar int vertex_index { “vertex_indices” is a list of ints } end_header { delimits the end of the header } 0 0 0 { start of vertex list } 0 0 1 0 1 1 0 1 0 1 0 0 1 0 1 1 1 1 1 1 0 4 0 1 2 3 { start of face list } 4 7 6 5 4 4 0 4 5 1 4 1 5 6 2 4 2 6 7 3 4 3 7 4 0

Parameters:f – A binary or text file-like object (with methods read, readline, tell and seek), a pathlib path or a string containing a file name. If the ply file is in the binary ply format rather than the text ply format, then a text stream is not supported. It is easiest to use a binary stream in all cases.
Returns:verts – FloatTensor of shape (V, 3). faces: LongTensor of vertex indices, shape (F, 3).
pytorch3d.io.save_ply(f, verts: torch.Tensor, faces: Optional[torch.LongTensor] = None, verts_normals: Optional[torch.Tensor] = None, decimal_places: Optional[int] = None) → None[source]

Save a mesh to a .ply file.

Parameters:
  • f – File (or path) to which the mesh should be written.
  • verts – FloatTensor of shape (V, 3) giving vertex coordinates.
  • faces – LongTensor of shape (F, 3) giving faces.
  • verts_normals – FloatTensor of shape (V, 3) giving vertex normals.
  • decimal_places – Number of decimal places for saving.