File IO#

This tutorial shows how basic data structures are read and written by Open3D.

Point cloud#

The code below reads and writes a point cloud.

[2]:
print("Testing IO for point cloud ...")
sample_pcd_data = o3d.data.PCDPointCloud()
pcd = o3d.io.read_point_cloud(sample_pcd_data.path)
print(pcd)
o3d.io.write_point_cloud("copy_of_fragment.pcd", pcd)
Testing IO for point cloud ...
PointCloud with 113662 points.
[2]:
True

By default, Open3D tries to infer the file type by the filename extension. The following point cloud file types are supported:

Format

Description

xyz

Each line contains [x, y, z], where x, y, z are the 3D coordinates

xyzn

Each line contains [x, y, z, nx, ny, nz], where nx, ny, nz are the normals

xyzrgb

Each line contains [x, y, z, r, g, b], where r, g, b are in floats of range [0, 1]

pts

The first line is an integer representing the number of points. The subsequent lines follow one of these formats: [x, y, z, i, r, g, b], [x, y, z, r, g, b], [x, y, z, i] or [x, y, z], where x, y, z, i are of type double and r, g, b are of type uint8

ply

See Polygon File Format, the ply file can contain both point cloud and mesh data

pcd

See Point Cloud Data

It’s also possible to specify the file type explicitly. In this case, the file extension will be ignored.

Mesh#

The code below reads and writes a mesh.

[3]:
print("Testing IO for meshes ...")
knot_data = o3d.data.KnotMesh()
mesh = o3d.io.read_triangle_mesh(knot_data.path)
print(mesh)
o3d.io.write_triangle_mesh("copy_of_knot.ply", mesh)
Testing IO for meshes ...
[Open3D INFO] Downloading https://github.com/isl-org/open3d_downloads/releases/download/20220201-data/KnotMesh.ply
[Open3D INFO] Downloaded to /root/open3d_data/download/KnotMesh/KnotMesh.ply
TriangleMesh with 1440 points and 2880 triangles.
[3]:
True

Compared to the point cloud data structure, a mesh has triangles that define the 3D surface.

By default, Open3D tries to infer the file type by the filename extension. The following mesh file types are supported:

Format

Description

ply

See Polygon File Format, the ply file can contain both point cloud and mesh data

stl

See StereoLithography

obj

See Object Files

off

See Object File Format

gltf/glb

See GL Transmission Format

fbx

Autodesk FBX (via Assimp)

Multi-material models (including USD usd/usda/usdc/usdz) should be loaded with read_triangle_model rather than read_triangle_mesh. USD import is experimental (meshes and PBR materials only; see section below).

Triangle mesh model (multi-material)#

For assets with multiple meshes and PBR materials (typical for glTF/GLB, FBX, and USD), use read_triangle_model. It returns a :class:open3d.visualization.rendering.TriangleMeshModel suitable for the Filament-based visualizer.

USD (.usd, .usda, .usdc, .usdz) import is experimental: only mesh geometry and PBR material read support is provided (base color, normal, metallic/roughness, occlusion, and related factors). There is no USD export, and scene features such as animation, lights, and cameras are not imported.

A complete example that downloads Apple’s sample biplane USDZ and visualizes it lives at examples/python/io/model_io.py:

import open3d as o3d
from pathlib import Path
import urllib.request

url = (
    "https://developer.apple.com/augmented-reality/quick-look/models/"
    "biplane/toy_biplane_realistic.usdz")
dest = Path("toy_biplane_realistic.usdz")
if not dest.is_file():
    urllib.request.urlretrieve(url, dest)

model = o3d.io.read_triangle_model(str(dest))
o3d.visualization.draw([{"name": "biplane", "geometry": model}])

Or run: python examples/python/io/model_io.py

[4]:
# Optional: run only if the USDZ was downloaded (see examples/python/io/model_io.py)
import os
from pathlib import Path

usdz = Path("toy_biplane_realistic.usdz")
if usdz.is_file():
    model = o3d.io.read_triangle_model(str(usdz))
    print(f"USD model: {len(model.meshes)} meshes, {len(model.materials)} materials")
else:
    print("Skip USD demo: download toy_biplane_realistic.usdz or run model_io.py")
Skip USD demo: download toy_biplane_realistic.usdz or run model_io.py

Image#

The code below reads and writes an image.

[5]:
print("Testing IO for images ...")
image_data = o3d.data.JuneauImage()
img = o3d.io.read_image(image_data.path)
print(img)
o3d.io.write_image("copy_of_Juneau.jpg", img)
Testing IO for images ...
[Open3D INFO] Downloading https://github.com/isl-org/open3d_downloads/releases/download/20220201-data/JuneauImage.jpg
[Open3D INFO] Downloaded to /root/open3d_data/download/JuneauImage/JuneauImage.jpg
Image of size 800x489, with 3 channels.
Use numpy.asarray to access buffer data.
[5]:
True

The size of the image is readily displayed using print(img).

Both jpg and png image files are supported.