Skip to main content

The Interactive & Immersive HQ

How to Use the Open3D Python Library in TouchDesigner

In this tutorial we will learn how to install and get the most out of the Open3D Python library in TouchDesigner.
open3d library in touchdesigner

In this tutorial we will learn how to install and get the most out of the Open3D Python library in TouchDesigner. Let’s get started!

Open3D is an open-source library for 3D data processing. It is incredibly powerful, packed with features for data manipulation, modelling, and development. The documentation is clear, and plenty of examples are available for quick testing. Open3D comes as a standalone app, as well as in C++ and Python.

Since TouchDesigner and Python pair so well together, let’s dive into how to install and use Open3D in our TD projects. As I am not a 3D developer myself, I will be using a lovely hippie 3D bus model for this tutorial.

How to Install the Open3D Python Library

To install the Open3D library, it is strongly recommended to create a virtual environment in the project folder, to avoid potential conflicts and mismatches between dependency versions.

To do so, open the terminal in the folder (Windows) and type:

py -3.11 -m venv venv

Replace -3.11 with the Python version you’re currently using.

Then activate the virtual environment by typing:

.\venv\Scripts\Activate.ps1

And finally install the library:

pip install open3d

Depending on what you would like to do with Open3D in TouchDesigner, you may also need to install other libraries, such as NumPy and Matplotlib.

Get Our 7 Core TouchDesigner Templates, FREE

We’re making our 7 core project file templates available – for free.

These templates shed light into the most useful and sometimes obtuse features of TouchDesigner.

They’re designed to be immediately applicable for the complete TouchDesigner beginner, while also providing inspiration for the advanced user.

Why does Open3D crash in TouchDesigner?

Now that the virtual environment has been correctly set up, you should be able to load the library in a DAT operator in TouchDesigner and start getting the most out of Open3D. The truth is that there are several conflicts and threading issues. So if you try to run the library as-is, TouchDesigner will crash. How do we solve it?

Luckily, I found the solution in a thread on the Derivative forum. To run the Open3D library in TouchDesigner, we need to set this environment variable:

MIMALLOC_DISABLE_REDIRECT=1

Since this variable is used by several other applications on our computer, we need to find a way to set it only within TouchDesigner. Here is the solution from the always-great Matthew Ragan: create a batch file that takes care of launching the patch.

So, open your favourite editor and type this script:

@echo off

set MIMALLOC_DISABLE_REDIRECT=1

start "" "C:\Program Files\Derivative\TouchDesigner.2025.32460\bin\TouchDesigner.exe" "C:\Users\gianm\Desktop\Interactive_Immersive\33_Open_3D\Open3D_TD_02.toe"

Of course, you will need to change the paths to both your TouchDesigner app and your project folder.

Save the script as a .bat file and close the editor.

Now, by clicking on the batch file, the patch will open and everything will work fine. Cool, isn’t it?

Open3D in TouchDesigner: a Couple of Ideas

So, now we can start working with the Open3D library in TouchDesigner. Let’s see a couple of examples.

Voxel downsampling

In this first example, we will use the voxel downsampling technique. Voxel downsampling uses a voxel grid to create a downsampled point cloud from an input point cloud. It can be useful for several point cloud processing tasks.

So, here is the complete script that runs in a Text DAT:

import sys
#Remeber to change the path
site_packages = r"C:\Users\gianm\Desktop\Interactive_Immersive\33_Open_3D\venv\Lib\site-packages"
if site_packages not in sys.path:
    sys.path.append(site_packages)
import open3d as o3d
import numpy as np
#Remeber to change the path
mesh = o3d.io.read_triangle_mesh(r"C:\Users\gianm\Desktop\Interactive_Immersive\33_Open_3D\Open3D-main\examples\python\geometry\bus_ply.ply")
mesh.compute_vertex_normals()
pcd = mesh.sample_points_poisson_disk(number_of_points=10000)
voxel_size = 0.05
downpcd = pcd.voxel_down_sample(voxel_size=voxel_size)
points = np.asarray(downpcd.points)
center = points.mean(axis=0)
max_extent = np.max(np.linalg.norm(points - center, axis=1))
points_norm = (points - center) / max_extent
points_table = op('points_table')
points_table.clear()
points_table.appendRow(['x', 'y', 'z'])
for p in points_norm:
	points_table.appendRow([p[0], p[1], p[2]])

First, we need to reference the path to the virtual environment’s libraries. Then we import the Open3D library, as well as NumPy, load the mesh, compute the normals, and calculate the voxel downsampling. Finally, we normalize the data and load it into a Table DAT. Very easy and straightforward.

Then we convert the DAT data to POP values and render it. Now let’s run the script et voilà, here is our lovely hippie bus with voxel downsampling.

open3d library in touchdesigner

DBSCAN clustering

DBSCAN clustering is a density-based clustering algorithm. Supposing we have a point cloud from a depth sensor, this technique allows us to group points into clusters.

So, here is the script – partially vibe-coded – that runs in a Text DAT:

import sys
#Remeber to change the path
site_packages = r"C:\Users\gianm\Desktop\Interactive_Immersive\33_Open_3D\venv\Lib\site-packages"
if site_packages not in sys.path:
    sys.path.append(site_packages)
import open3d as o3d
import numpy as np
import matplotlib.pyplot as plt
#Remeber to change the path
mesh = o3d.io.read_triangle_mesh(r"C:\Users\gianm\Desktop\Interactive_Immersive\33_Open_3D\Open3D-main\examples\python\geometry\bus_ply.ply")
mesh.compute_vertex_normals()
pcd = mesh.sample_points_poisson_disk(number_of_points=10000)
distances = pcd.compute_nearest_neighbor_distance()
avg_dist = np.mean(distances)
eps = avg_dist * 3 
min_points = 10
with o3d.utility.VerbosityContextManager(
        o3d.utility.VerbosityLevel.Debug) as cm:
    labels = np.array(
        pcd.cluster_dbscan(eps=eps, min_points=min_points, print_progress=True))
max_label = labels.max()
n_noise = int(np.sum(labels < 0))
colors = plt.get_cmap("tab20")(labels / (max_label if max_label > 0 else 1))
colors[labels < 0] = 0  # punti di rumore (label -1) in nero
pcd.colors = o3d.utility.Vector3dVector(colors[:, :3])
points = np.asarray(pcd.points)
point_colors = np.asarray(pcd.colors)
center = points.mean(axis=0)
max_extent = np.max(np.linalg.norm(points - center, axis=1))
points_norm = (points - center) / max_extent
points_table = op('points_table_02')
points_table.clear()
points_table.appendRow(['x', 'y', 'z', 'r', 'g', 'b', 'label'])
for p, c, l in zip(points_norm, point_colors, labels):
	points_table.appendRow([p[0], p[1], p[2], c[0], c[1], c[2], int(l)])

As with the previous script, we start by referencing the virtual environment’s libraries, importing the necessary ones, and loading the mesh. Then the algorithm calculates the point density and generates the clustering. Finally, we pass the data into a table, where we store the coordinates and color-code the point clusters.

Then we convert the DATs to POPs, render the data, and here is the result.

open3d library in touchdesigner

Wrap Up

Implementing Open3D in TouchDesigner opens up great new perspectives, especially when working with data from depth sensors. While the installation process can be intimidating, the library’s features are well worth it. So start experimenting: the sky, as we know, is the limit.