pytorch3d.io

pytorch3d.io.load_obj(f, load_textures=True, create_texture_atlas: bool = False, texture_atlas_size: int = 4, texture_wrap: Optional[str] = 'repeat', device: Union[str, torch.device] = 'cpu', path_manager: Optional[iopath.common.file_io.PathManager] = None)[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 triangle
- 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 assumed 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 – Device (as str or torch.device) on which to return the new tensors.
  • path_manager – optionally a PathManager object to interpret paths.
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: Union[str, torch.device, None] = None, load_textures: bool = True, create_texture_atlas: bool = False, texture_atlas_size: int = 4, texture_wrap: Optional[str] = 'repeat', path_manager: Optional[iopath.common.file_io.PathManager] = None)[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:
  • files – A list of file-like objects (with methods read, readline, tell, and seek), pathlib paths or strings containing file names.
  • 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
  • texture_atlas_size, texture_wrap (create_texture_atlas,) – as for load_obj.
  • path_manager – optionally a PathManager object to interpret paths.
Returns:

New Meshes object.

pytorch3d.io.save_obj(f: Union[pathlib.Path, str], verts, faces, decimal_places: Optional[int] = None, path_manager: Optional[iopath.common.file_io.PathManager] = None, *, verts_uvs: Optional[torch.Tensor] = None, faces_uvs: Optional[torch.Tensor] = None, texture_map: Optional[torch.Tensor] = None) → None[source]

Save a mesh to an .obj file.

Parameters:
  • f – File (str 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.
  • path_manager – Optional PathManager for interpreting f if it is a str.
  • verts_uvs – FloatTensor of shape (V, 2) giving the uv coordinate per vertex.
  • faces_uvs – LongTensor of shape (F, 3) giving the index into verts_uvs for each vertex in the face.
  • texture_map – FloatTensor of shape (H, W, 3) representing the texture map for the mesh which will be saved as an image. The values are expected to be in the range [0, 1],
class pytorch3d.io.IO(include_default_formats: bool = True, path_manager: Optional[iopath.common.file_io.PathManager] = None)[source]

Bases: object

This class is the interface to flexible loading and saving of meshes and point clouds.

In simple cases the user will just initialize an instance of this class as IO() and then use its load and save functions. The arguments of the initializer are not usually needed.

The user can add their own formats for saving and loading by passing their own objects to the register_* functions.

Parameters:
  • include_default_formats – If False, the built-in file formats will not be available. Then only user-registered formats can be used.
  • path_manager – Used to customize how paths given as strings are interpreted.
register_default_formats() → None[source]
register_meshes_format(interpreter: pytorch3d.io.pluggable_formats.MeshFormatInterpreter) → None[source]

Register a new interpreter for a new mesh file format.

Parameters:interpreter – the new interpreter to use, which must be an instance of a class which inherits MeshFormatInterpreter.
register_pointcloud_format(interpreter: pytorch3d.io.pluggable_formats.PointcloudFormatInterpreter) → None[source]

Register a new interpreter for a new point cloud file format.

Parameters:interpreter – the new interpreter to use, which must be an instance of a class which inherits PointcloudFormatInterpreter.
load_mesh(path: Union[str, pathlib.Path], include_textures: bool = True, device: Union[str, torch.device] = 'cpu', **kwargs) → pytorch3d.structures.meshes.Meshes[source]

Attempt to load a mesh from the given file, using a registered format. Materials are not returned. If you have a .obj file with materials you might want to load them with the load_obj function instead.

Parameters:
  • path – file to read
  • include_textures – whether to try to load texture information
  • device – device on which to leave the data.
Returns:

new Meshes object containing one mesh.

save_mesh(data: pytorch3d.structures.meshes.Meshes, path: Union[str, pathlib.Path], binary: Optional[bool] = None, include_textures: bool = True, **kwargs) → None[source]

Attempt to save a mesh to the given file, using a registered format.

Parameters:
  • data – a 1-element Meshes
  • path – file to write
  • binary – If there is a choice, whether to save in a binary format.
  • include_textures – If textures are present, whether to try to save them.
load_pointcloud(path: Union[str, pathlib.Path], device: Union[str, torch.device] = 'cpu', **kwargs) → pytorch3d.structures.pointclouds.Pointclouds[source]

Attempt to load a point cloud from the given file, using a registered format.

Parameters:
  • path – file to read
  • device – Device (as str or torch.device) on which to load the data.
Returns:

new Pointclouds object containing one mesh.

save_pointcloud(data: pytorch3d.structures.pointclouds.Pointclouds, path: Union[str, pathlib.Path], binary: Optional[bool] = None, **kwargs) → None[source]

Attempt to save a point cloud to the given file, using a registered format.

Parameters:
  • data – a 1-element Pointclouds
  • path – file to write
  • binary – If there is a choice, whether to save in a binary format.
pytorch3d.io.load_ply(f, *, path_manager: Optional[iopath.common.file_io.PathManager] = None) → Tuple[torch.Tensor, torch.Tensor][source]

Load the verts and faces from a .ply file. Note that the preferred way to load data from such a file is to use the IO.load_mesh and IO.load_pointcloud functions, which can read more of the data.

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.
  • path_manager – PathManager for loading if f is a str.
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, ascii: bool = False, decimal_places: Optional[int] = None, path_manager: Optional[iopath.common.file_io.PathManager] = 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.
  • ascii – (bool) whether to use the ascii ply format.
  • decimal_places – Number of decimal places for saving if ascii=True.
  • path_manager – PathManager for interpreting f if it is a str.