Convert Mesh to Point Cloud
SUMMARY
Convert Mesh to Point Cloud samples a triangle mesh's surface into a point cloud.
It converts a datatypes.Mesh3D (vertices + triangles) into a datatypes.PointCloud by sampling points across the mesh's surface — the reverse of reconstruct_mesh_using_convex_hull/reconstruct_mesh_using_poisson. This is useful for turning a CAD or parametric model (e.g. from create_cylinder_mesh, create_sphere_mesh, create_torus_mesh, create_plane_mesh) into a synthetic point cloud for testing point-cloud Skills, or for resampling a scanned mesh at a controlled point density.
Use this Skill when you want to turn a mesh model into a point cloud at a controlled density, for example to prepare a CAD model for 6D pose estimation or registration against real sensor data.
The Skill
from telekinesis import vitreous
point_cloud = vitreous.convert_mesh_to_point_cloud(
mesh=mesh,
num_points=10000,
sampling_method="poisson_disk",
initial_sampling_factor=5,
initial_point_cloud=None,
use_triangle_normal=False,
)Data Transfer Notice
There is no longer a fixed limit of 1 million points per request. However, very large datasets may result in slower data transfer and processing times. We are continuously optimizing performance as part of our beta program, with ongoing improvements to enhance speed and reliability.
Example
Input Mesh
Output Point Cloud
Parameters: num_points=10000, sampling_method="poisson_disk", initial_sampling_factor=5, initial_point_cloud=None, use_triangle_normal=False.
The Code
There is no standalone example script for this Skill in the Telekinesis examples repository yet. The snippet below is adapted directly from convert_mesh_to_point_cloud's own SDK docstring — it builds a synthetic mesh with create_cylinder_mesh and is runnable as a standalone script once you have a Telekinesis API key configured:
"""
Demonstrates converting a mesh into a point cloud by sampling its surface.
"""
from loguru import logger
import numpy as np
import rerun as rr
from telekinesis import vitreous, datatypes
def convert_mesh_to_point_cloud_example():
"""Samples a parametric cylinder mesh's surface into a point cloud."""
# ===================== Create Mesh ==========================================
mesh = vitreous.create_cylinder_mesh(
radius=0.01,
height=0.02,
radial_resolution=20,
height_resolution=4,
retain_base=False,
vertex_tolerance=1e-6,
transformation_matrix=np.eye(4, dtype=np.float32),
compute_vertex_normals=True,
)
# ===================== Run Skill ==========================================
point_cloud = vitreous.convert_mesh_to_point_cloud(
mesh=mesh,
num_points=10000,
sampling_method="poisson_disk",
initial_sampling_factor=5,
initial_point_cloud=None,
use_triangle_normal=False,
)
# ===================== Log ================================================
logger.success(f"Converted {mesh} to a point cloud.")
logger.success(f"Result: {point_cloud}")
logger.info(f"Sampled point cloud positions shape: {point_cloud.positions.shape}")
logger.info(f"Sampled point cloud has normals: {point_cloud.has_normals}")
# ===================== Visualization (Optional) ===========================
rr.init("convert_mesh_to_point_cloud_example", spawn=True)
datatypes.visualize(mesh, entity_path="/1-input_mesh")
datatypes.visualize(point_cloud, entity_path="/2-sampled_point_cloud")
if __name__ == "__main__":
convert_mesh_to_point_cloud_example()Parameter Configuration
| Key | Type | Default | Description |
|---|---|---|---|
mesh | datatypes.Mesh3D | required | The mesh to sample points from |
num_points | datatypes.Int | int | 1000 | The number of points to sample from the surface |
sampling_method | datatypes.String | str | "uniform" | The sampling algorithm: "uniform" or "poisson_disk" |
initial_sampling_factor | datatypes.Int | int | 1 | Only used when sampling_method="poisson_disk": the initial uniform oversample has initial_sampling_factor * num_points points before thinning down to num_points |
initial_point_cloud | datatypes.PointCloud | None | None | An optional existing point cloud to seed "poisson_disk" sampling with, instead of starting from scratch |
use_triangle_normal | datatypes.Bool | bool | False | Whether each sampled point's normal is taken from its parent triangle's flat face normal instead of interpolated per-vertex normals |
Returns
| Type | Description |
|---|---|
datatypes.PointCloud | A point cloud with num_points sampled positions (and normals, derived per use_triangle_normal). Use .positions for the (num_points, 3) array, len(...) for the point count, and .has_normals/.normals to check/access the sampled normals. |
Raises
| Exception | Condition |
|---|---|
TypeError | A parameter's value does not match its expected type (see the Parameter Configuration table above) |
ConfigurationError | The TELEKINESIS_API_KEY environment variable is not set |
SerializationError | The request input failed to serialize, or the response failed to deserialize |
RequestTimeoutError | The request to the Vitreous service timed out |
TransportError | A network failure occurred before a response was received |
ClientError | The Vitreous service rejected the request due to invalid input, invalid data, or another unexpected 4xx response |
AuthenticationError | The API key was rejected as invalid or expired |
AuthenticationServiceError | The authentication service was unavailable |
ServerError | The Vitreous service returned a 5xx or otherwise unexpected error response |
How to Tune the Parameters
num_points
- Controls: The number of sampled surface points.
- Units: Points (count)
- Default:
1000 - Increase → denser, more detailed coverage, at the cost of a larger point cloud
- Decrease → sparser sample, smaller point cloud
- Typical range: 1,000–20,000+, depending on how much detail downstream Skills need
sampling_method
- Controls: How points are distributed across the mesh surface.
- Units: N/A (categorical)
- Default:
"uniform"- Options:
"uniform"— samples points uniformly at random, weighted by triangle area. Fast, but points can clump or leave small gaps since there's no minimum spacing between them."poisson_disk"— produces a more evenly-spaced ("blue noise") sample with a minimum distance between points, by drawing an initial uniform oversample (seeinitial_sampling_factor) and thinning it down tonum_points. Slower than"uniform"but gives more visually/statistically even coverage.
- Options:
initial_sampling_factor
- Controls: Only used when
sampling_method="poisson_disk"— how large the initial uniform oversample is, as a multiple ofnum_points, before thinning. - Units: Dimensionless multiplier
- Default:
1 - Increase → gives the Poisson-disk thinning step more candidates to pick from (better final spacing), at the cost of more up-front sampling work
- Typical range: 2–10 — start at
5
initial_point_cloud
- Controls: An optional existing point cloud to seed
"poisson_disk"sampling with, e.g. to extend a previous sample with more, evenly-spaced points, instead of starting from scratch. - Units: N/A
- Default:
None - Use
Nonefor a standard, from-scratch mesh-to-point-cloud conversion; provide a seed cloud for incremental refinement or consistency across runs
use_triangle_normal
- Controls: Whether a sampled point's normal comes from its parent triangle's flat face normal (
True) or is interpolated from the mesh's per-vertex normals (False). - Units: Boolean flag
- Default:
False - Keep
Falsefor smoother normals on curved surfaces; setTruewhen you specifically need per-triangle flat-face normals (or the mesh has no per-vertex normals to interpolate)
TIP
Start with sampling_method="uniform" for quick iteration; switch to "poisson_disk" (with initial_sampling_factor around 5) once you need an evenly-spaced sample for registration or pose estimation.
Where to Use the Skill
Common pipelines include:
- 6D pose estimation and registration – converting a CAD or mesh model into a point cloud so it can be aligned with real sensor data via correspondence-based registration
- Synthetic test data generation – sampling a parametric mesh from
create_cylinder_mesh,create_sphere_mesh,create_torus_mesh, orcreate_plane_meshto get a synthetic point cloud for testing other point-cloud Skills - Controlled resampling – resampling a scanned or reconstructed mesh at a chosen point density instead of using its raw vertex count
Alternative Skills
| Skill | vs. Convert Mesh to Point Cloud |
|---|---|
| reconstruct_mesh_using_poisson | Goes the opposite direction: builds a mesh surface from a point cloud instead of sampling a point cloud from a mesh. |
| reconstruct_mesh_using_convex_hull | Also builds a mesh from a point cloud, using its convex hull, rather than sampling points from an existing mesh. |
| create_cylinder_mesh | Generates a parametric mesh you can feed into this Skill as synthetic test geometry. |
When Not to Use the Skill
Do not use Convert Mesh to Point Cloud when:
- You already have a real point cloud - this Skill produces a synthetic sample from a mesh's surface, not a sensor capture
- You need a mesh from a point cloud - use
reconstruct_mesh_using_poissonorreconstruct_mesh_using_convex_hullinstead, which go the opposite direction - You need the mesh's exact original vertices rather than a resampled surface - sampled points are new positions on the surface, not the mesh's own vertex positions
TIP
If you're building synthetic test data, pair this Skill with a generator like create_cylinder_mesh, create_sphere_mesh, create_torus_mesh, or create_plane_mesh — they produce meshes purpose-built to be sampled into point clouds.

